From 393d7aee1208178b56f9b2192c0102fa0dfebef2 Mon Sep 17 00:00:00 2001 From: luka-micas Date: Wed, 12 Aug 2026 06:38:22 +0000 Subject: [PATCH 1/2] [micas] Fix Micas compatibility issues on Trixie Debian 13 with kernel 6.12 Signed-off-by: luka-micas --- platform/broadcom/rules.dep | 2 +- platform/broadcom/rules.mk | 2 +- .../common/modules/ct7148.c | 11 ++- .../common/modules/hw_test.c | 2 +- .../modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c | 17 +++++ .../s3ip_sysfs/switch_driver/cfg/dfd_cfg.c | 21 ++++++ .../s3ip_sysfs/switch_driver/wb_fan_driver.c | 5 ++ .../s3ip_sysfs/switch_driver/wb_psu_driver.c | 10 ++- .../common/modules/wb_csu550.c | 11 ++- .../common/modules/wb_fpga_i2c_bus_drv.c | 6 ++ .../common/modules/wb_fpga_pca954x_drv.c | 35 ++++++++-- .../common/modules/wb_gpio_d1500.c | 9 +++ .../common/modules/wb_i2c_dev.c | 14 ++++ .../common/modules/wb_i2c_mux_pca954x.c | 42 +++++++++--- .../common/modules/wb_i2c_mux_pca9641.c | 26 ++++++- .../common/modules/wb_i2c_ocores.c | 7 ++ .../common/modules/wb_indirect_dev.c | 12 ++++ .../common/modules/wb_io_dev.c | 9 ++- .../common/modules/wb_lpc_drv.c | 9 ++- .../common/modules/wb_mac_bsc.c | 22 ++++++ .../common/modules/wb_pcie_dev.c | 9 ++- .../common/modules/wb_platform_i2c_dev.c | 8 ++- .../common/modules/wb_spi_dev.c | 1 + .../common/modules/wb_spi_ocores.c | 56 +++++++++------- .../common/modules/wb_ucd9081.c | 13 ++++ .../common/modules/wb_uio_irq.c | 11 ++- .../common/modules/wb_wdt.c | 60 +++++++++++------ .../common/modules/wb_wdt.h | 7 +- .../common/modules/wb_xdpe132g5c.c | 13 ++++ .../common/modules/wb_xdpe132g5c_pmbus.c | 16 ++++- .../common/sonic_platform/psu.py | 2 +- .../sonic-platform-modules-micas/debian/rules | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../driver/wb_i2c_mux_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../driver/wb_i2c_mux_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../driver/wb_i2c_mux_pca954x_device.c | 2 +- .../modules/driver/wb_fpga_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../modules/driver/wb_fpga_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../modules/driver/wb_fpga_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../modules/driver/wb_fpga_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../driver/wb_i2c_mux_pca954x_device.c | 2 +- .../modules/driver/wb_spi_dev_device.c | 10 +-- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../driver/wb_i2c_mux_pca954x_device.c | 2 +- .../x86_64_micas_m2_w6940_64oc_r0_config.py | 67 +++++++++++++++++++ .../x86_64_micas_m2_w6940_64oc_r0_device.py | 31 +++++---- .../x86_64_micas_m2_w6940_64oc_r0_monitor.py | 12 +++- .../modules/driver/wb_fpga_pca954x_device.c | 2 +- .../modules/driver/wb_i2c_dev_device.c | 2 +- .../driver/wb_i2c_mux_pca954x_device.c | 2 +- .../modules/driver/wb_wdt_device.c | 7 +- .../s3ip_sysfs_cfg/cfg_file/SENSOR.cfg | 1 - 58 files changed, 509 insertions(+), 129 deletions(-) diff --git a/platform/broadcom/rules.dep b/platform/broadcom/rules.dep index 806f8d50e0..45e6e13ead 100644 --- a/platform/broadcom/rules.dep +++ b/platform/broadcom/rules.dep @@ -19,7 +19,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.dep #include $(PLATFORM_PATH)/platform-modules-ragile.dep include $(PLATFORM_PATH)/platform-modules-supermicro.dep include $(PLATFORM_PATH)/platform-modules-ufispace.dep -#include $(PLATFORM_PATH)/platform-modules-micas.dep +include $(PLATFORM_PATH)/platform-modules-micas.dep include $(PLATFORM_PATH)/docker-syncd-brcm.dep include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.dep include $(PLATFORM_PATH)/docker-saiserver-brcm.dep diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 4e7f600348..aa0a1000eb 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -23,7 +23,7 @@ include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-supermicro.mk #include $(PLATFORM_PATH)/platform-modules-tencent.mk include $(PLATFORM_PATH)/platform-modules-ufispace.mk -#include $(PLATFORM_PATH)/platform-modules-micas.mk +include $(PLATFORM_PATH)/platform-modules-micas.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk include $(PLATFORM_PATH)/docker-saiserver-brcm.mk diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c index fff4b0e0ee..9719e763d8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c @@ -29,6 +29,7 @@ #include #include #include +#include /* debug switch level */ typedef enum { @@ -187,7 +188,11 @@ static const struct hwmon_ops ct7318_ops = { .is_visible = ct7318_is_visible, }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) +static int ct7318_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else static int ct7318_probe(struct i2c_client *client) +#endif { struct device *dev = &client->dev; struct device *hwmon_dev; @@ -201,7 +206,11 @@ static int ct7318_probe(struct i2c_client *client) mutex_init(&data->update_lock); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) + data->channels = id->driver_data; +#else data->channels = i2c_match_id(ct7318_id, client)->driver_data; +#endif data->client = client; for (i = 0; i < data->channels; i++) { @@ -226,7 +235,7 @@ static struct i2c_driver ct7318_driver = { .name = "ct7318", .of_match_table = of_match_ptr(ct7318_of_match), }, - .probe_new = ct7318_probe, + .probe = ct7318_probe, .id_table = ct7318_id, }; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c index 84d3f54943..7ab6dfdc01 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c @@ -48,7 +48,7 @@ #include "hw_test.h" -extern struct bus_type mdio_bus_type; +extern const struct bus_type mdio_bus_type; struct board_mdio_dev { struct list_head list; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c index 44bfe8e95b..28763bc3ab 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "../include/dfd_module.h" #include "../include/dfd_cfg_file.h" @@ -246,7 +247,11 @@ static int dfd_ko_cfg_add_str_item(int key, char *str, int line_num) return -1; } mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#else + strscpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#endif rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg); if (rv == 0) { @@ -260,7 +265,11 @@ static int dfd_ko_cfg_add_str_item(int key, char *str, int line_num) } else { DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08x\n", line_num, str_cfg, str, key); mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#else + strscpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#endif } return 0; @@ -454,7 +463,11 @@ static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl break; case INFO_CTRL_MEM_FPATH: mem_clear(info_ctrl->fpath, sizeof(info_ctrl->fpath)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath)); +#else + strscpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath)); +#endif break; case INFO_CTRL_MEM_ADDR: dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num); @@ -467,7 +480,11 @@ static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl break; case INFO_CTRL_MEM_STR_CONS: mem_clear(info_ctrl->str_cons, sizeof(info_ctrl->str_cons)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); +#else + strscpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); +#endif break; case INFO_CTRL_MEM_INT_EXTRA1: dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c index 0637d8566a..7579af9069 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "wb_module.h" #include "dfd_cfg_file.h" @@ -146,7 +147,11 @@ static void dfd_ko_cfg_regval_conv_lst_add(struct list_head *root, int val, char val_convert->index1 = index1; val_convert->index2 = index2; if (str != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(val_convert->str_val, str, sizeof(val_convert->str_val)); +#else + strscpy(val_convert->str_val, str, sizeof(val_convert->str_val)); +#endif } /* After initialization, the list does not change and does not need to be locked */ @@ -517,7 +522,11 @@ static int dfd_ko_cfg_add_str_item(uint64_t key, char *str, int line_num) return -1; } mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#else + strscpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#endif /* Add to linked list */ rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg); @@ -535,7 +544,11 @@ static int dfd_ko_cfg_add_str_item(uint64_t key, char *str, int line_num) DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08llx\n", line_num, str_cfg, str, key); mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#else + strscpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); +#endif } return 0; @@ -748,7 +761,11 @@ static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl break; case INFO_CTRL_MEM_FPATH: mem_clear(info_ctrl->fpath, sizeof(info_ctrl->fpath)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath)); +#else + strscpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath)); +#endif break; case INFO_CTRL_MEM_ADDR: dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num); @@ -761,7 +778,11 @@ static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl break; case INFO_CTRL_MEM_STR_CONS: mem_clear(info_ctrl->str_cons, sizeof(info_ctrl->str_cons)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); +#else + strscpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); +#endif break; case INFO_CTRL_MEM_INT_EXTRA1: dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c index 77f88429ed..c68be35339 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c @@ -20,6 +20,7 @@ #include #include +#include #include "wb_module.h" #include "dfd_cfg.h" @@ -440,7 +441,11 @@ static int dfd_fan_product_name_decode(char *fan_buf, int buf_len) return -DFD_RV_DEV_NOTSUPPORT; } mem_clear(fan_buf, buf_len); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(fan_buf, p_decode_name, buf_len); +#else + strscpy(fan_buf, p_decode_name, buf_len); +#endif DFD_FAN_DEBUG(DBG_VERBOSE, "fan name match ok, display fan name: %s.\n", fan_buf); return DFD_RV_OK; } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c index aad65d2829..5f4310b13a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c @@ -20,6 +20,7 @@ #include #include +#include #include "wb_module.h" #include "dfd_cfg.h" @@ -353,7 +354,11 @@ static int dfd_get_psu_fan_speed_cal_str(int power_type, char *psu_buf, int buf_ return -DFD_RV_DEV_NOTSUPPORT; } mem_clear(psu_buf, buf_len); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(psu_buf, speed_cal, buf_len); +#else + strscpy(psu_buf, speed_cal, buf_len); +#endif DFD_PSU_DEBUG(DBG_VERBOSE, "psu speed cal match ok, speed_cal: %s\n", psu_buf); return DFD_RV_OK; } @@ -421,7 +426,11 @@ static int dfd_psu_product_name_decode(int power_type, char *psu_buf, int buf_le return -DFD_RV_DEV_NOTSUPPORT; } mem_clear(psu_buf, buf_len); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) strlcpy(psu_buf, p_decode_name, buf_len); +#else + strscpy(psu_buf, p_decode_name, buf_len); +#endif DFD_PSU_DEBUG(DBG_VERBOSE, "psu name match ok, display psu name: %s\n", psu_buf); return DFD_RV_OK; } @@ -947,4 +956,3 @@ int dfd_clear_psu_blackbox(unsigned int psu_index, uint8_t value) DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, clear blackbox info success\n", psu_index); return DFD_RV_OK; } - diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c index 55f6a529c7..304a79e535 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "pmbus.h" struct pmbus_device_info { @@ -174,7 +175,11 @@ static int pmbus_identify(struct i2c_client *client, return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) +static int pmbus_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else static int pmbus_probe(struct i2c_client *client) +#endif { struct pmbus_driver_info *info; struct pmbus_platform_data *pdata = NULL; @@ -185,7 +190,11 @@ static int pmbus_probe(struct i2c_client *client) if (!info) return -ENOMEM; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) + device_info = (struct pmbus_device_info *)id->driver_data; +#else device_info = (struct pmbus_device_info *)i2c_match_id(pmbus_id, client)->driver_data; +#endif if (device_info->flags & PMBUS_SKIP_STATUS_CHECK) { pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data), GFP_KERNEL); @@ -239,7 +248,7 @@ static struct i2c_driver pmbus_driver = { .driver = { .name = "wb_pmbus", }, - .probe_new = pmbus_probe, + .probe = pmbus_probe, .id_table = pmbus_id, }; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c index b237df4e36..5c1834b21b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c @@ -1115,14 +1115,20 @@ static int fpga_i2c_probe(struct platform_device *pdev) return ret; }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int fpga_i2c_remove(struct platform_device *pdev) +#else +static void fpga_i2c_remove(struct platform_device *pdev) +#endif { fpga_i2c_dev_t *fpga_i2c; fpga_i2c = platform_get_drvdata(pdev); i2c_del_adapter(&fpga_i2c->adap); platform_set_drvdata(pdev, NULL); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif }; static struct of_device_id fpga_i2c_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c index d55d0cef12..30e3d2351c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c @@ -372,10 +372,20 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) /* * I2C init/probing/exit functions */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int fpga_i2c_pca954x_probe(struct i2c_client *client) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) + const struct i2c_device_id *id = i2c_match_id(fpga_pca954x_id, client); +#endif struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); - int num, force, class; + int num, force; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 10, 0) + unsigned int class = 0; +#endif struct pca954x *data; int ret = -ENODEV; struct device *dev; @@ -426,6 +436,12 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de ret = -EINVAL; goto exit_free; } + if (!id) { + dev_err(&client->dev, "Failed to match i2c device id.\n"); + ret = -ENODEV; + goto exit_free; + } + data->type = id->driver_data; fpga_pca954x_device = client->dev.platform_data; data->fpga_9548_flag = fpga_pca954x_device->fpga_9548_flag; data->fpga_9548_reset_flag = fpga_pca954x_device->fpga_9548_reset_flag; @@ -438,7 +454,7 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); } } else { - data->type = id->driver_data; + data->type = id ? id->driver_data : 0; /* BUS ID */ ret = of_property_read_u32(dev->of_node, "fpga_9548_flag", &data->fpga_9548_flag); if (ret != 0) { @@ -462,8 +478,6 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de ret = -EINVAL; goto exit_free; } - - data->type = id->driver_data; data->last_chan = 0; /* force the first selection */ /* Now create an adapter for each channel */ @@ -473,7 +487,6 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de } else { force = data->pca9548_base_nr + num; } - class = 0; /* no class by default */ #if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) data->virt_adaps[num] = i2c_add_mux_adapter(adap, &client->dev, client, @@ -486,7 +499,11 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de goto virt_reg_failed; } #else +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 10, 0) ret = i2c_mux_add_adapter(muxc, force, num, class); +#else + ret = i2c_mux_add_adapter(muxc, force, num); +#endif if (ret) { dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n", num, force); @@ -514,7 +531,11 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int fpga_i2c_pca954x_remove(struct i2c_client *client) +#else static void fpga_i2c_pca954x_remove(struct i2c_client *client) +#endif { #if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7) struct pca954x *data = i2c_get_clientdata(client); @@ -534,7 +555,11 @@ static void fpga_i2c_pca954x_remove(struct i2c_client *client) i2c_mux_del_adapters(muxc); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static struct i2c_driver fpga_i2c_pca954x_driver = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c index 25fa7acc1f..13b6c1e60f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c @@ -24,10 +24,13 @@ #include #include #include +#include #include #include #include +#include #include +#include #define GPIO_NAME "wb_gpio_d1500" @@ -351,10 +354,16 @@ static int wb_gpio_probe(struct platform_device *pdev) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int wb_gpio_remove(struct platform_device *pdev) +#else +static void wb_gpio_remove(struct platform_device *pdev) +#endif { dev_info(&pdev->dev, "unregister d1500 gpio success\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static const struct of_device_id gpio_d1500_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c index 69b2aad0e7..ac9a2aacf6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c @@ -25,11 +25,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include "wb_i2c_dev.h" @@ -741,7 +743,11 @@ int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_ } EXPORT_SYMBOL(i2c_device_func_write); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) static int i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int i2c_dev_probe(struct i2c_client *client) +#endif { int ret = 0; struct i2c_dev_info *i2c_dev; @@ -819,7 +825,11 @@ static int i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id * return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int i2c_dev_remove(struct i2c_client *client) +#else static void i2c_dev_remove(struct i2c_client *client) +#endif { int i; for (i = 0; i < MAX_I2C_DEV_NUM; i++) { @@ -828,7 +838,11 @@ static void i2c_dev_remove(struct i2c_client *client) i2c_dev_arry[i] = NULL; } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static const struct i2c_device_id i2c_dev_id[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c index 5c7c566ed4..b9e3f8cee8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c @@ -656,20 +656,20 @@ static int pca954x_do_gpio_reset(struct i2c_mux_core *muxc) } /* reset on */ - __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); + gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); if (reset_cfg->rst_delay) { usleep_range(reset_cfg->rst_delay, reset_cfg->rst_delay + 1); } /* reset off */ - __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); + gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); ret = -1; udelay_cnt = 0; timeout = reset_cfg->rst_delay_a; while (timeout > 0) { usleep_range(1, 2); - val = __gpio_get_value(gpio_attr->gpio); + val = gpio_get_value(gpio_attr->gpio); if (val == gpio_attr->reset_off) { ret = 0; PCA954X_DEBUG("pca954x_do_gpio_reset success.\n"); @@ -1186,18 +1186,27 @@ static int pca954x_reset_data_init(struct pca954x *data) /* * I2C init/probing/exit functions */ -static int pca954x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) +static int pca954x_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int pca954x_probe(struct i2c_client *client) +#endif { struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct device_node *of_node = client->dev.of_node; bool idle_disconnect_dt; struct gpio_desc *gpio; - int num, force, class; + int num, force; struct i2c_mux_core *muxc; struct pca954x *data; const struct of_device_id *match; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) + const struct i2c_device_id *id; +#endif unsigned int probe_disable; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 10, 0) + unsigned int class = 0; +#endif int ret, dynamic_nr; i2c_mux_pca954x_device_t *i2c_mux_pca954x_device; @@ -1245,10 +1254,14 @@ static int pca954x_probe(struct i2c_client *client, } match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev); - if (match) + if (match) { data->chip = of_device_get_match_data(&client->dev); - else + } else { + id = i2c_match_id(pca954x_id, client); + if (!id) + return -ENODEV; data->chip = &chips[id->driver_data]; + } data->last_chan = 0; /* force the first selection */ @@ -1313,11 +1326,14 @@ static int pca954x_probe(struct i2c_client *client, force = data->pca9548_cfg_info.pca9548_base_nr + num; } - class = 0; /* no class by default */ data->deselect |= (idle_disconnect_pd || idle_disconnect_dt) << num; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 10, 0) ret = i2c_mux_add_adapter(muxc, force, num, class); +#else + ret = i2c_mux_add_adapter(muxc, force, num); +#endif if (ret) goto fail_del_adapters; } @@ -1334,7 +1350,11 @@ static int pca954x_probe(struct i2c_client *client, return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int pca954x_remove(struct i2c_client *client) +#else static void pca954x_remove(struct i2c_client *client) +#endif { struct i2c_mux_core *muxc = i2c_get_clientdata(client); struct pca954x *data = i2c_mux_priv(muxc); @@ -1349,7 +1369,11 @@ static void pca954x_remove(struct i2c_client *client) } i2c_mux_del_adapters(muxc); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } #ifdef CONFIG_PM_SLEEP diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c index 83b0774ec9..c3c8995dcb 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c @@ -541,19 +541,19 @@ static int pca9641_do_gpio_reset(struct i2c_mux_core *muxc) usleep_range(reset_cfg->rst_delay_b, reset_cfg->rst_delay_b + 1); } - __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); + gpio_set_value(gpio_attr->gpio, gpio_attr->reset_on); if (reset_cfg->rst_delay) { usleep_range(reset_cfg->rst_delay, reset_cfg->rst_delay + 1); } - __gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); + gpio_set_value(gpio_attr->gpio, gpio_attr->reset_off); ret = -1; udelay_cnt = 0; timeout = reset_cfg->rst_delay_a; while (timeout > 0) { usleep_range(1, 2); - val = __gpio_get_value(gpio_attr->gpio); + val = gpio_get_value(gpio_attr->gpio); if (val == gpio_attr->reset_off) { ret = 0; PCA_DEBUG("pca9641_do_gpio_reset success.\n"); @@ -1272,7 +1272,11 @@ static int pca9641_reset_data_init(struct pca9541 *data) /* * I2C init/probing/exit functions */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) static int pca9541_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int pca9541_probe(struct i2c_client *client) +#endif { struct i2c_adapter *adap = client->adapter; struct i2c_mux_core *muxc; @@ -1322,7 +1326,11 @@ static int pca9541_probe(struct i2c_client *client, const struct i2c_device_id * PCA_DEBUG("pca9641_nr: %d.\n", force); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 10, 0) ret = i2c_mux_add_adapter(muxc, force, 0, 0); +#else + ret = i2c_mux_add_adapter(muxc, force, 0); +#endif if (ret) return ret; } else { @@ -1375,7 +1383,11 @@ static int pca9541_probe(struct i2c_client *client, const struct i2c_device_id * } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 10, 0) ret = i2c_mux_add_adapter(muxc, force, 0, 0); +#else + ret = i2c_mux_add_adapter(muxc, force, 0); +#endif if (ret) { dev_err(&client->dev, "Failed to register master selector.\n"); return ret; @@ -1388,12 +1400,20 @@ static int pca9541_probe(struct i2c_client *client, const struct i2c_device_id * return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int pca9541_remove(struct i2c_client *client) +#else static void pca9541_remove(struct i2c_client *client) +#endif { struct i2c_mux_core *muxc = i2c_get_clientdata(client); i2c_mux_del_adapters(muxc); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static struct i2c_driver pca9641_driver = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c index 643fc3b605..6b4e2f5ef4 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "wb_i2c_ocores.h" @@ -1157,7 +1158,11 @@ static int ocores_i2c_probe(struct platform_device *pdev) return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int ocores_i2c_remove(struct platform_device *pdev) +#else +static void ocores_i2c_remove(struct platform_device *pdev) +#endif { struct ocores_i2c *i2c = platform_get_drvdata(pdev); u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); @@ -1168,7 +1173,9 @@ static int ocores_i2c_remove(struct platform_device *pdev) /* remove adapter & data */ i2c_del_adapter(&i2c->adap); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static struct platform_driver ocores_i2c_driver = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c index c0a730e774..ef398fbb74 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c @@ -31,11 +31,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include "wb_indirect_dev.h" #define MODULE_NAME "wb-indirect-dev" @@ -813,7 +815,11 @@ static int wb_indirect_dev_probe(struct platform_device *pdev) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int wb_indirect_dev_remove(struct platform_device *pdev) +#else +static void wb_indirect_dev_remove(struct platform_device *pdev) +#endif { int i; @@ -822,11 +828,17 @@ static int wb_indirect_dev_remove(struct platform_device *pdev) if (indirect_dev_arry[i]->dev == &pdev->dev) { misc_deregister(&indirect_dev_arry[i]->misc); indirect_dev_arry[i] = NULL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#else + return; +#endif } } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static const struct of_device_id wb_indirect_dev_driver_of_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c index 6699397aa4..b6287417a6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include "wb_io_dev.h" @@ -638,7 +640,11 @@ static int io_dev_probe(struct platform_device *pdev) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int io_dev_remove(struct platform_device *pdev) +#else +static void io_dev_remove(struct platform_device *pdev) +#endif { int i; @@ -648,8 +654,9 @@ static int io_dev_remove(struct platform_device *pdev) io_dev_arry[i] = NULL; } } - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static struct of_device_id io_dev_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c index 45290ca843..9509ea5442 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c @@ -23,11 +23,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include "wb_lpc_drv.h" @@ -133,7 +135,11 @@ static int wb_lpc_probe(struct platform_device *pdev) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int wb_lpc_remove(struct platform_device *pdev) +#else +static void wb_lpc_remove(struct platform_device *pdev) +#endif { wb_lpc_dev_t *wb_lpc_dev; @@ -143,8 +149,9 @@ static int wb_lpc_remove(struct platform_device *pdev) LPC_DEV_DEBUG_VERBOSE("lpc base:0x%x, len:0x%x.\n", wb_lpc_dev->lpc_io_base, wb_lpc_dev->lpc_io_size); } LPC_DEV_DEBUG_VERBOSE("lpc remove.\n"); - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static struct of_device_id lpc_dev_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c index ba9cd692f8..d8c08c0e9c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c @@ -29,6 +29,7 @@ #include #include #include +#include #define mem_clear(data, size) memset((data), 0, (size)) @@ -44,6 +45,8 @@ #define MAC_BSC_MAX_RETRY (3) #define MAC_BSC_RETRY_SLEEP_TIME (10000) /* 10ms */ +static const struct i2c_device_id mac_id_table[]; + static int g_wb_mac_bsc_debug = 0; static int g_wb_mac_bsc_error = 0; @@ -761,10 +764,17 @@ static int mac_bsc_config_check(dev_params_t *dev_params) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int mac_probe(struct i2c_client *client) +#endif { struct mac_data *data; int ret, mac_id, index; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) + const struct i2c_device_id *id = i2c_match_id(mac_id_table, client); +#endif WB_MAC_BSC_DEBUG("=========mac_probe(%d-%04x)===========\n", client->adapter->nr, client->addr); @@ -783,6 +793,10 @@ static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id) data->client = client; i2c_set_clientdata(client, data); + if (!id) { + dev_err(&client->dev, "Failed to match i2c device id.\n"); + return -ENODEV; + } mac_id = id->driver_data; ret = find_mac_config(mac_id, &index); if (ret < 0) { @@ -834,12 +848,20 @@ static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int mac_remove(struct i2c_client *client) +#else static void mac_remove(struct i2c_client *client) +#endif { struct mac_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static const struct i2c_device_id mac_id_table[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c index 83904d7960..803d438bb9 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c @@ -24,12 +24,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include "wb_pcie_dev.h" @@ -865,7 +867,11 @@ static int pci_dev_probe(struct platform_device *pdev) return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int pci_dev_remove(struct platform_device *pdev) +#else +static void pci_dev_remove(struct platform_device *pdev) +#endif { int i; @@ -878,8 +884,9 @@ static int pci_dev_remove(struct platform_device *pdev) pcie_dev_arry[i] = NULL; } } - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static struct of_device_id pci_dev_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c index 678a48483b..5242b0be4b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "wb_platform_i2c_dev.h" @@ -721,7 +722,11 @@ static int platform_i2c_dev_probe(struct platform_device *pdev) return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int platform_i2c_dev_remove(struct platform_device *pdev) +#else +static void platform_i2c_dev_remove(struct platform_device *pdev) +#endif { int i; @@ -731,8 +736,9 @@ static int platform_i2c_dev_remove(struct platform_device *pdev) i2c_dev_arry[i] = NULL; } } - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static const struct of_device_id platform_i2c_dev_of_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c index dd13fe9a99..11c0d0c05b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c index f87dd63eca..4664916314 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "wb_spi_ocores.h" @@ -506,7 +507,7 @@ static void spioc_chipselect(struct spi_device *spi, int is_active) u8 tx_conf; int ret; - spioc = spi_master_get_devdata(spi->master); + spioc = spi_controller_get_devdata(spi->controller); spioc->transfer_busy_flag = 0; ret = spioc_wait_trans(spioc, msecs_to_jiffies(100)); if (ret < 0) { @@ -514,7 +515,7 @@ static void spioc_chipselect(struct spi_device *spi, int is_active) spioc->transfer_busy_flag = 1; return; } - spioc->chip_select = spi->chip_select; + spioc->chip_select = spi_get_chipselect(spi, 0); SPI_OC_VERBOSE("spioc_chipselect:%u, value:%d.\n", spioc->chip_select, is_active); tx_conf = 0; tx_conf |= SPIOC_CSID(spioc->chip_select); @@ -572,7 +573,7 @@ static int spioc_setup_transfer(struct spi_device *spi, struct spi_transfer *tra u32 hz; int div; - spioc = spi_master_get_devdata(spi->master); + spioc = spi_controller_get_devdata(spi->controller); ctrl = 0; if (spi->mode & SPI_LSB_FIRST) { @@ -625,14 +626,14 @@ static int spioc_spi_setup(struct spi_device *spi) return -EINVAL; } - spioc = spi_master_get_devdata(spi->master); - if (spi->chip_select >= spioc->num_chipselect) { + spioc = spi_controller_get_devdata(spi->controller); + if (spi_get_chipselect(spi, 0) >= spioc->num_chipselect) { SPI_OC_ERROR("Spi device chipselect:%u, more than max chipselect:%u.\n", - spi->chip_select, spioc->num_chipselect); + spi_get_chipselect(spi, 0), spioc->num_chipselect); return -EINVAL; } SPI_OC_VERBOSE("Support spi device mode:0x%x, chip_select:%u.\n", - spi->mode, spi->chip_select); + spi->mode, spi_get_chipselect(spi, 0)); return 0; } @@ -776,7 +777,7 @@ static int spioc_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) return 0; } - spioc = spi_master_get_devdata(spi->master); + spioc = spi_controller_get_devdata(spi->controller); if (spioc->transfer_busy_flag) { ret = -EBUSY; goto err; @@ -919,19 +920,19 @@ static int ocores_spi_config_init(struct spioc *spioc) static int spioc_probe(struct platform_device *pdev) { - struct spi_master *master; + struct spi_controller *ctlr; struct spioc *spioc; int ret; bool be; ret = -1; - master = spi_alloc_master(&pdev->dev, sizeof(struct spioc)); - if (!master) { - dev_err(&pdev->dev, "Failed to alloc spi master.\n"); + ctlr = spi_alloc_master(&pdev->dev, sizeof(struct spioc)); + if (!ctlr) { + dev_err(&pdev->dev, "Failed to alloc spi controller.\n"); goto out; } - spioc = spi_master_get_devdata(master); + spioc = spi_controller_get_devdata(ctlr); platform_set_drvdata(pdev, spioc); spioc->dev = &pdev->dev; @@ -980,17 +981,17 @@ static int spioc_probe(struct platform_device *pdev) } /* master state */ - master->num_chipselect = spioc->num_chipselect; - master->mode_bits = MODEBITS; - master->setup = spioc_spi_setup; + ctlr->num_chipselect = spioc->num_chipselect; + ctlr->mode_bits = MODEBITS; + ctlr->setup = spioc_spi_setup; if (spioc->dev->of_node) { - master->dev.of_node = pdev->dev.of_node; + ctlr->dev.of_node = pdev->dev.of_node; } else { - master->bus_num = spioc->bus_num; + ctlr->bus_num = spioc->bus_num; } /* setup the state for the bitbang driver */ - spioc->bitbang.master = master; + spioc->bitbang.ctlr = ctlr; spioc->bitbang.setup_transfer = spioc_setup_transfer; spioc->bitbang.chipselect = spioc_chipselect; spioc->bitbang.txrx_bufs = spioc_spi_txrx_bufs; @@ -1021,27 +1022,32 @@ static int spioc_probe(struct platform_device *pdev) goto free; } dev_info(spioc->dev, "registered spi-%d for %s with base address:0x%x success.\n", - master->bus_num, spioc->dev_name, spioc->base_addr); + ctlr->bus_num, spioc->dev_name, spioc->base_addr); return ret; free: - spi_master_put(master); + spi_controller_put(ctlr); out: return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int spioc_remove(struct platform_device *pdev) +#else +static void spioc_remove(struct platform_device *pdev) +#endif { struct spioc *spioc; - struct spi_master *master; + struct spi_controller *ctlr; spioc = platform_get_drvdata(pdev); - master = spioc->bitbang.master; + ctlr = spioc->bitbang.ctlr; spi_bitbang_stop(&spioc->bitbang); platform_set_drvdata(pdev, NULL); - spi_master_put(master); - + spi_controller_put(ctlr); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static const struct of_device_id spioc_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c index 2fae45c72a..5214bd5894 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c @@ -31,6 +31,7 @@ #include #include #include +#include #define WB_UCD9081_RAIL1H (0x00) /* Channel 1 voltage address, high 8 bits */ #define WB_UCD9081_RAIL1L (0x01) /* Channel 1 voltage address, low 8 bits */ @@ -283,7 +284,11 @@ static struct attribute *ucd9081_hwmon_attrs[] = { }; ATTRIBUTE_GROUPS(ucd9081_hwmon); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) static int ucd9081_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int ucd9081_probe(struct i2c_client *client) +#endif { int ret; struct ucd9081_data *data; @@ -315,7 +320,11 @@ static int ucd9081_probe(struct i2c_client *client, const struct i2c_device_id * return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int ucd9081_remove(struct i2c_client *client) +#else static void ucd9081_remove(struct i2c_client *client) +#endif { struct ucd9081_data *data; @@ -323,7 +332,11 @@ static void ucd9081_remove(struct i2c_client *client) dev_info(&client->dev, "ucd9081 do remove\n"); hwmon_device_unregister(data->hwmon_dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static const struct i2c_device_id ucd9081_id[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c index 835386127f..e4c36432e1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c @@ -246,7 +246,11 @@ static int dfd_irq_probe(struct platform_device *pdev) return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int dfd_irq_remove(struct platform_device *pdev) +#else +static void dfd_irq_remove(struct platform_device *pdev) +#endif { dfd_irq_t *dfd_irq; struct uio_info *dfd_irq_info; @@ -254,12 +258,13 @@ static int dfd_irq_remove(struct platform_device *pdev) dfd_irq = platform_get_drvdata(pdev); dfd_irq_info = &dfd_irq->dfd_irq_info; + sysfs_remove_group(&pdev->dev.kobj, &dfd_irq->attr_group); uio_unregister_device(dfd_irq_info); + platform_set_drvdata(pdev, NULL); kfree(dfd_irq); - - sysfs_remove_group(&pdev->dev.kobj, &dfd_irq->attr_group); - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static struct of_device_id dfd_irq_match[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c index 899886a039..ca5201a201 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c @@ -21,7 +21,9 @@ #include #include #include -#include +#include +#include +#include #include #include #include @@ -30,6 +32,7 @@ #include #include #include +#include #include "wb_wdt.h" @@ -310,15 +313,15 @@ static void wdt_hwping(wb_wdt_priv_t *priv) case HW_ALGO_TOGGLE: gpio_wdt = &priv->gpio_wdt; gpio_wdt->state = !gpio_wdt->state; - gpio_set_value_cansleep(gpio_wdt->gpio, gpio_wdt->state); + gpiod_set_value_cansleep(gpio_wdt->gpiod, gpio_wdt->state); WDT_VERBOSE("gpio toggle wdt work. val:%u\n", gpio_wdt->state); break; case HW_ALGO_LEVEL: gpio_wdt = &priv->gpio_wdt; /* Pulse */ - gpio_set_value_cansleep(gpio_wdt->gpio, !gpio_wdt->active_low); + gpiod_set_value_cansleep(gpio_wdt->gpiod, !gpio_wdt->active_low); udelay(1); - gpio_set_value_cansleep(gpio_wdt->gpio, gpio_wdt->active_low); + gpiod_set_value_cansleep(gpio_wdt->gpiod, gpio_wdt->active_low); WDT_VERBOSE("gpio level wdt work.\n"); break; } @@ -795,7 +798,8 @@ static int gpio_wdt_init(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) { struct device *dev; gpio_wdt_info_t *gpio_wdt; - enum of_gpio_flags flags; + unsigned long flags; + struct gpio_desc *gpiod; uint32_t f = 0; int ret; @@ -803,33 +807,42 @@ static int gpio_wdt_init(wb_wdt_priv_t *priv, wb_wdt_device_t *wb_wdt_device) gpio_wdt = &priv->gpio_wdt; if (dev->of_node) { - gpio_wdt->gpio = of_get_gpio_flags(dev->of_node, 0, &flags); + gpiod = devm_gpiod_get_index(dev, NULL, 0, GPIOD_ASIS); + if (IS_ERR(gpiod)) { + dev_err(dev, "Failed to get gpio descriptor, ret: %ld.\n", PTR_ERR(gpiod)); + return PTR_ERR(gpiod); + } + gpio_wdt->gpiod = gpiod; + gpio_wdt->gpio = desc_to_gpio(gpiod); + gpio_wdt->active_low = gpiod_is_active_low(gpiod); } else { gpio_wdt->gpio = wb_wdt_device->wdt_config_mode.gpio_wdt.gpio; flags = wb_wdt_device->wdt_config_mode.gpio_wdt.flags; - } - if (!gpio_is_valid(gpio_wdt->gpio)) { - dev_err(dev, "gpio is invalid.\n"); - return gpio_wdt->gpio; + gpio_wdt->gpiod = gpio_to_desc(gpio_wdt->gpio); + if (!gpio_wdt->gpiod) { + dev_err(dev, "gpio is invalid.\n"); + return -ENODEV; + } + gpio_wdt->active_low = !!(flags & GPIOF_ACTIVE_LOW); } - gpio_wdt->active_low = flags & OF_GPIO_ACTIVE_LOW; - if(priv->hw_algo == HW_ALGO_TOGGLE) { f = GPIOF_IN; } else { f = gpio_wdt->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; } - ret = devm_gpio_request_one(dev, gpio_wdt->gpio, f, - dev_name(dev)); - if (ret) { - dev_err(dev, "devm_gpio_request_one failed.\n"); - return ret; + if (!dev->of_node) { + ret = devm_gpio_request_one(dev, gpio_wdt->gpio, f, + dev_name(dev)); + if (ret) { + dev_err(dev, "devm_gpio_request_one failed.\n"); + return ret; + } } gpio_wdt->state = gpio_wdt->active_low; - gpio_direction_output(gpio_wdt->gpio, gpio_wdt->state); + gpiod_direction_output(gpio_wdt->gpiod, gpio_wdt->state); WDT_VERBOSE("active_low:%d\n", gpio_wdt->active_low); return 0; @@ -1164,10 +1177,10 @@ static void unregister_action(struct platform_device *pdev) if (priv->config_mode == GPIO_FEED_WDT_MODE) { gpio_wdt = &priv->gpio_wdt; - gpio_set_value_cansleep(gpio_wdt->gpio, !gpio_wdt->active_low); + gpiod_set_value_cansleep(gpio_wdt->gpiod, !gpio_wdt->active_low); if (priv->hw_algo == HW_ALGO_TOGGLE) { - gpio_direction_input(gpio_wdt->gpio); + gpiod_direction_input(gpio_wdt->gpiod); } } else { logic_wdt = &priv->logic_wdt; @@ -1182,13 +1195,18 @@ static void unregister_action(struct platform_device *pdev) return; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int wb_wdt_remove(struct platform_device *pdev) +#else +static void wb_wdt_remove(struct platform_device *pdev) +#endif { WDT_VERBOSE("enter remove wdt.\n"); unregister_action(pdev); dev_info(&pdev->dev, "remove wdt finish.\n"); - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static void wb_wdt_shutdown(struct platform_device *pdev) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h index 4314646888..fbed3dca3b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h @@ -21,14 +21,17 @@ #ifndef __WB_WDT_H__ #define __WB_WDT_H__ -#include +#include #define SYSFS_NO_CFG (0xff) #define INVALID_REG_ADDR (0xffffffff) +struct gpio_desc; + typedef struct gpio_wdt_info_s { int gpio; - enum of_gpio_flags flags; + unsigned long flags; + struct gpio_desc *gpiod; bool active_low; bool state; }gpio_wdt_info_t; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c index 3d2b2ff0ba..c32a2d9096 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c @@ -29,6 +29,7 @@ #include #include #include +#include #define WB_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ #define WB_I2C_RETRY_TIME (10) @@ -513,7 +514,11 @@ static const struct attribute_group xdpe132g5c_sysfs_attrs_group = { .attrs = xdpe132g5c_sysfs_attrs, }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) static int xdpe132g5c_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int xdpe132g5c_probe(struct i2c_client *client) +#endif { struct xdpe_data *data; int ret; @@ -548,7 +553,11 @@ static int xdpe132g5c_probe(struct i2c_client *client, const struct i2c_device_i return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int xdpe132g5c_remove(struct i2c_client *client) +#else static void xdpe132g5c_remove(struct i2c_client *client) +#endif { struct xdpe_data *data; @@ -556,7 +565,11 @@ static void xdpe132g5c_remove(struct i2c_client *client) data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static const struct i2c_device_id xdpe132g5c_id[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c index 493f477a16..7200b6f66d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "pmbus.h" static int g_wb_xdpe132g5_pmbus_debug = 0; @@ -349,8 +350,11 @@ static struct pmbus_driver_info xdpe132g5c_info = { .identify = xdpe132g5c_identify, }; -static int xdpe132g5c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) +static int xdpe132g5c_probe(struct i2c_client *client, const struct i2c_device_id *id) +#else +static int xdpe132g5c_probe(struct i2c_client *client) +#endif { int status; struct pmbus_driver_info *info; @@ -375,10 +379,18 @@ static int xdpe132g5c_probe(struct i2c_client *client, return status; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int xdpe132g5c_remove(struct i2c_client *client) +#else static void xdpe132g5c_remove(struct i2c_client *client) +#endif { sysfs_remove_group(&client->dev.kobj, &xdpe132g5c_sysfs_attrs_group); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + return 0; +#else return; +#endif } static const struct i2c_device_id xdpe132g5c_id[] = { diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py index da9d1883a3..f62510130e 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py @@ -70,7 +70,7 @@ def get_name(self): Returns: string: The name of the device """ - return "PSU {}".format(self.index) + return "PSU{}".format(self.index) def get_presence(self): """ diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/rules b/platform/broadcom/sonic-platform-modules-micas/debian/rules index baa92b2338..ba89d3bc48 100755 --- a/platform/broadcom/sonic-platform-modules-micas/debian/rules +++ b/platform/broadcom/sonic-platform-modules-micas/debian/rules @@ -69,7 +69,7 @@ COMPILE_WHL: $(COMPILE_DIRS) binary: binary-indep @echo "=======================================================" -binary-indep: +binary-indep: build # Resuming debhelper scripts dh_testroot dh_install diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_dev_device.c index 76f8911e0b..0fb31ce9ed 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_dev_device.c @@ -111,7 +111,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c index eb7d3294ab..a2eb86f4a6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-32c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -210,7 +210,7 @@ static int __init wb_i2c_mux_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_mux_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_dev_device.c index 6e187eae97..5d6b28f7cb 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_dev_device.c @@ -111,7 +111,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_mux_pca954x_device.c index 387ad5b223..fbe0fe44d3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_mux_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48gt4v/modules/driver/wb_i2c_mux_pca954x_device.c @@ -112,7 +112,7 @@ static int __init wb_i2c_mux_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_mux_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_dev_device.c index 865e7afea4..d38091cf71 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_dev_device.c @@ -106,7 +106,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c index f12a710134..cb7d47bd92 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6510-48v8c/modules/driver/wb_i2c_mux_pca954x_device.c @@ -262,7 +262,7 @@ static int __init wb_i2c_mux_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_mux_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c index 94a4ca54e5..fd22dc93a1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c @@ -295,7 +295,7 @@ static int __init wb_fpga_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { fpga_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c index 89e8f32213..1c963db00b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c @@ -141,7 +141,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_fpga_pca954x_device.c index ed0894c095..3a017a2e42 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_fpga_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_fpga_pca954x_device.c @@ -103,7 +103,7 @@ static int __init wb_fpga_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { fpga_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_i2c_dev_device.c index bfeace96e1..1fb01e7114 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-48c8qc/modules/driver/wb_i2c_dev_device.c @@ -126,7 +126,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_fpga_pca954x_device.c index 4e442d8544..cb7960d218 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_fpga_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_fpga_pca954x_device.c @@ -379,7 +379,7 @@ static int __init wb_fpga_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { fpga_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_i2c_dev_device.c index 9a3aef3297..e6bb634ba2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6920-32qc2x/modules/driver/wb_i2c_dev_device.c @@ -112,7 +112,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_fpga_pca954x_device.c index ecb8460476..ef0bb81da4 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_fpga_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_fpga_pca954x_device.c @@ -798,7 +798,7 @@ static int __init wb_fpga_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { fpga_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_dev_device.c index 0f97f8f5e0..805004f5a4 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_dev_device.c @@ -156,7 +156,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_mux_pca954x_device.c index dc54dee29f..307dbe9423 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_mux_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_i2c_mux_pca954x_device.c @@ -112,7 +112,7 @@ static int __init wb_i2c_mux_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_mux_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_spi_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_spi_dev_device.c index 45f6038596..27b3c49cc2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_spi_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6930-64qc/modules/driver/wb_spi_dev_device.c @@ -72,7 +72,7 @@ struct spi_board_info spi_dev_device_info[] = { static int __init wb_spi_dev_device_init(void) { int i; - struct spi_master *master; + struct spi_controller *ctlr; struct spi_device *spi; int spi_dev_num; @@ -86,14 +86,14 @@ static int __init wb_spi_dev_device_init(void) } for (i = 0; i < ARRAY_SIZE(spi_dev_device_info); i++) { - master = wb_spi_master_busnum_to_master(spi_dev_device_info[i].bus_num); - if (!master) { + ctlr = wb_spi_master_busnum_to_master(spi_dev_device_info[i].bus_num); + if (!ctlr) { printk(KERN_ERR "get bus_num %u spi master failed.\n", spi_dev_device_info[i].bus_num); continue; } - spi = spi_new_device(master, &spi_dev_device_info[i]); - put_device(&master->dev); + spi = spi_new_device(ctlr, &spi_dev_device_info[i]); + spi_controller_put(ctlr); if (spi) { g_spi_device[i] = spi; } else { diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_dev_device.c index c0a7e6c002..6854f6cfc6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_dev_device.c @@ -127,7 +127,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_mux_pca954x_device.c index 6d96bb5659..973d877957 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_mux_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-128qc/modules/driver/wb_i2c_mux_pca954x_device.c @@ -505,7 +505,7 @@ static int __init wb_i2c_mux_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_mux_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/config/x86_64_micas_m2_w6940_64oc_r0_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/config/x86_64_micas_m2_w6940_64oc_r0_config.py index 638ad724e5..de33d9605b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/config/x86_64_micas_m2_w6940_64oc_r0_config.py +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/config/x86_64_micas_m2_w6940_64oc_r0_config.py @@ -11,6 +11,7 @@ "pmon_syslog": 1, "sff_temp_polling": 1, "reboot_cause": 1, + "generate_airflow": 1, } DEV_MONITOR_PARAM = { @@ -1641,3 +1642,69 @@ {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, ], } + +AIR_FLOW_CONF = { + "psu_fan_airflow": { + "intake": ['PA3000I-F', 'CRPS3000CL', 'ECDL3000123'], + "exhaust": ['PA3000I-R', 'CRPS3000CLR'] + }, + + "fanairflow": { + "intake": ['FAN80-02-F'], + "exhaust": ['FAN80-02-R'] + }, + + "fans": [ + { + "name": "FAN1", + "e2_type": "fru", + "e2_path": "/sys/bus/i2c/devices/52-0050/eeprom", + "area": "productInfoArea", + "field": "productName", + "decode": "fanairflow" + }, + { + "name": "FAN2", + "e2_type": "fru", + "e2_path": "/sys/bus/i2c/devices/53-0050/eeprom", + "area": "productInfoArea", + "field": "productName", + "decode": "fanairflow" + }, + { + "name": "FAN3", + "e2_type": "fru", + "e2_path": "/sys/bus/i2c/devices/54-0050/eeprom", + "area": "productInfoArea", + "field": "productName", + "decode": "fanairflow" + }, + { + "name": "FAN4", + "e2_type": "fru", + "e2_path": "/sys/bus/i2c/devices/55-0050/eeprom", + "area": "productInfoArea", + "field": "productName", + "decode": "fanairflow" + } + ], + + "psus": [ + { + "name": "PSU1", + "e2_type": "fru", + "e2_path": "/sys/bus/i2c/devices/42-0050/eeprom", + "area": "productInfoArea", + "field": "productPartModelName", + "decode": "psu_fan_airflow" + }, + { + "name": "PSU2", + "e2_type": "fru", + "e2_path": "/sys/bus/i2c/devices/43-0050/eeprom", + "area": "productInfoArea", + "field": "productPartModelName", + "decode": "psu_fan_airflow" + } + ] +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_device.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_device.py index b79db186fd..e2eaafefeb 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_device.py +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_device.py @@ -2,16 +2,17 @@ psu_fan_airflow = { "intake": ['CRPS3000CL', 'ECDL3000123'], - "exhaust": [] + "exhaust": ['CRPS3000CLR'], } fanairflow = { "intake": ['FAN80-02-F'], - "exhaust": [], + "exhaust": ['FAN80-02-R'], } psu_display_name = { "PA3000I-F": ['CRPS3000CL', 'ECDL3000123'], + "PA3000I-R": ['CRPS3000CLR'] } psutypedecode = { @@ -119,6 +120,7 @@ class threshold: "Max": { "ECDL3000123": threshold.PSU_FAN_SPEED_MAX, "CRPS3000CL": threshold.PSU_A_FAN_SPEED_MAX, + "CRPS3000CLR": threshold.PSU_A_FAN_SPEED_MAX, }, "Unit": Unit.Speed }, @@ -208,6 +210,7 @@ class threshold: "Max": { "ECDL3000123": threshold.PSU_FAN_SPEED_MAX, "CRPS3000CL": threshold.PSU_A_FAN_SPEED_MAX, + "CRPS3000CLR": threshold.PSU_A_FAN_SPEED_MAX, }, "Unit": Unit.Speed }, @@ -445,7 +448,7 @@ class threshold: "present": {"loc": "/sys/s3ip/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, - "led": {"loc": "/dev/cpld10", "offset":0xd0, "len": 1, "way":"devfile"}, + "led": {"bus": 50, "addr": 0x0d, "offset":0xd0, "len": 1, "way":"i2c"}, "led_attrs": { "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 @@ -454,7 +457,7 @@ class threshold: "Rotor": { "Rotor1_config": { "name": "Rotor1", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x90, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x90, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -468,7 +471,7 @@ class threshold: }, "Rotor2_config": { "name": "Rotor2", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x90, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x90, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan1/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan1/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -489,7 +492,7 @@ class threshold: "present": {"loc": "/sys/s3ip/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, - "led": {"loc": "/dev/cpld10", "offset":0xd1, "len": 1, "way":"devfile"}, + "led": {"bus": 50, "addr": 0x0d, "offset":0xd1, "len": 1, "way":"i2c"}, "led_attrs": { "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 @@ -498,7 +501,7 @@ class threshold: "Rotor": { "Rotor1_config": { "name": "Rotor1", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x91, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x91, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -512,7 +515,7 @@ class threshold: }, "Rotor2_config": { "name": "Rotor2", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x91, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x91, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan2/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan2/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -533,7 +536,7 @@ class threshold: "present": {"loc": "/sys/s3ip/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, - "led": {"loc": "/dev/cpld10", "offset":0xd2, "len": 1, "way":"devfile"}, + "led": {"bus": 50, "addr": 0x0d, "offset":0xd2, "len": 1, "way":"i2c"}, "led_attrs": { "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 @@ -542,7 +545,7 @@ class threshold: "Rotor": { "Rotor1_config": { "name": "Rotor1", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x92, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x92, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -556,7 +559,7 @@ class threshold: }, "Rotor2_config": { "name": "Rotor2", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x92, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x92, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan3/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan3/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -577,7 +580,7 @@ class threshold: "present": {"loc": "/sys/s3ip/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, - "led": {"loc": "/dev/cpld10", "offset":0xd3, "len": 1, "way":"devfile"}, + "led": {"bus": 50, "addr": 0x0d, "offset":0xd3, "len": 1, "way":"i2c"}, "led_attrs": { "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 @@ -586,7 +589,7 @@ class threshold: "Rotor": { "Rotor1_config": { "name": "Rotor1", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x93, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x93, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, @@ -600,7 +603,7 @@ class threshold: }, "Rotor2_config": { "name": "Rotor2", - "Set_speed": {"loc": "/dev/cpld10", "offset":0x93, "len": 1, "way":"devfile"}, + "Set_speed": {"bus": 50, "addr": 0x0d, "offset":0x93, "len": 1, "way":"i2c"}, "Running": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, "SpeedMin": threshold.FAN_SPEED_MIN, diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_monitor.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_monitor.py index 4e95787950..b08320c474 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/hal-config/x86_64_micas_m2_w6940_64oc_r0_monitor.py @@ -43,7 +43,7 @@ "pwm_min": 0x80, "pwm_max": 0xff, "Kp": 1.5, - "Ki": 1, + "Ki": 0.3, "Kd": 0.3, "target": 90, "value": [None, None, None], @@ -90,13 +90,15 @@ "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105, "invalid": -100000, "error": -99999}, "INLET_TEMP": {"name": "INLET_TEMP", "warning": 50, "critical": 55, "fix": -2}, "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 75}, - "CPU_TEMP": {"name": "CPU_TEMP", "warning": 90, "critical": 95}, - "MOS_TEMP": {"name": "MOS_TEMP", "warning": 100, "critical": 125}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 95, "critical": 100}, + "MOS_TEMP": {"name": "MOS_TEMP", "warning": 115, "critical": 125}, "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 95, "critical": 100}, "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, }, "fancontrol_para": { + "fan_air_flow_monitor":1, + "psu_air_flow_monitor":1, "interval": 5, "max_pwm": 0xff, "min_pwm": 0x80, @@ -149,6 +151,10 @@ "board_fan_led": [ {"led_name": "FRONT_FAN_LED"}, ], + "fan_air_flow_monitor":1, + "psu_air_flow_monitor":1, + "psu_air_flow_amber_num":1, + "fan_air_flow_amber_num":1, }, "otp_reboot_judge_file": { diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_fpga_pca954x_device.c index 043ec82366..e252c7ea5d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_fpga_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_fpga_pca954x_device.c @@ -455,7 +455,7 @@ static int __init wb_fpga_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { fpga_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_dev_device.c index 92bced3558..af01167d31 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_dev_device.c @@ -147,7 +147,7 @@ static int __init wb_i2c_dev_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_dev_device_data->client = NULL; printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_mux_pca954x_device.c index 1bc2aafed2..13511bf168 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_mux_pca954x_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_i2c_mux_pca954x_device.c @@ -88,7 +88,7 @@ static int __init wb_i2c_mux_pca954x_device_init(void) continue; } client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); - if (!client) { + if (IS_ERR(client) || !client) { i2c_mux_pca954x_device_data->client = NULL; printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_wdt_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_wdt_device.c index e40ed10639..5fd6e4ffba 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_wdt_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_wdt_device.c @@ -49,7 +49,7 @@ static wb_wdt_device_t wb_wdt_device_data_0 = { .feed_time = 9000, .config_dev_name = "/dev/cpld1", .config_mode = 1, - .priv_func_mode = 3, + .priv_func_mode = 4, .enable_reg = 0xb0, .enable_val = 0x1, .disable_val = 0x0, @@ -58,7 +58,7 @@ static wb_wdt_device_t wb_wdt_device_data_0 = { .timeleft_cfg_reg = 0xb2, .hw_algo = "toggle", .wdt_config_mode.gpio_wdt = { - .gpio = 346, + .gpio = 10074, .flags = 1 }, .timer_accuracy = 1600, /* 1.6s */ @@ -72,7 +72,7 @@ static wb_wdt_device_t wb_wdt_device_data_1 = { .feed_time = 30000, .config_dev_name = "/dev/cpld1", .config_mode = 2, - .priv_func_mode = 3, + .priv_func_mode = 4, .enable_reg = 0xba, .enable_val = 0x1, .disable_val = 0x0, @@ -87,7 +87,6 @@ static wb_wdt_device_t wb_wdt_device_data_1 = { .logic_func_mode = 4, }, .timer_accuracy = 6000, /* 6s */ - .sysfs_index = SYSFS_NO_CFG, }; static void wb_wdt_device_release(struct device *dev) diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg index 7442d55dd1..7fa5874002 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg @@ -3460,4 +3460,3 @@ hwmon_curr.mode_0x0007_0x03=constant hwmon_curr.int_cons_0x0007_0x03=19000 hwmon_curr.mode_0x0007_0x05=constant hwmon_curr.int_cons_0x0007_0x05=-3100 - From 7e0eae6d089a53c9e1e8e29b20f1588ce199abea Mon Sep 17 00:00:00 2001 From: luka-micas Date: Wed, 12 Aug 2026 06:40:33 +0000 Subject: [PATCH 2/2] [Platform/Micas] add TH6 m2-w6950-128oc and m2-w6951-64hc-cp Signed-off-by: luka-micas --- .../M2-W6950-O128-COPPER/default_sku | 1 + .../M2-W6950-O128-COPPER/hwsku.json | 654 + .../M2-W6950-O128-COPPER/media_settings.json | 8196 ++++++++ .../M2-W6950-O128-COPPER/port_config.ini | 131 + .../M2-W6950-O128-COPPER/sai.profile | 1 + .../M2-W6950-O128-COPPER/sap_bcm_81394.cfg | 246 + ...6-m2-w6950-o128-copper-128x800G.config.yml | 2195 +++ .../M2-W6950-O128-LPO-N/default_sku | 1 + .../M2-W6950-O128-LPO-N/hwsku.json | 654 + .../M2-W6950-O128-LPO-N/media_settings.json | 8196 ++++++++ .../M2-W6950-O128-LPO-N/port_config.ini | 131 + .../M2-W6950-O128-LPO-N/sai.profile | 1 + .../M2-W6950-O128-LPO-N/sap_bcm_81394.cfg | 246 + ...h6-m2-w6950-o128-lpo-n-128x800G.config.yml | 2182 +++ .../M2-W6950-O128/default_sku | 1 + .../M2-W6950-O128/hwsku.json | 654 + .../M2-W6950-O128/media_settings.json | 8196 ++++++++ .../M2-W6950-O128/port_config.ini | 131 + .../M2-W6950-O128/sai.profile | 1 + .../M2-W6950-O128/sap_bcm_81394.cfg | 246 + .../th6-m2-w6950-o128-128x800G.config.yml | 2182 +++ .../M2-W6950-Q256/default_sku | 1 + .../M2-W6950-Q256/hwsku.json | 654 + .../M2-W6950-Q256/media_settings.json | 8196 ++++++++ .../M2-W6950-Q256/port_config.ini | 259 + .../M2-W6950-Q256/sai.profile | 1 + .../M2-W6950-Q256/sap_bcm_81394.cfg | 246 + .../th6-m2-w6950-q256-256x400G.config.yml | 2182 +++ .../x86_64-micas_m2-w6950-128oc-r0/bmc.json | 6 + .../custom_led.bin | Bin 0 -> 810 bytes .../default_sku | 1 + .../x86_64-micas_m2-w6950-128oc-r0/dev.xml | 154 + .../x86_64-micas_m2-w6950-128oc-r0/fru.py | 961 + .../installer.conf | 42 + .../led_proc_init.soc | 4 + .../ledswitch_monitor.py | 456 + .../x86_64-micas_m2-w6950-128oc-r0/monitor.py | 402 + .../x86_64-micas_m2-w6950-128oc-r0/pcie.yaml | 285 + .../platform.json | 3740 ++++ .../platform_asic | 1 + .../platform_components.json | 19 + .../platform_env.conf | 3 + .../platform_env_fac.conf | 1 + .../plugins/eeprom.py | 19 + .../plugins/sfputil.py | 379 + .../plugins/ssd_util.py | 318 + .../pmon_daemon_control.json | 4 + .../system_health_monitoring_config.json | 0 .../M2-W6951-64HC-CP/hwsku.json | 333 + .../M2-W6951-64HC-CP/port_config.ini | 67 + .../M2-W6951-64HC-CP/sai.profile | 1 + .../th6-m2-w6951-64hc-cp-64x1600G.config.yml | 1169 ++ .../custom_led.bin | Bin 0 -> 898 bytes .../default_sku | 1 + .../x86_64-micas_m2-w6951-64hc-cp-r0/dev.xml | 1153 ++ .../x86_64-micas_m2-w6951-64hc-cp-r0/fru.py | 961 + .../installer.conf | 41 + .../led_proc_init.soc | 2 + .../media_settings.json | 4100 ++++ .../monitor.py | 402 + .../pcie.yaml | 240 + .../platform.json | 4402 +++++ .../platform_asic | 1 + .../platform_components.json | 17 + .../platform_env.conf | 2 + .../plugins/sfputil.py | 443 + .../plugins/ssd_util.py | 319 + .../pmon_daemon_control.json | 4 + .../postinit_cmd_file.soc | 4 + .../system_health_monitoring_config.json | 0 platform/broadcom/one-image.mk | 2 + platform/broadcom/platform-modules-micas.mk | 17 + .../common/Makefile | 2 + .../common/app/Makefile | 3 +- .../common/app/dev_util/Makefile | 1 + .../app/fw_upgrade/fw_upgrade/fw_upgrade.c | 201 +- .../fw_upgrade/include/fw_upgrade.h | 70 +- .../common/app/hw_test/Makefile | 15 + .../common/app/hw_test/hw_test_app/Makefile | 31 + .../app/hw_test/hw_test_app/ft_ddr_test.c | 2074 ++ .../common/app/hw_test/hw_test_app/hw_dram.c | 804 + .../common/app/hw_test/hw_test_app/hw_emmc.c | 115 + .../common/app/hw_test/hw_test_app/hw_i2c.c | 692 + .../common/app/hw_test/hw_test_app/hw_misc.c | 712 + .../app/hw_test/hw_test_app/hw_mtdflash.c | 699 + .../common/app/hw_test/hw_test_app/hw_pci.c | 469 + .../common/app/hw_test/hw_test_app/hw_test.c | 163 + .../common/app/hw_test/hw_test_app/hw_usb.c | 28 + .../hw_test_app/include/hw_dram/fac_common.h | 32 + .../hw_test_app/include/hw_dram/ft_ddr_test.h | 104 + .../hw_test_app/include/hw_dram/hw_dram.h | 9 + .../hw_test_app/include/hw_emmc/hw_emmc.h | 6 + .../hw_test_app/include/hw_i2c/hw_i2c.h | 27 + .../hw_test_app/include/hw_i2c/i2c-dev.h | 69 + .../hw_test/hw_test_app/include/hw_i2c/i2c.h | 734 + .../hw_test/hw_test_app/include/hw_i2c/rtc.h | 100 + .../hw_test_app/include/hw_misc/dram_driver.h | 28 + .../hw_test_app/include/hw_misc/hw_misc.h | 26 + .../hw_test_app/include/hw_mtd/hw_mtdflash.h | 25 + .../hw_test_app/include/hw_mtd/mtd-abi.h | 199 + .../hw_test_app/include/hw_pci/hw_pci.h | 24 + .../app/hw_test/hw_test_app/include/hw_test.h | 14 + .../hw_test_app/include/hw_usb/hw_usb.h | 8 + .../app/hw_test/hw_test_driver/Makefile | 17 + .../app/hw_test/hw_test_driver/hw_test.c | 728 + .../app/hw_test/hw_test_driver/hw_test.h | 28 + .../common/lib/plat_hal/chassisbase.py | 41 +- .../common/lib/plat_hal/dcdc.py | 8 +- .../common/lib/plat_hal/interface.py | 29 +- .../common/lib/plat_hal/sensor.py | 23 +- .../common/modules/Makefile | 14 +- .../common/modules/i2c-designware/Makefile | 19 + .../modules/i2c-designware/i2c-ccgx-ucsi.h | 11 + .../i2c-designware/i2c-designware-amdpsp.c | 318 + .../i2c-designware/i2c-designware-baytrail.c | 44 + .../i2c-designware/i2c-designware-common.c | 835 + .../i2c-designware/i2c-designware-core.h | 409 + .../i2c-designware/i2c-designware-master.c | 1081 ++ .../i2c-designware/i2c-designware-pcidrv.c | 374 + .../i2c-designware/i2c-designware-platdrv.c | 418 + .../i2c-designware/i2c-designware-slave.c | 284 + .../common/modules/i2c-designware/math.h | 148 + .../common/modules/i2c-designware/units.h | 108 + .../common/modules/ixgbe/Makefile | 87 + .../common/modules/ixgbe/Module.supported | 1 + .../common/modules/ixgbe/auxiliary_compat.h | 122 + .../common/modules/ixgbe/common.mk | 463 + .../common/modules/ixgbe/ixgbe.h | 1547 ++ .../common/modules/ixgbe/ixgbe_82598.c | 1379 ++ .../common/modules/ixgbe/ixgbe_82598.h | 22 + .../common/modules/ixgbe/ixgbe_82599.c | 2537 +++ .../common/modules/ixgbe/ixgbe_82599.h | 34 + .../common/modules/ixgbe/ixgbe_api.c | 1721 ++ .../common/modules/ixgbe/ixgbe_api.h | 197 + .../common/modules/ixgbe/ixgbe_common.c | 5239 +++++ .../common/modules/ixgbe/ixgbe_common.h | 151 + .../common/modules/ixgbe/ixgbe_dcb.c | 702 + .../common/modules/ixgbe/ixgbe_dcb.h | 144 + .../common/modules/ixgbe/ixgbe_dcb_82598.c | 340 + .../common/modules/ixgbe/ixgbe_dcb_82598.h | 69 + .../common/modules/ixgbe/ixgbe_dcb_82599.c | 578 + .../common/modules/ixgbe/ixgbe_dcb_82599.h | 97 + .../common/modules/ixgbe/ixgbe_dcb_nl.c | 1406 ++ .../common/modules/ixgbe/ixgbe_debugfs.c | 1447 ++ .../common/modules/ixgbe/ixgbe_devlink.c | 1534 ++ .../common/modules/ixgbe/ixgbe_devlink.h | 50 + .../common/modules/ixgbe/ixgbe_e610.c | 6282 ++++++ .../common/modules/ixgbe/ixgbe_e610.h | 210 + .../common/modules/ixgbe/ixgbe_ethtool.c | 6144 ++++++ .../common/modules/ixgbe/ixgbe_fcoe.c | 1059 + .../common/modules/ixgbe/ixgbe_fcoe.h | 72 + .../common/modules/ixgbe/ixgbe_fw_update.c | 945 + .../common/modules/ixgbe/ixgbe_fw_update.h | 18 + .../common/modules/ixgbe/ixgbe_lib.c | 1407 ++ .../common/modules/ixgbe/ixgbe_main.c | 15931 ++++++++++++++++ .../common/modules/ixgbe/ixgbe_mbx.c | 1181 ++ .../common/modules/ixgbe/ixgbe_mbx.h | 191 + .../common/modules/ixgbe/ixgbe_model.h | 99 + .../common/modules/ixgbe/ixgbe_osdep.h | 188 + .../common/modules/ixgbe/ixgbe_osdep2.h | 50 + .../common/modules/ixgbe/ixgbe_param.c | 1271 ++ .../common/modules/ixgbe/ixgbe_phy.c | 2662 +++ .../common/modules/ixgbe/ixgbe_phy.h | 189 + .../common/modules/ixgbe/ixgbe_procfs.c | 917 + .../common/modules/ixgbe/ixgbe_ptp.c | 1644 ++ .../common/modules/ixgbe/ixgbe_ptp_e600.c | 1308 ++ .../common/modules/ixgbe/ixgbe_ptp_e600.h | 20 + .../common/modules/ixgbe/ixgbe_sriov.c | 2238 +++ .../common/modules/ixgbe/ixgbe_sriov.h | 76 + .../common/modules/ixgbe/ixgbe_sysfs.c | 293 + .../common/modules/ixgbe/ixgbe_txrx_common.h | 76 + .../common/modules/ixgbe/ixgbe_type.h | 4428 +++++ .../common/modules/ixgbe/ixgbe_type_e610.h | 2591 +++ .../common/modules/ixgbe/ixgbe_x540.c | 1032 + .../common/modules/ixgbe/ixgbe_x540.h | 36 + .../common/modules/ixgbe/ixgbe_x550.c | 4573 +++++ .../common/modules/ixgbe/ixgbe_x550.h | 89 + .../common/modules/ixgbe/ixgbe_xsk.c | 1097 ++ .../common/modules/ixgbe/kcompat-generator.sh | 715 + .../common/modules/ixgbe/kcompat-lib.sh | 490 + .../common/modules/ixgbe/kcompat.c | 3003 +++ .../common/modules/ixgbe/kcompat.h | 6932 +++++++ .../common/modules/ixgbe/kcompat_cleanup.h | 289 + .../common/modules/ixgbe/kcompat_defs.h | 36 + .../common/modules/ixgbe/kcompat_gcc.h | 111 + .../common/modules/ixgbe/kcompat_impl.h | 3638 ++++ .../common/modules/ixgbe/kcompat_kthread.h | 48 + .../common/modules/ixgbe/kcompat_overflow.h | 493 + .../common/modules/ixgbe/kcompat_packing.c | 476 + .../common/modules/ixgbe/kcompat_packing.h | 466 + .../common/modules/ixgbe/kcompat_pldmfw.c | 1134 ++ .../common/modules/ixgbe/kcompat_pldmfw.h | 178 + .../common/modules/ixgbe/kcompat_rhel_defs.h | 138 + .../common/modules/ixgbe/kcompat_sles_defs.h | 159 + .../common/modules/ixgbe/kcompat_std_defs.h | 220 + .../modules/ixgbe/kcompat_ubuntu_defs.h | 34 + .../common/modules/ixgbe/kcompat_xarray.c | 2406 +++ .../common/modules/ixgbe/kcompat_xarray.h | 1912 ++ .../plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c | 19 + .../plat_sysfs/dev_cfg/include/dfd_cfg_info.h | 3 +- .../common/modules/pmbus.h | 24 + .../device_driver/sysled_device_driver.c | 25 + .../s3ip_sysfs/switch_driver/cfg/dfd_cfg.c | 3 + .../switch_driver/cfg/dfd_cfg_info.c | 85 +- .../switch_driver/include/dfd_cfg_info.h | 13 + .../switch_driver/include/dfd_sysfs_common.h | 2 + .../switch_driver/include/wb_module.h | 1 + .../s3ip_sysfs/switch_driver/switch_driver.c | 32 + .../s3ip_sysfs/switch_driver/wb_fpga_driver.c | 1 - .../sysfs_driver/include/sysled_sysfs.h | 2 + .../s3ip_sysfs/sysfs_driver/sysled_sysfs.c | 36 + .../common/modules/wb_indirect_dev.c | 1241 +- .../common/modules/wb_indirect_dev.h | 28 +- .../common/modules/wb_logic_dev_common.c | 2570 +++ .../common/modules/wb_mac_bsc.c | 347 +- .../common/modules/wb_mdio_dev.c | 600 + .../common/modules/wb_mdio_dev.h | 97 + .../common/modules/wb_rc32312.c | 895 + .../common/modules/wb_spi_master.c | 111 + .../common/modules/wb_spi_ocores.c | 33 +- .../common/modules/wb_spi_ocores.h | 1 + .../common/modules/wb_switch_dev.c | 269 + .../common/modules/wb_switch_dev.h | 22 + .../common/modules/wb_vr_common.c | 286 + .../common/modules/wb_vr_common.h | 27 + .../common/modules/wb_xdpe132g5c_pmbus.c | 62 +- .../common/public/include/wb_bsp_i2c_debug.h | 280 + .../public/include/wb_bsp_kernel_debug.h | 65 + .../common/public/include/wb_kernel_io.h | 80 + .../public/include/wb_logic_dev_common.h | 301 + .../public/include/wb_platform_common.h | 14 + .../common/public/include/wb_spi_master.h | 16 + .../common/script/config-hwsku-cpo.sh | 203 + .../common/script/config-hwsku.sh | 260 + .../common/script/config-ledswitch.sh | 265 + .../common/script/dev_monitor.py | 18 + .../common/script/hal_fanctrl.py | 46 +- .../common/script/mgmt_ledctrl.py | 124 + .../common/script/platform_common.py | 4 + .../common/script/platform_config.py | 4 + .../common/script/platform_driver.py | 68 +- .../common/script/platform_process.py | 15 + .../common/script/platform_sensors_hal.py | 6 +- .../common/script/platform_util.py | 102 +- .../common/script/saphy_script.sh | 136 + .../common/script/sfp_highest_temperatue.py | 2 +- .../common/service/saphy.service | 15 + .../common/sonic_platform/chassis.py | 79 +- .../common/sonic_platform/dcdc.py | 231 +- .../common/sonic_platform/sfp.py | 55 +- .../debian/control | 10 +- ...tform-modules-micas-m2-w6950-128oc.install | 1 + ...form-modules-micas-m2-w6950-128oc.postinst | 10 + ...orm-modules-micas-m2-w6951-64hc-cp.install | 1 + ...rm-modules-micas-m2-w6951-64hc-cp.postinst | 10 + .../debian/rule.mk | 3 +- .../m2-w6940-64oc/modules/driver/Makefile | 2 + .../modules/driver/wb_indirect_dev_device.c | 12 - .../m2-w6950-128oc/Makefile | 34 + .../x86_64_micas_m2_w6950_128oc_r0_config.py | 2271 +++ ..._64_micas_m2_w6950_128oc_r0_port_config.py | 6 + .../x86_64_micas_m2_w6950_128oc_r0_device.py | 1079 ++ .../x86_64_micas_m2_w6950_128oc_r0_monitor.py | 186 + .../m2-w6950-128oc/modules/driver/Makefile | 29 + .../modules/driver/spi-bitbang-txrx.h | 176 + .../modules/driver/wb_cpld_i2c_bus_device.c | 101 + .../modules/driver/wb_cpld_pca954x_device.c | 78 + .../driver/wb_firmware_upgrade_device.c | 816 + .../modules/driver/wb_fpga_i2c_bus_device.c | 1840 ++ .../modules/driver/wb_fpga_pca954x_device.c | 564 + .../modules/driver/wb_i2c_dev_device.c | 340 + .../driver/wb_i2c_mux_pca954x_device.c | 89 + .../modules/driver/wb_pcie_dev_device.c | 126 + .../modules/driver/wb_spi_dev_device.c | 126 + .../modules/driver/wb_spi_gpio.c | 521 + .../modules/driver/wb_spi_gpio_device_cpld.c | 148 + .../modules/driver/wb_switch_dev_device.c | 81 + .../modules/driver/wb_vr_common_dev_device.c | 130 + .../modules/driver/wb_wdt_device.c | 120 + .../s3ip_sysfs_cfg/cfg_file/CPLD.cfg | 412 + .../s3ip_sysfs_cfg/cfg_file/FAN.cfg | 608 + .../s3ip_sysfs_cfg/cfg_file/FPGA.cfg | 131 + .../s3ip_sysfs_cfg/cfg_file/LED.cfg | 209 + .../s3ip_sysfs_cfg/cfg_file/PSU.cfg | 1179 ++ .../s3ip_sysfs_cfg/cfg_file/SENSOR.cfg | 8120 ++++++++ .../s3ip_sysfs_cfg/cfg_file/SFF.cfg | 6527 +++++++ .../s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg | 20 + .../s3ip_sysfs_cfg/file_name/0x414e | 7 + .../m2-w6950-128oc/setup.py | 39 + .../m2-w6951-64hc-cp/Makefile | 29 + ...x86_64_micas_m2_w6951_64hc_cp_r0_config.py | 1511 ++ ...4_micas_m2_w6951_64hc_cp_r0_port_config.py | 74 + ...x86_64_micas_m2_w6951_64hc_cp_r0_device.py | 961 + ...86_64_micas_m2_w6951_64hc_cp_r0_monitor.py | 133 + .../m2-w6951-64hc-cp/modules/driver/Makefile | 25 + .../driver/wb_firmware_upgrade_device.c | 457 + .../modules/driver/wb_fpga_i2c_bus_device.c | 1219 ++ .../modules/driver/wb_fpga_pca954x_device.c | 524 + .../modules/driver/wb_i2c_dev_device.c | 197 + .../driver/wb_i2c_mux_pca954x_device.c | 149 + .../modules/driver/wb_indirect_dev_device.c | 162 + .../modules/driver/wb_pcie_dev_device.c | 139 + .../modules/driver/wb_spi_dev_device.c | 126 + .../modules/driver/wb_spi_ocores_device.c | 115 + .../modules/driver/wb_wdt_device.c | 155 + .../s3ip_sysfs_cfg/cfg_file/CPLD.cfg | 275 + .../s3ip_sysfs_cfg/cfg_file/FAN.cfg | 440 + .../s3ip_sysfs_cfg/cfg_file/FPGA.cfg | 95 + .../s3ip_sysfs_cfg/cfg_file/LED.cfg | 165 + .../s3ip_sysfs_cfg/cfg_file/PSU.cfg | 1088 ++ .../s3ip_sysfs_cfg/cfg_file/SENSOR.cfg | 3769 ++++ .../s3ip_sysfs_cfg/cfg_file/SFF.cfg | 2681 +++ .../s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg | 18 + .../s3ip_sysfs_cfg/file_name/0x414c | 8 + .../m2-w6951-64hc-cp/setup.py | 39 + 315 files changed, 229026 insertions(+), 658 deletions(-) create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/media_settings.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/port_config.ini create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sai.profile create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sap_bcm_81394.cfg create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/th6-m2-w6950-o128-copper-128x800G.config.yml create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/media_settings.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/port_config.ini create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sai.profile create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sap_bcm_81394.cfg create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/th6-m2-w6950-o128-lpo-n-128x800G.config.yml create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/media_settings.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/port_config.ini create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sai.profile create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sap_bcm_81394.cfg create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/th6-m2-w6950-o128-128x800G.config.yml create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/media_settings.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/port_config.ini create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sai.profile create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sap_bcm_81394.cfg create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/th6-m2-w6950-q256-256x400G.config.yml create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/bmc.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/custom_led.bin create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/dev.xml create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/fru.py create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/installer.conf create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/led_proc_init.soc create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/ledswitch_monitor.py create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/monitor.py create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/pcie.yaml create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/platform.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_asic create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_components.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env.conf create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env_fac.conf create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/eeprom.py create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/sfputil.py create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/ssd_util.py create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/pmon_daemon_control.json create mode 100644 device/micas/x86_64-micas_m2-w6950-128oc-r0/system_health_monitoring_config.json create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/port_config.ini create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/sai.profile create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/th6-m2-w6951-64hc-cp-64x1600G.config.yml create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/custom_led.bin create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/dev.xml create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/fru.py create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/installer.conf create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/led_proc_init.soc create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/media_settings.json create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/monitor.py create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pcie.yaml create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform.json create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_asic create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_components.json create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_env.conf create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/sfputil.py create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/ssd_util.py create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pmon_daemon_control.json create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/postinit_cmd_file.soc create mode 100644 device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/system_health_monitoring_config.json create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/ft_ddr_test.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_dram.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_emmc.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_i2c.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_misc.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_mtdflash.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_pci.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_test.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_usb.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/fac_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/ft_ddr_test.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/hw_dram.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_emmc/hw_emmc.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/hw_i2c.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c-dev.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/rtc.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/dram_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/hw_misc.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/hw_mtdflash.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/mtd-abi.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_pci/hw_pci.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_test.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_usb/hw_usb.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-ccgx-ucsi.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-amdpsp.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-baytrail.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-common.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-core.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-master.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-pcidrv.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-platdrv.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-slave.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/math.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/units.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Module.supported create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/auxiliary_compat.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/common.mk create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_nl.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_debugfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ethtool.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_lib.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_main.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_model.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep2.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_param.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_procfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_txrx_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type_e610.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_xsk.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-generator.sh create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-lib.sh create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_cleanup.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_defs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_gcc.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_impl.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_kthread.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_overflow.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_rhel_defs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_sles_defs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_std_defs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_ubuntu_defs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_logic_dev_common.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_rc32312.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_master.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_i2c_debug.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_kernel_debug.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_kernel_io.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_logic_dev_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_platform_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_spi_master.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku-cpo.sh create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku.sh create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/script/config-ledswitch.sh create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/script/mgmt_ledctrl.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/script/saphy_script.sh create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/service/saphy.service create mode 100644 platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.install create mode 100644 platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.postinst create mode 100644 platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.install create mode 100644 platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.postinst create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_config.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/spi-bitbang-txrx.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_i2c_bus_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_i2c_bus_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio_device_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_switch_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_vr_common_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_wdt_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FPGA.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/LED.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/file_name/0x414e create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_config.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_firmware_upgrade_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_i2c_bus_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_mux_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_indirect_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_ocores_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_wdt_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FPGA.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/LED.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/file_name/0x414c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/setup.py diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/default_sku b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/default_sku new file mode 100644 index 0000000000..cca556ccb7 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/default_sku @@ -0,0 +1 @@ +M2-W6950-O128-COPPER l2 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/hwsku.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/hwsku.json new file mode 100644 index 0000000000..276fda2943 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/hwsku.json @@ -0,0 +1,654 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet136": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet144": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet152": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet160": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet168": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet176": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet184": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet192": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet200": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet208": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet216": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet224": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet232": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet240": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet248": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet256": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet264": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet272": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet280": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet288": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet296": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet304": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet312": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet320": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet328": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet336": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet344": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet352": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet360": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet368": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet376": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet384": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet392": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet400": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet408": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet416": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet424": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet432": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet440": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet448": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet456": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet464": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet472": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet480": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet488": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet496": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet504": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet512": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet520": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet528": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet536": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet544": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet552": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet560": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet568": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet576": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet584": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet592": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet600": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet608": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet616": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet624": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet632": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet640": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet648": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet656": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet664": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet672": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet680": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet688": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet696": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet704": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet712": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet720": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet728": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet736": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet744": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet752": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet760": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet768": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet776": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet784": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet792": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet800": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet808": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet816": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet824": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet832": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet840": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet848": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet856": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet864": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet872": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet880": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet888": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet896": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet904": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet912": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet920": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet928": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet936": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet944": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet952": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet960": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet968": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet976": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet984": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet992": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1000": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1008": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1016": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1024": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1025": { + "default_brkout_mode": "1x1G", + "autoneg": "off", + "fec": "none" + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/media_settings.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/media_settings.json new file mode 100644 index 0000000000..b96920ded6 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/media_settings.json @@ -0,0 +1,8196 @@ +{ + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "2": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "3": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "4": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "5": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "6": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "7": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "8": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "9": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "10": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "11": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "12": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "13": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "14": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "15": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "16": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "17": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "18": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "19": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "20": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "21": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "22": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "23": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "24": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "25": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "26": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "27": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "28": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "29": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "30": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "31": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "32": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "33": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "34": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "35": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "36": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "37": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "38": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "39": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "40": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "41": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "42": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "43": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "44": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "45": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "46": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "47": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "48": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "49": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "50": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "51": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "52": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "53": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "54": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "55": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "56": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "57": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "58": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "59": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "60": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "61": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "62": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "63": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "64": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "65": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "66": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "67": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "68": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "69": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "70": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "71": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "72": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "73": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "74": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "75": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "76": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "77": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "78": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "79": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "80": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "81": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "82": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "83": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "84": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "85": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "86": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "87": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "88": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "89": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "90": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "91": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "92": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "93": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "94": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "95": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "96": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "97": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "98": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "99": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "100": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "101": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "102": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "103": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "104": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "105": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "106": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "107": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "108": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "109": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "110": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "111": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xfffffff0", + "lane1": "0xfffffff0", + "lane2": "0xfffffff0", + "lane3": "0xfffffff0", + "lane4": "0xfffffff0", + "lane5": "0xfffffff0", + "lane6": "0xfffffff0", + "lane7": "0xfffffff0" + }, + "main": { + "lane0": "0x00000094", + "lane1": "0x00000094", + "lane2": "0x00000094", + "lane3": "0x00000094", + "lane4": "0x00000094", + "lane5": "0x00000094", + "lane6": "0x00000094", + "lane7": "0x00000094" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "112": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000004", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000090", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "113": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "114": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000004", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffec", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000090", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "115": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000008", + "lane1": "0x00000008", + "lane2": "0x00000008", + "lane3": "0x00000008", + "lane4": "0x00000008", + "lane5": "0x00000008", + "lane6": "0x00000008", + "lane7": "0x00000008" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "116": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "117": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "118": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "119": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "120": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "121": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "122": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe8", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe8", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x0000008c", + "lane1": "0x0000008c", + "lane2": "0x0000008c", + "lane3": "0x0000008c", + "lane4": "0x0000008c", + "lane5": "0x0000008c", + "lane6": "0x0000008c", + "lane7": "0x0000008c" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "123": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "124": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "125": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "126": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "127": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "128": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/port_config.ini b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/port_config.ini new file mode 100644 index 0000000000..6b950df1d2 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/port_config.ini @@ -0,0 +1,131 @@ +# name lanes alias index speed +Ethernet0 265,266,267,268,269,270,271,272 etp1 1 800000 +Ethernet8 297,298,299,300,301,302,303,304 etp2 2 800000 +Ethernet16 305,306,307,308,309,310,311,312 etp3 3 800000 +Ethernet24 313,314,315,316,317,318,319,320 etp4 4 800000 +Ethernet32 377,378,379,380,381,382,383,384 etp5 5 800000 +Ethernet40 369,370,371,372,373,374,375,376 etp6 6 800000 +Ethernet48 361,362,363,364,365,366,367,368 etp7 7 800000 +Ethernet56 329,330,331,332,333,334,335,336 etp8 8 800000 +Ethernet64 505,506,507,508,509,510,511,512 etp9 9 800000 +Ethernet72 497,498,499,500,501,502,503,504 etp10 10 800000 +Ethernet80 489,490,491,492,493,494,495,496 etp11 11 800000 +Ethernet88 457,458,459,460,461,462,463,464 etp12 12 800000 +Ethernet96 449,450,451,452,453,454,455,456 etp13 13 800000 +Ethernet104 465,466,467,468,469,470,471,472 etp14 14 800000 +Ethernet112 481,482,483,484,485,486,487,488 etp15 15 800000 +Ethernet120 473,474,475,476,477,478,479,480 etp16 16 800000 +Ethernet128 537,538,539,540,541,542,543,544 etp17 17 800000 +Ethernet136 545,546,547,548,549,550,551,552 etp18 18 800000 +Ethernet144 529,530,531,532,533,534,535,536 etp19 19 800000 +Ethernet152 513,514,515,516,517,518,519,520 etp20 20 800000 +Ethernet160 521,522,523,524,525,526,527,528 etp21 21 800000 +Ethernet168 553,554,555,556,557,558,559,560 etp22 22 800000 +Ethernet176 561,562,563,564,565,566,567,568 etp23 23 800000 +Ethernet184 569,570,571,572,573,574,575,576 etp24 24 800000 +Ethernet192 649,650,651,652,653,654,655,656 etp25 25 800000 +Ethernet200 681,682,683,684,685,686,687,688 etp26 26 800000 +Ethernet208 689,690,691,692,693,694,695,696 etp27 27 800000 +Ethernet216 697,698,699,700,701,702,703,704 etp28 28 800000 +Ethernet224 761,762,763,764,765,766,767,768 etp29 29 800000 +Ethernet232 753,754,755,756,757,758,759,760 etp30 30 800000 +Ethernet240 713,714,715,716,717,718,719,720 etp31 31 800000 +Ethernet248 745,746,747,748,749,750,751,752 etp32 32 800000 +Ethernet256 33,34,35,36,37,38,39,40 etp33 33 800000 +Ethernet264 1,2,3,4,5,6,7,8 etp34 34 800000 +Ethernet272 41,42,43,44,45,46,47,48 etp35 35 800000 +Ethernet280 57,58,59,60,61,62,63,64 etp36 36 800000 +Ethernet288 121,122,123,124,125,126,127,128 etp37 37 800000 +Ethernet296 105,106,107,108,109,110,111,112 etp38 38 800000 +Ethernet304 65,66,67,68,69,70,71,72 etp39 39 800000 +Ethernet312 97,98,99,100,101,102,103,104 etp40 40 800000 +Ethernet320 153,154,155,156,157,158,159,160 etp41 41 800000 +Ethernet328 145,146,147,148,149,150,151,152 etp42 42 800000 +Ethernet336 321,322,323,324,325,326,327,328 etp43 43 800000 +Ethernet344 353,354,355,356,357,358,359,360 etp44 44 800000 +Ethernet352 409,410,411,412,413,414,415,416 etp45 45 800000 +Ethernet360 401,402,403,404,405,406,407,408 etp46 46 800000 +Ethernet368 393,394,395,396,397,398,399,400 etp47 47 800000 +Ethernet376 433,434,435,436,437,438,439,440 etp48 48 800000 +Ethernet384 585,586,587,588,589,590,591,592 etp49 49 800000 +Ethernet392 625,626,627,628,629,630,631,632 etp50 50 800000 +Ethernet400 601,602,603,604,605,606,607,608 etp51 51 800000 +Ethernet408 593,594,595,596,597,598,599,600 etp52 52 800000 +Ethernet416 641,642,643,644,645,646,647,648 etp53 53 800000 +Ethernet424 673,674,675,676,677,678,679,680 etp54 54 800000 +Ethernet432 857,858,859,860,861,862,863,864 etp55 55 800000 +Ethernet440 849,850,851,852,853,854,855,856 etp56 56 800000 +Ethernet448 897,898,899,900,901,902,903,904 etp57 57 800000 +Ethernet456 929,930,931,932,933,934,935,936 etp58 58 800000 +Ethernet464 953,954,955,956,957,958,959,960 etp59 59 800000 +Ethernet472 937,938,939,940,941,942,943,944 etp60 60 800000 +Ethernet480 1001,1002,1003,1004,1005,1006,1007,1008 etp61 61 800000 +Ethernet488 1017,1018,1019,1020,1021,1022,1023,1024 etp62 62 800000 +Ethernet496 993,994,995,996,997,998,999,1000 etp63 63 800000 +Ethernet504 961,962,963,964,965,966,967,968 etp64 64 800000 +Ethernet512 17,18,19,20,21,22,23,24 etp65 65 800000 +Ethernet520 25,26,27,28,29,30,31,32 etp66 66 800000 +Ethernet528 49,50,51,52,53,54,55,56 etp67 67 800000 +Ethernet536 9,10,11,12,13,14,15,16 etp68 68 800000 +Ethernet544 73,74,75,76,77,78,79,80 etp69 69 800000 +Ethernet552 113,114,115,116,117,118,119,120 etp70 70 800000 +Ethernet560 89,90,91,92,93,94,95,96 etp71 71 800000 +Ethernet568 81,82,83,84,85,86,87,88 etp72 72 800000 +Ethernet576 129,130,131,132,133,134,135,136 etp73 73 800000 +Ethernet584 161,162,163,164,165,166,167,168 etp74 74 800000 +Ethernet592 345,346,347,348,349,350,351,352 etp75 75 800000 +Ethernet600 337,338,339,340,341,342,343,344 etp76 76 800000 +Ethernet608 385,386,387,388,389,390,391,392 etp77 77 800000 +Ethernet616 417,418,419,420,421,422,423,424 etp78 78 800000 +Ethernet624 441,442,443,444,445,446,447,448 etp79 79 800000 +Ethernet632 425,426,427,428,429,430,431,432 etp80 80 800000 +Ethernet640 633,634,635,636,637,638,639,640 etp81 81 800000 +Ethernet648 617,618,619,620,621,622,623,624 etp82 82 800000 +Ethernet656 577,578,579,580,581,582,583,584 etp83 83 800000 +Ethernet664 609,610,611,612,613,614,615,616 etp84 84 800000 +Ethernet672 665,666,667,668,669,670,671,672 etp85 85 800000 +Ethernet680 657,658,659,660,661,662,663,664 etp86 86 800000 +Ethernet688 833,834,835,836,837,838,839,840 etp87 87 800000 +Ethernet696 865,866,867,868,869,870,871,872 etp88 88 800000 +Ethernet704 921,922,923,924,925,926,927,928 etp89 89 800000 +Ethernet712 913,914,915,916,917,918,919,920 etp90 90 800000 +Ethernet720 905,906,907,908,909,910,911,912 etp91 91 800000 +Ethernet728 945,946,947,948,949,950,951,952 etp92 92 800000 +Ethernet736 1009,1010,1011,1012,1013,1014,1015,1016 etp93 93 800000 +Ethernet744 969,970,971,972,973,974,975,976 etp94 94 800000 +Ethernet752 977,978,979,980,981,982,983,984 etp95 95 800000 +Ethernet760 985,986,987,988,989,990,991,992 etp96 96 800000 +Ethernet768 209,210,211,212,213,214,215,216 etp97 97 800000 +Ethernet776 193,194,195,196,197,198,199,200 etp98 98 800000 +Ethernet784 225,226,227,228,229,230,231,232 etp99 99 800000 +Ethernet792 217,218,219,220,221,222,223,224 etp100 100 800000 +Ethernet800 281,282,283,284,285,286,287,288 etp101 101 800000 +Ethernet808 289,290,291,292,293,294,295,296 etp102 102 800000 +Ethernet816 257,258,259,260,261,262,263,264 etp103 103 800000 +Ethernet824 273,274,275,276,277,278,279,280 etp104 104 800000 +Ethernet832 201,202,203,204,205,206,207,208 etp105 105 800000 +Ethernet840 233,234,235,236,237,238,239,240 etp106 106 800000 +Ethernet848 241,242,243,244,245,246,247,248 etp107 107 800000 +Ethernet856 249,250,251,252,253,254,255,256 etp108 108 800000 +Ethernet864 185,186,187,188,189,190,191,192 etp109 109 800000 +Ethernet872 177,178,179,180,181,182,183,184 etp110 110 800000 +Ethernet880 169,170,171,172,173,174,175,176 etp111 111 800000 +Ethernet888 137,138,139,140,141,142,143,144 etp112 112 800000 +Ethernet896 841,842,843,844,845,846,847,848 etp113 113 800000 +Ethernet904 873,874,875,876,877,878,879,880 etp114 114 800000 +Ethernet912 881,882,883,884,885,886,887,888 etp115 115 800000 +Ethernet920 889,890,891,892,893,894,895,896 etp116 116 800000 +Ethernet928 825,826,827,828,829,830,831,832 etp117 117 800000 +Ethernet936 817,818,819,820,821,822,823,824 etp118 118 800000 +Ethernet944 809,810,811,812,813,814,815,816 etp119 119 800000 +Ethernet952 777,778,779,780,781,782,783,784 etp120 120 800000 +Ethernet960 721,722,723,724,725,726,727,728 etp121 121 800000 +Ethernet968 705,706,707,708,709,710,711,712 etp122 122 800000 +Ethernet976 737,738,739,740,741,742,743,744 etp123 123 800000 +Ethernet984 729,730,731,732,733,734,735,736 etp124 124 800000 +Ethernet992 793,794,795,796,797,798,799,800 etp125 125 800000 +Ethernet1000 801,802,803,804,805,806,807,808 etp126 126 800000 +Ethernet1008 785,786,787,788,789,790,791,792 etp127 127 800000 +Ethernet1016 769,770,771,772,773,774,775,776 etp128 128 800000 +Ethernet1024 1026,1027,1028,1029 etp129 129 100000 +Ethernet1025 0 etp130 130 1000 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sai.profile b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sai.profile new file mode 100644 index 0000000000..96e0c9c9dc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th6-m2-w6950-o128-copper-128x800G.config.yml diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sap_bcm_81394.cfg b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sap_bcm_81394.cfg new file mode 100644 index 0000000000..c8b29b322c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/sap_bcm_81394.cfg @@ -0,0 +1,246 @@ +# Configuration file version number. +# The current sap_bcm_81394.c does not read this field; it is compatibility/identification information. +# Modifying it will not affect the initialization process of the 81394 driver. +version=1 + +# ==================== +# Global Initialization Parameters +# ==================== + +# Number of slots on the board. +# sap_aperta_config_init() first reads this value into the global g_slot_num, +# then sap_bcm_platform_init() calls sap_slot_init() for 0 to g_slot_num-1. +# Missing this field will cause configuration initialization to fail directly. +plp_slot_num=1 + +# MDIO access type. The ':1' in the key is not a PHY address, but the mdio_id. +# The code first reads plp_phy_mdio_id:0x30=1, then looks up plp_mdio_accs_type:1. +# The value comes from sap_mdio_type_e: +# 0 = MAC +# 1 = SYSFS +# 2 = SYSFS_CUST +# The current value 2 indicates using the custom sysfs MDIO access path. +plp_mdio_accs_type:1=2 + +# Firmware loading method, saved to the global g_fw_load_method. +# The definitions in the 81394 driver are: +# 0 = Do not load +# 1 = Unicast load +# 2 = Broadcast load +# 3 = EEPROM load +# 4 = upgrade path +# 5 = skip +# 6 = full process +# The current value 1 means downloading firmware to each PHY via unicast. +plp_fw_load_method=1 + +# Enable or disable I2C slave. +# The code reads this into g_i2c_slave_en, but in the current main flow of the 81394, +# the corresponding register write logic is completely commented out. +# Therefore, this value is currently a "parsed but not effective by default" field. +plp_i2c_slave_en=0 + +# AVS I2C response address. +# This is also read into g_avs_i2c_resp_addr and used by sap_bcm_avs_init() to assemble register values. +# However, AVS initialization is not actually enabled in the current boot path, so this is just a reserved configuration. +avs_i2c_resp_addr=0x35 + +# Default enable/disable link training for the port's system side. +# If there is no per-port configuration for init_linktrain_sys, each port inherits this global value. +# In sap_aperta_post_port_init(), it calls sap_bcm_linktraining_set(..., true) only if the value is 1. +# 0 means do not automatically enable LT. +plp_port_linktrain_sys=0 + +# Default enable/disable link training for the port's line side. +# The semantics are the same as plp_port_linktrain_sys, applying to the line side. +plp_port_linktrain_line=0 + +# ==================== +# Profile 1 VCO Presets +# ==================== + +# VCO selection for Profile 1, octal 0, system side. +# The 81394 code forcibly reads this and saves it to phy_info->vco_octal_0_sys. +# Confirmed from public headers: +# 0 = bcmplpVco51G +# 1 = bcmplpVco53G +# The current value 1 means 53G VCO. +# Note: In this version of the 81394 implementation, this value is read but not used further in mode_config_set. +# It seems more like a field retained to share the configuration format with other chips in the family. +plp_profile_1_init_vco_octal_0_sys=1 + +# VCO selection for Profile 1, octal 0, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_0_line=1 + +# VCO selection for Profile 1, octal 1, system side. +# The current board type uses only one PHY at address 0x30 and the profile uses lanes=0,1, +# but the code still requires the VCO for octal 1 to be configured, otherwise configuration parsing fails. +plp_profile_1_init_vco_octal_1_sys=1 + +# VCO selection for Profile 1, octal 1, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_1_line=1 + +# ==================== +# Profile 1: 100G, split=1, Single port with 4 lanes +# Key format: plp_profile__speed__split_.: +# This is changed to a single 100G port, hence split_num=1, port_id=0. +# +# In the 81394 code, split_num is not hardcoded, but calculated by: +# phy_info->lane_num / port_info->lanes +# Therefore, to target split_1.0, the init_lanes below needs to provide 4 lane entries, +# and init_ports_lane_num must be configured as 4, indicating a 4-lane aggregated port. +# ==================== + +# FEC mode for the line side. +# For the 100G 4x25G scenario, the semantics from the original file are retained, where 3 = RSFEC. +# This still uses the 25.78125G/lane NRZ path, not 2x50G PAM4. +plp_profile_1_speed_100000_split_1.0:fec_line=3 + +# FEC mode for the system side. +# Consistent with the line side, configured as 3 = RSFEC. +plp_profile_1_speed_100000_split_1.0:fec_sys=3 + +# Interface type for the line side. +# In bcm_pm_interface_t, 7 = bcm_pm_InterfaceKR4. +# This is changed from the single-lane KR to 4-lane KR4, matching the 100G 4-lane port form factor. +plp_profile_1_speed_100000_split_1.0:iftype_line=7 + +# Interface type for the system side. +# Also changed to 7 = KR4, maintaining the lane count and interface width consistency between system/line sides. +plp_profile_1_speed_100000_split_1.0:iftype_sys=7 + +# Line side lane bitmask. +# 0xF = 0000 1111b, indicating selection of 4 consecutive lanes. +# With speed=100000, the code calculates the per-lane speed as 25.78125G. +plp_profile_1_speed_100000_split_1.0:lanemap_line=0xF + +# System side lane bitmask. +# Same as the line side, indicating a 4-lane passthrough port, not a gearbox/reverse-gearbox. +plp_profile_1_speed_100000_split_1.0:lanemap_sys=0xF + +# Force NR (No Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_sys=0x0 + +# Force NR (No Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_line=0x0 + +# Force ER (Eye Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_sys=0x0 + +# Force ER (Eye Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_line=0x0 + + +# ==================== +# PHY List +# ==================== + +# List of PHY addresses to initialize. +# sap_aperta_config_init() generates g_bcm_phy_infos based on this array. +# Currently, there is only one PHY at address 0x30. +plp_phy_addrs=0x30 + +# ==================== +# PHY 0x30 Base Attributes +# PHY address resolution method: +# bus_id = (phy_addr & 0x7c00)>>10; +# mdio_index = (phy_addr & 0x3e0)>>5; +# phy_addr = phy_addr & 0x1f; +# return dfd_utest_mdiodev_rd(mdio_index+bus_id, phy_addr, reg_addr, data); +# ==================== + +# The unit to which the PHY is bound. +# sap_slot_init() filters by unit and card_id to determine if this PHY should be initialized in the current round. +plp_phy_unit_id:0x30=0 + +# The card/slot number the PHY belongs to. +# The PHY is initialized only when this matches the outer slot_id. +plp_phy_card_id:0x30=0 + +# The mdio_id used by this PHY. +# The code will then use this mdio_id to look up plp_mdio_accs_type:. +plp_phy_mdio_id:0x30=1 + +# PHY chip name. +# For this version of the 81394 code, this is a compatibility field, as the chip_name is hardcoded to "aperta" in the source. +# Modifying it will not change the chip name used by the driver. +plp_phy_chip_name:0x30=aperta + +# MACsec option. +# The current 81394 file only reads and saves this to phy_info->macsec_option, with no subsequent use observed. +# Therefore, this is more of a reserved field. +plp_phy_macsec_option:0x30=0x0 + +# PTP option. +# Similar to macsec_option, currently only parsed and saved, not consumed in the main 81394 flow. +plp_phy_ptp_option:0x30=0x0 + +# The initialization profile ID used by this PHY. +# The '1' in all subsequent plp_profile_1_* key names is determined by this value. +plp_phy_init_profile_id:0x30=1 + +# The lane list for this PHY under Profile 1. +# This is changed to 0,1,2,3. This does not mean 4 independent logical ports, +# but rather to make phy_info->lane_num = 4, causing the code to calculate split_num = 1. +# The number of logical ports actually created is still determined by the next line, init_ports. +plp_profile_1_init_lanes:0x30=0-3 + +# The list of logical port numbers presented externally by this PHY under Profile 1. +# Changed to create only one logical port, port 1, to carry the 1x100G module. +plp_profile_1_init_ports:0x30=1 + +# The number of lanes occupied by each logical port under Profile 1. +# Changed to a single port occupying 4 lanes. +plp_profile_1_init_ports_lane_num:0x30=4 + +# The initial speed of each logical port under Profile 1. +# Changed to 100000 Mbps for a single port, i.e., 100G. +plp_profile_1_init_speed_mode:0x30=100000 + +# ==================== +# PHY 0x30 Global Lane Swap and Polarity Configuration +# These keys apply to the entire PHY, not a single port. +# ==================== + +# System side TX lane mapping. +# This value is parsed as 8 nibbles, lane by lane. +# lane_map_tx[lane_index] = GET_LANE_SWAP_OCTAL(value, lane_index). +# 0x76543210 represents logical 0->0, 1->1, 2->2... 7->7, which is an identity mapping. +plp_phy_tx_lane_map_sys:0x30=0x76543210 + +# System side RX lane mapping. +# Currently also an identity mapping. +plp_phy_rx_lane_map_sys:0x30=0x76543210 + +# Line side TX lane mapping. +# 0x76543120 indicates a lane swap on the line side, no longer a direct passthrough. +# The code calls bcm_plp_rxtx_laneswap_set() in sap_aperta_phy_init() to apply this. +plp_phy_tx_lane_map_line:0x30=0x76542301 + +# Line side RX lane mapping. +# Currently the same as TX, indicating that RX/TX both follow the same line-side swapping rules. +plp_phy_rx_lane_map_line:0x30=0x76542301 + +# Line side TX polarity flip bitmap. +# In sap_aperta_phy_init(), the current polarity is read, XORed with this value, and then written back. +# Therefore, a bit=1 means flip the polarity for the corresponding lane; 0 means leave it unchanged. +# The current 0x0 means no polarity flip on the line side TX. +plp_tx_polarity_flip_line:0x30=0x0 + +# Line side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the line side RX. +plp_rx_polarity_flip_line:0x30=0xF + +# System side TX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side TX. +plp_tx_polarity_flip_sys:0x30=0x0 + +# System side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side RX. +plp_rx_polarity_flip_sys:0x30=0x0 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/th6-m2-w6950-o128-copper-128x800G.config.yml b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/th6-m2-w6950-o128-copper-128x800G.config.yml new file mode 100644 index 0000000000..7a999355d8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-COPPER/th6-m2-w6950-o128-copper-128x800G.config.yml @@ -0,0 +1,2195 @@ +--- +device: + 0: + DEVICE_CONFIG: + AUTOLOAD_BOARD_SETTINGS: 0 +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12360745 + RX_LANE_MAP: 0x34726150 + TX_POLARITY_FLIP: 0x57 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327140 + RX_LANE_MAP: 0x60317425 + TX_POLARITY_FLIP: 0x99 + RX_POLARITY_FLIP: 0x59 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23145670 + RX_LANE_MAP: 0x57462103 + TX_POLARITY_FLIP: 0x6e + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45726013 + RX_LANE_MAP: 0x12360475 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0x87 + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17204653 + RX_LANE_MAP: 0x54036127 + TX_POLARITY_FLIP: 0x3f + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x14027653 + RX_LANE_MAP: 0x54217036 + TX_POLARITY_FLIP: 0x45 + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26351407 + RX_LANE_MAP: 0x52407163 + TX_POLARITY_FLIP: 0x43 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670321 + RX_LANE_MAP: 0x53274610 + TX_POLARITY_FLIP: 0xad + RX_POLARITY_FLIP: 0xd8 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21705463 + RX_LANE_MAP: 0x46327105 + TX_POLARITY_FLIP: 0x95 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12057463 + RX_LANE_MAP: 0x51740236 + TX_POLARITY_FLIP: 0xc8 + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67105243 + RX_LANE_MAP: 0x40236715 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0x05 + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23164507 + RX_LANE_MAP: 0x45712063 + TX_POLARITY_FLIP: 0xd7 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46570213 + RX_LANE_MAP: 0x71546032 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0x51 + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17453206 + RX_LANE_MAP: 0x61257430 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x64 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327041 + RX_LANE_MAP: 0x50361427 + TX_POLARITY_FLIP: 0xe2 + RX_POLARITY_FLIP: 0xf8 + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x57624301 + TX_POLARITY_FLIP: 0x0d + RX_POLARITY_FLIP: 0xa0 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01374526 + RX_LANE_MAP: 0x64751032 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13024675 + RX_LANE_MAP: 0x61304275 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xa1 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x16452307 + RX_LANE_MAP: 0x50346721 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0xb8 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32604571 + RX_LANE_MAP: 0x67205314 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46120573 + RX_LANE_MAP: 0x13526407 + TX_POLARITY_FLIP: 0x2e + RX_POLARITY_FLIP: 0xf6 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x30412657 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x04 + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13207465 + RX_LANE_MAP: 0x20316475 + TX_POLARITY_FLIP: 0x01 + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x61305274 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23107465 + RX_LANE_MAP: 0x32107654 + TX_POLARITY_FLIP: 0x62 + RX_POLARITY_FLIP: 0x99 + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0xf7 + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x62307145 + TX_POLARITY_FLIP: 0x9d + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x31064752 + RX_LANE_MAP: 0x02135764 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xca + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12357064 + RX_LANE_MAP: 0x03216457 + TX_POLARITY_FLIP: 0x81 + RX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106745 + RX_LANE_MAP: 0x61034275 + TX_POLARITY_FLIP: 0x11 + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32014756 + RX_LANE_MAP: 0x13024576 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02376154 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xd5 + RX_POLARITY_FLIP: 0xef + ? + PC_PM_ID: 33 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x02637154 + TX_POLARITY_FLIP: 0xe7 + RX_POLARITY_FLIP: 0x20 + ? + PC_PM_ID: 34 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0x01 + ? + PC_PM_ID: 35 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02134765 + RX_LANE_MAP: 0x13026745 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0x82 + ? + PC_PM_ID: 36 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23016745 + RX_LANE_MAP: 0x30162745 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xc9 + ? + PC_PM_ID: 37 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30412675 + RX_LANE_MAP: 0x32051674 + TX_POLARITY_FLIP: 0xa7 + RX_POLARITY_FLIP: 0x1b + ? + PC_PM_ID: 38 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x91 + ? + PC_PM_ID: 39 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x01534267 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x29 + ? + PC_PM_ID: 40 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 41 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x46357201 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x3a + ? + PC_PM_ID: 42 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x10325746 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0xee + ? + PC_PM_ID: 43 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65073421 + RX_LANE_MAP: 0x53026714 + TX_POLARITY_FLIP: 0x7e + RX_POLARITY_FLIP: 0xc5 + ? + PC_PM_ID: 44 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21057463 + RX_LANE_MAP: 0x47513260 + TX_POLARITY_FLIP: 0x65 + RX_POLARITY_FLIP: 0x07 + ? + PC_PM_ID: 45 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47061235 + RX_LANE_MAP: 0x41276530 + TX_POLARITY_FLIP: 0x34 + RX_POLARITY_FLIP: 0xf1 + ? + PC_PM_ID: 46 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x01437265 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 47 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x13607254 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x44 + ? + PC_PM_ID: 48 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x13025476 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 49 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70152643 + RX_LANE_MAP: 0x76512043 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 50 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x04635271 + RX_LANE_MAP: 0x67235014 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x25 + ? + PC_PM_ID: 51 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x76540213 + RX_LANE_MAP: 0x51376240 + TX_POLARITY_FLIP: 0xf1 + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 52 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12375460 + RX_LANE_MAP: 0x54261037 + TX_POLARITY_FLIP: 0xe1 + RX_POLARITY_FLIP: 0x0f + ? + PC_PM_ID: 53 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64301572 + RX_LANE_MAP: 0x63107425 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 54 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45213670 + RX_LANE_MAP: 0x41062537 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 55 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25461073 + RX_LANE_MAP: 0x73215640 + TX_POLARITY_FLIP: 0xec + RX_POLARITY_FLIP: 0x0e + ? + PC_PM_ID: 56 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30264571 + RX_LANE_MAP: 0x67452031 + TX_POLARITY_FLIP: 0x38 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 57 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 58 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 59 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x23017654 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x96 + ? + PC_PM_ID: 60 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x33 + ? + PC_PM_ID: 61 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x02341675 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0xc7 + ? + PC_PM_ID: 62 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x23106754 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x26 + ? + PC_PM_ID: 63 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36170254 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x73 + ? + PC_PM_ID: 64 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xd0 + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 65 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0x7a + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 66 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x13 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 67 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x32106745 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x96 + ? + PC_PM_ID: 68 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0xa3 + RX_POLARITY_FLIP: 0xcc + ? + PC_PM_ID: 69 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x20436157 + TX_POLARITY_FLIP: 0xd3 + RX_POLARITY_FLIP: 0x34 + ? + PC_PM_ID: 70 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x32017645 + TX_POLARITY_FLIP: 0x63 + RX_POLARITY_FLIP: 0xe6 + ? + PC_PM_ID: 71 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63712045 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x4c + ? + PC_PM_ID: 72 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x23 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 73 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13762540 + RX_LANE_MAP: 0x51764320 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 74 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x62135470 + RX_LANE_MAP: 0x64025317 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xea + ? + PC_PM_ID: 75 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54761302 + RX_LANE_MAP: 0x50326741 + TX_POLARITY_FLIP: 0x0b + RX_POLARITY_FLIP: 0x7e + ? + PC_PM_ID: 76 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x34075261 + RX_LANE_MAP: 0x57021634 + TX_POLARITY_FLIP: 0x5a + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 77 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75201463 + RX_LANE_MAP: 0x70126435 + TX_POLARITY_FLIP: 0xe4 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 78 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67013542 + RX_LANE_MAP: 0x26034517 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 79 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46257310 + RX_LANE_MAP: 0x70265143 + TX_POLARITY_FLIP: 0x4c + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 80 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21354670 + RX_LANE_MAP: 0x45673120 + TX_POLARITY_FLIP: 0xab + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 81 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41237506 + TX_POLARITY_FLIP: 0x80 + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 82 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x01237564 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0xdd + ? + PC_PM_ID: 83 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x24173560 + RX_LANE_MAP: 0x62015734 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 84 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03247561 + RX_LANE_MAP: 0x51476032 + TX_POLARITY_FLIP: 0xf6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 85 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06473512 + RX_LANE_MAP: 0x40256731 + TX_POLARITY_FLIP: 0x3e + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 86 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x10342756 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0xc9 + ? + PC_PM_ID: 87 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x31062745 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 88 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x31204567 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0xcd + ? + PC_PM_ID: 89 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64751302 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0xfb + ? + PC_PM_ID: 90 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0x02 + ? + PC_PM_ID: 91 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65471302 + RX_LANE_MAP: 0x54762031 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0xbe + ? + PC_PM_ID: 92 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670123 + RX_LANE_MAP: 0x54726103 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0x6c + ? + PC_PM_ID: 93 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75264130 + RX_LANE_MAP: 0x47615023 + TX_POLARITY_FLIP: 0x25 + RX_POLARITY_FLIP: 0x27 + ? + PC_PM_ID: 94 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x91 + ? + PC_PM_ID: 95 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x10352476 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x16 + ? + PC_PM_ID: 96 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x42 + ? + PC_PM_ID: 97 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65741023 + RX_LANE_MAP: 0x45670123 + TX_POLARITY_FLIP: 0x76 + RX_POLARITY_FLIP: 0x66 + ? + PC_PM_ID: 98 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0x84 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 99 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x45713062 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 100 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52470631 + RX_LANE_MAP: 0x46753120 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xac + ? + PC_PM_ID: 101 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64703512 + RX_LANE_MAP: 0x75461230 + TX_POLARITY_FLIP: 0xbd + RX_POLARITY_FLIP: 0x3b + ? + PC_PM_ID: 102 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45671032 + RX_LANE_MAP: 0x57243016 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0x9c + ? + PC_PM_ID: 103 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56470132 + RX_LANE_MAP: 0x67542031 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x8c + ? + PC_PM_ID: 104 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54613702 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0xa8 + RX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 105 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36054721 + RX_LANE_MAP: 0x75643210 + TX_POLARITY_FLIP: 0xb7 + RX_POLARITY_FLIP: 0xb9 + ? + PC_PM_ID: 106 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75642031 + RX_LANE_MAP: 0x57240316 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x7a + ? + PC_PM_ID: 107 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45160723 + RX_LANE_MAP: 0x51376420 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x43 + ? + PC_PM_ID: 108 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65104273 + RX_LANE_MAP: 0x64325017 + TX_POLARITY_FLIP: 0xc9 + RX_POLARITY_FLIP: 0x1b + ? + PC_PM_ID: 109 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75320641 + RX_LANE_MAP: 0x62501437 + TX_POLARITY_FLIP: 0xd1 + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 110 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x75621403 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xdf + ? + PC_PM_ID: 111 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65742013 + RX_LANE_MAP: 0x57461302 + TX_POLARITY_FLIP: 0xbf + RX_POLARITY_FLIP: 0xe3 + ? + PC_PM_ID: 112 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x47250316 + TX_POLARITY_FLIP: 0xf9 + RX_POLARITY_FLIP: 0xee + ? + PC_PM_ID: 113 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74305162 + RX_LANE_MAP: 0x75014236 + TX_POLARITY_FLIP: 0x8e + RX_POLARITY_FLIP: 0x01 + ? + PC_PM_ID: 114 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03147562 + RX_LANE_MAP: 0x74513602 + TX_POLARITY_FLIP: 0x0e + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 115 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x42305761 + RX_LANE_MAP: 0x63214705 + TX_POLARITY_FLIP: 0x08 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 116 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17254603 + RX_LANE_MAP: 0x71456320 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 117 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x57461302 + RX_LANE_MAP: 0x72506431 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 118 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45170632 + RX_LANE_MAP: 0x60247531 + TX_POLARITY_FLIP: 0x55 + RX_POLARITY_FLIP: 0xde + ? + PC_PM_ID: 119 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x40127653 + RX_LANE_MAP: 0x16325407 + TX_POLARITY_FLIP: 0x9f + RX_POLARITY_FLIP: 0x15 + ? + PC_PM_ID: 120 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41035267 + TX_POLARITY_FLIP: 0x97 + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 121 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124507 + RX_LANE_MAP: 0x30716254 + TX_POLARITY_FLIP: 0xa2 + RX_POLARITY_FLIP: 0x83 + ? + PC_PM_ID: 122 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x41027653 + RX_LANE_MAP: 0x71326405 + TX_POLARITY_FLIP: 0x22 + RX_POLARITY_FLIP: 0x3c + ? + PC_PM_ID: 123 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10265473 + RX_LANE_MAP: 0x46570321 + TX_POLARITY_FLIP: 0xbc + RX_POLARITY_FLIP: 0xb9 + ? + PC_PM_ID: 124 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10327546 + RX_LANE_MAP: 0x06371425 + TX_POLARITY_FLIP: 0x44 + RX_POLARITY_FLIP: 0xe2 + ? + PC_PM_ID: 125 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26304751 + RX_LANE_MAP: 0x67215304 + TX_POLARITY_FLIP: 0x05 + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 126 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06327451 + RX_LANE_MAP: 0x76305124 + TX_POLARITY_FLIP: 0x9b + RX_POLARITY_FLIP: 0x64 + ? + PC_PM_ID: 127 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37241506 + RX_LANE_MAP: 0x40526371 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0xbf + ? + PC_PM_ID: 128 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67452103 + RX_LANE_MAP: 0x50264713 + TX_POLARITY_FLIP: 0x58 + RX_POLARITY_FLIP: 0x62 + ? + PC_PM_ID: 129 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x0123 + RX_LANE_MAP: 0x0123 + TX_POLARITY_FLIP: 0x0 + RX_POLARITY_FLIP: 0x0 +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 105 + : + PC_PHYS_PORT_ID: 185 + ? + PORT_ID: 120 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 121 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 123 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 138 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 16 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 139 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 141 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 156 + : + PC_PHYS_PORT_ID: 257 + ? + PORT_ID: 157 + : + PC_PHYS_PORT_ID: 265 + ? + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 273 + ? + PORT_ID: 159 + : + PC_PHYS_PORT_ID: 281 + ? + PORT_ID: 174 + : + PC_PHYS_PORT_ID: 289 + ? + PORT_ID: 175 + : + PC_PHYS_PORT_ID: 297 + ? + PORT_ID: 176 + : + PC_PHYS_PORT_ID: 305 + ? + PORT_ID: 177 + : + PC_PHYS_PORT_ID: 313 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 192 + : + PC_PHYS_PORT_ID: 321 + ? + PORT_ID: 193 + : + PC_PHYS_PORT_ID: 329 + ? + PORT_ID: 194 + : + PC_PHYS_PORT_ID: 337 + ? + PORT_ID: 195 + : + PC_PHYS_PORT_ID: 345 + ? + PORT_ID: 210 + : + PC_PHYS_PORT_ID: 353 + ? + PORT_ID: 211 + : + PC_PHYS_PORT_ID: 361 + ? + PORT_ID: 212 + : + PC_PHYS_PORT_ID: 369 + ? + PORT_ID: 213 + : + PC_PHYS_PORT_ID: 377 + ? + PORT_ID: 228 + : + PC_PHYS_PORT_ID: 385 + ? + PORT_ID: 31 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 229 + : + PC_PHYS_PORT_ID: 393 + ? + PORT_ID: 230 + : + PC_PHYS_PORT_ID: 401 + ? + PORT_ID: 231 + : + PC_PHYS_PORT_ID: 409 + ? + PORT_ID: 246 + : + PC_PHYS_PORT_ID: 417 + ? + PORT_ID: 247 + : + PC_PHYS_PORT_ID: 425 + ? + PORT_ID: 248 + : + PC_PHYS_PORT_ID: 433 + ? + PORT_ID: 249 + : + PC_PHYS_PORT_ID: 441 + ? + PORT_ID: 264 + : + PC_PHYS_PORT_ID: 449 + ? + PORT_ID: 265 + : + PC_PHYS_PORT_ID: 457 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 266 + : + PC_PHYS_PORT_ID: 465 + ? + PORT_ID: 267 + : + PC_PHYS_PORT_ID: 473 + ? + PORT_ID: 282 + : + PC_PHYS_PORT_ID: 481 + ? + PORT_ID: 283 + : + PC_PHYS_PORT_ID: 489 + ? + PORT_ID: 284 + : + PC_PHYS_PORT_ID: 497 + ? + PORT_ID: 285 + : + PC_PHYS_PORT_ID: 505 + ? + PORT_ID: 300 + : + PC_PHYS_PORT_ID: 513 + ? + PORT_ID: 301 + : + PC_PHYS_PORT_ID: 521 + ? + PORT_ID: 302 + : + PC_PHYS_PORT_ID: 529 + ? + PORT_ID: 33 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 303 + : + PC_PHYS_PORT_ID: 537 + ? + PORT_ID: 318 + : + PC_PHYS_PORT_ID: 545 + ? + PORT_ID: 319 + : + PC_PHYS_PORT_ID: 553 + ? + PORT_ID: 320 + : + PC_PHYS_PORT_ID: 561 + ? + PORT_ID: 321 + : + PC_PHYS_PORT_ID: 569 + ? + PORT_ID: 336 + : + PC_PHYS_PORT_ID: 577 + ? + PORT_ID: 337 + : + PC_PHYS_PORT_ID: 585 + ? + PORT_ID: 338 + : + PC_PHYS_PORT_ID: 593 + ? + PORT_ID: 339 + : + PC_PHYS_PORT_ID: 601 + ? + PORT_ID: 354 + : + PC_PHYS_PORT_ID: 609 + ? + PORT_ID: 355 + : + PC_PHYS_PORT_ID: 617 + ? + PORT_ID: 356 + : + PC_PHYS_PORT_ID: 625 + ? + PORT_ID: 357 + : + PC_PHYS_PORT_ID: 633 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 372 + : + PC_PHYS_PORT_ID: 641 + ? + PORT_ID: 373 + : + PC_PHYS_PORT_ID: 649 + ? + PORT_ID: 374 + : + PC_PHYS_PORT_ID: 657 + ? + PORT_ID: 375 + : + PC_PHYS_PORT_ID: 665 + ? + PORT_ID: 390 + : + PC_PHYS_PORT_ID: 673 + ? + PORT_ID: 391 + : + PC_PHYS_PORT_ID: 681 + ? + PORT_ID: 392 + : + PC_PHYS_PORT_ID: 689 + ? + PORT_ID: 393 + : + PC_PHYS_PORT_ID: 697 + ? + PORT_ID: 408 + : + PC_PHYS_PORT_ID: 705 + ? + PORT_ID: 49 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 409 + : + PC_PHYS_PORT_ID: 713 + ? + PORT_ID: 410 + : + PC_PHYS_PORT_ID: 721 + ? + PORT_ID: 411 + : + PC_PHYS_PORT_ID: 729 + ? + PORT_ID: 426 + : + PC_PHYS_PORT_ID: 737 + ? + PORT_ID: 427 + : + PC_PHYS_PORT_ID: 745 + ? + PORT_ID: 428 + : + PC_PHYS_PORT_ID: 753 + ? + PORT_ID: 429 + : + PC_PHYS_PORT_ID: 761 + ? + PORT_ID: 444 + : + PC_PHYS_PORT_ID: 769 + ? + PORT_ID: 445 + : + PC_PHYS_PORT_ID: 777 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 446 + : + PC_PHYS_PORT_ID: 785 + ? + PORT_ID: 447 + : + PC_PHYS_PORT_ID: 793 + ? + PORT_ID: 462 + : + PC_PHYS_PORT_ID: 801 + ? + PORT_ID: 463 + : + PC_PHYS_PORT_ID: 809 + ? + PORT_ID: 464 + : + PC_PHYS_PORT_ID: 817 + ? + PORT_ID: 465 + : + PC_PHYS_PORT_ID: 825 + ? + PORT_ID: 480 + : + PC_PHYS_PORT_ID: 833 + ? + PORT_ID: 481 + : + PC_PHYS_PORT_ID: 841 + ? + PORT_ID: 482 + : + PC_PHYS_PORT_ID: 849 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 483 + : + PC_PHYS_PORT_ID: 857 + ? + PORT_ID: 498 + : + PC_PHYS_PORT_ID: 865 + ? + PORT_ID: 499 + : + PC_PHYS_PORT_ID: 873 + ? + PORT_ID: 500 + : + PC_PHYS_PORT_ID: 881 + ? + PORT_ID: 501 + : + PC_PHYS_PORT_ID: 889 + ? + PORT_ID: 14 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 516 + : + PC_PHYS_PORT_ID: 897 + ? + PORT_ID: 517 + : + PC_PHYS_PORT_ID: 905 + ? + PORT_ID: 518 + : + PC_PHYS_PORT_ID: 913 + ? + PORT_ID: 519 + : + PC_PHYS_PORT_ID: 921 + ? + PORT_ID: 534 + : + PC_PHYS_PORT_ID: 929 + ? + PORT_ID: 535 + : + PC_PHYS_PORT_ID: 937 + ? + PORT_ID: 536 + : + PC_PHYS_PORT_ID: 945 + ? + PORT_ID: 537 + : + PC_PHYS_PORT_ID: 953 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 552 + : + PC_PHYS_PORT_ID: 961 + ? + PORT_ID: 553 + : + PC_PHYS_PORT_ID: 969 + ? + PORT_ID: 554 + : + PC_PHYS_PORT_ID: 977 + ? + PORT_ID: 555 + : + PC_PHYS_PORT_ID: 985 + ? + PORT_ID: 570 + : + PC_PHYS_PORT_ID: 993 + ? + PORT_ID: 571 + : + PC_PHYS_PORT_ID: 1001 + ? + PORT_ID: 572 + : + PC_PHYS_PORT_ID: 1009 + ? + PORT_ID: 573 + : + PC_PHYS_PORT_ID: 1017 + ? + PORT_ID: 67 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 69 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 84 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 85 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 86 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 87 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 102 + : + PC_PHYS_PORT_ID: 161 + ? + PORT_ID: 103 + : + PC_PHYS_PORT_ID: 169 + ? + PORT_ID: 104 + : + PC_PHYS_PORT_ID: 177 + ? + PORT_ID: 268 + : + PC_PHYS_PORT_ID: 1026 + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + ENABLE: 1 + SPEED: 800000 + NUM_LANES: 8 + FEC_MODE: PC_FEC_RS544_2XN_IEEE + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [268] + : + ENABLE: 1 + SPEED: 100000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS528 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 +... + +--- +device: + 0: + PC_PMD_FIRMWARE: + ? + PORT_ID: [192, 194, 195, 210, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 300, 301, 302, 303, 318, 319, 320, 336, 337, 338, 339, 354, 355, 356, 357, 372, 374, 375, 390] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_COPPER + NORMAL_REACH_PAM4_AUTO: 0 + NORMAL_REACH_PAM4: 255 + EXTENDED_REACH_PAM4_AUTO: 0 + EXTENDED_REACH_PAM4: 0 + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 193, 211, 212, 284, 285, 321, 373, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_COPPER + NORMAL_REACH_PAM4_AUTO: 0 + NORMAL_REACH_PAM4: 0 + EXTENDED_REACH_PAM4_AUTO: 0 + EXTENDED_REACH_PAM4: 255 + ? + PORT_ID: [268] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + stat_custom_receive0_management_mode: 1 + pktio_mode: 1 + sai_pfc_defaults_disable: 1 + sai_mac_policy_vfp_group: 0 + sai_skip_create_sys_efp_grp: 1 + sai_rdma_udf_disable: 1 + sai_trap_fp_action_drop_copy_to_cpu: 1 + sai_crm_hw_nh_group_cnt: 0 + riot_overlay_l3_intf_mem_size: 4096 + riot_overlay_l3_egress_mem_size: 8192 + l3_ecmp_member_first_lkup_mem_size: 8192 + l3_ecmp_member_secondary_mem_size: 8192 + failover_fixed_nh_offset_enable: 1 + sai_optimized_mmu: 0 + sai_async_fdb_nbr_enable: 1 + bcm_linkscan_interval: 100000 + sai_pfc_dlr_init_capability: 2 + sai_stats_support_mask: 0x804 +... + +--- +device: + 0: + # IFP mode + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... + +--- +bcm_device: + 0: + port: + "*": + encap_mode: IEEE +... diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/default_sku b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/default_sku new file mode 100644 index 0000000000..bb54698a9d --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/default_sku @@ -0,0 +1 @@ +M2-W6950-O128-LPO-N l2 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/hwsku.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/hwsku.json new file mode 100644 index 0000000000..276fda2943 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/hwsku.json @@ -0,0 +1,654 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet136": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet144": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet152": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet160": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet168": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet176": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet184": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet192": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet200": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet208": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet216": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet224": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet232": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet240": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet248": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet256": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet264": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet272": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet280": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet288": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet296": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet304": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet312": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet320": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet328": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet336": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet344": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet352": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet360": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet368": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet376": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet384": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet392": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet400": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet408": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet416": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet424": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet432": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet440": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet448": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet456": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet464": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet472": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet480": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet488": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet496": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet504": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet512": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet520": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet528": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet536": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet544": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet552": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet560": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet568": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet576": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet584": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet592": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet600": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet608": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet616": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet624": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet632": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet640": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet648": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet656": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet664": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet672": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet680": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet688": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet696": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet704": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet712": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet720": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet728": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet736": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet744": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet752": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet760": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet768": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet776": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet784": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet792": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet800": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet808": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet816": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet824": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet832": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet840": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet848": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet856": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet864": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet872": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet880": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet888": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet896": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet904": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet912": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet920": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet928": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet936": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet944": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet952": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet960": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet968": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet976": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet984": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet992": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1000": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1008": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1016": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1024": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1025": { + "default_brkout_mode": "1x1G", + "autoneg": "off", + "fec": "none" + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/media_settings.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/media_settings.json new file mode 100644 index 0000000000..267b5d2f3d --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/media_settings.json @@ -0,0 +1,8196 @@ +{ + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "2": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "3": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "4": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "5": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "6": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "7": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "8": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "9": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "10": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "11": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "12": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "13": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "14": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "15": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "16": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "17": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "18": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "19": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "20": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "21": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "22": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "23": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "24": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "25": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "26": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "27": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "28": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "29": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "30": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "31": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "32": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "33": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "34": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "35": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "36": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "37": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "38": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "39": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "40": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "41": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "42": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "43": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "44": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "45": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "46": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "47": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "48": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "49": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "50": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "51": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "52": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "53": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "54": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "55": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "56": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "57": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "58": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "59": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "60": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "61": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "62": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "63": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "64": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "65": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "66": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "67": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "68": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "69": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "70": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "71": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "72": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "73": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "74": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "75": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "76": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "77": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "78": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "79": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "80": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "81": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "82": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "83": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "84": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "85": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "86": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "87": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "88": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "89": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "90": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "91": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "92": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "93": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "94": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "95": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "96": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "97": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "98": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "99": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "100": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "101": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "102": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "103": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "104": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "105": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "106": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "107": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "108": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "109": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "110": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "111": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "112": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "113": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "114": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "115": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "116": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "117": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "118": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "119": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "120": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "121": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "122": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "123": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "124": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "125": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "126": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "127": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "128": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/port_config.ini b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/port_config.ini new file mode 100644 index 0000000000..6b950df1d2 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/port_config.ini @@ -0,0 +1,131 @@ +# name lanes alias index speed +Ethernet0 265,266,267,268,269,270,271,272 etp1 1 800000 +Ethernet8 297,298,299,300,301,302,303,304 etp2 2 800000 +Ethernet16 305,306,307,308,309,310,311,312 etp3 3 800000 +Ethernet24 313,314,315,316,317,318,319,320 etp4 4 800000 +Ethernet32 377,378,379,380,381,382,383,384 etp5 5 800000 +Ethernet40 369,370,371,372,373,374,375,376 etp6 6 800000 +Ethernet48 361,362,363,364,365,366,367,368 etp7 7 800000 +Ethernet56 329,330,331,332,333,334,335,336 etp8 8 800000 +Ethernet64 505,506,507,508,509,510,511,512 etp9 9 800000 +Ethernet72 497,498,499,500,501,502,503,504 etp10 10 800000 +Ethernet80 489,490,491,492,493,494,495,496 etp11 11 800000 +Ethernet88 457,458,459,460,461,462,463,464 etp12 12 800000 +Ethernet96 449,450,451,452,453,454,455,456 etp13 13 800000 +Ethernet104 465,466,467,468,469,470,471,472 etp14 14 800000 +Ethernet112 481,482,483,484,485,486,487,488 etp15 15 800000 +Ethernet120 473,474,475,476,477,478,479,480 etp16 16 800000 +Ethernet128 537,538,539,540,541,542,543,544 etp17 17 800000 +Ethernet136 545,546,547,548,549,550,551,552 etp18 18 800000 +Ethernet144 529,530,531,532,533,534,535,536 etp19 19 800000 +Ethernet152 513,514,515,516,517,518,519,520 etp20 20 800000 +Ethernet160 521,522,523,524,525,526,527,528 etp21 21 800000 +Ethernet168 553,554,555,556,557,558,559,560 etp22 22 800000 +Ethernet176 561,562,563,564,565,566,567,568 etp23 23 800000 +Ethernet184 569,570,571,572,573,574,575,576 etp24 24 800000 +Ethernet192 649,650,651,652,653,654,655,656 etp25 25 800000 +Ethernet200 681,682,683,684,685,686,687,688 etp26 26 800000 +Ethernet208 689,690,691,692,693,694,695,696 etp27 27 800000 +Ethernet216 697,698,699,700,701,702,703,704 etp28 28 800000 +Ethernet224 761,762,763,764,765,766,767,768 etp29 29 800000 +Ethernet232 753,754,755,756,757,758,759,760 etp30 30 800000 +Ethernet240 713,714,715,716,717,718,719,720 etp31 31 800000 +Ethernet248 745,746,747,748,749,750,751,752 etp32 32 800000 +Ethernet256 33,34,35,36,37,38,39,40 etp33 33 800000 +Ethernet264 1,2,3,4,5,6,7,8 etp34 34 800000 +Ethernet272 41,42,43,44,45,46,47,48 etp35 35 800000 +Ethernet280 57,58,59,60,61,62,63,64 etp36 36 800000 +Ethernet288 121,122,123,124,125,126,127,128 etp37 37 800000 +Ethernet296 105,106,107,108,109,110,111,112 etp38 38 800000 +Ethernet304 65,66,67,68,69,70,71,72 etp39 39 800000 +Ethernet312 97,98,99,100,101,102,103,104 etp40 40 800000 +Ethernet320 153,154,155,156,157,158,159,160 etp41 41 800000 +Ethernet328 145,146,147,148,149,150,151,152 etp42 42 800000 +Ethernet336 321,322,323,324,325,326,327,328 etp43 43 800000 +Ethernet344 353,354,355,356,357,358,359,360 etp44 44 800000 +Ethernet352 409,410,411,412,413,414,415,416 etp45 45 800000 +Ethernet360 401,402,403,404,405,406,407,408 etp46 46 800000 +Ethernet368 393,394,395,396,397,398,399,400 etp47 47 800000 +Ethernet376 433,434,435,436,437,438,439,440 etp48 48 800000 +Ethernet384 585,586,587,588,589,590,591,592 etp49 49 800000 +Ethernet392 625,626,627,628,629,630,631,632 etp50 50 800000 +Ethernet400 601,602,603,604,605,606,607,608 etp51 51 800000 +Ethernet408 593,594,595,596,597,598,599,600 etp52 52 800000 +Ethernet416 641,642,643,644,645,646,647,648 etp53 53 800000 +Ethernet424 673,674,675,676,677,678,679,680 etp54 54 800000 +Ethernet432 857,858,859,860,861,862,863,864 etp55 55 800000 +Ethernet440 849,850,851,852,853,854,855,856 etp56 56 800000 +Ethernet448 897,898,899,900,901,902,903,904 etp57 57 800000 +Ethernet456 929,930,931,932,933,934,935,936 etp58 58 800000 +Ethernet464 953,954,955,956,957,958,959,960 etp59 59 800000 +Ethernet472 937,938,939,940,941,942,943,944 etp60 60 800000 +Ethernet480 1001,1002,1003,1004,1005,1006,1007,1008 etp61 61 800000 +Ethernet488 1017,1018,1019,1020,1021,1022,1023,1024 etp62 62 800000 +Ethernet496 993,994,995,996,997,998,999,1000 etp63 63 800000 +Ethernet504 961,962,963,964,965,966,967,968 etp64 64 800000 +Ethernet512 17,18,19,20,21,22,23,24 etp65 65 800000 +Ethernet520 25,26,27,28,29,30,31,32 etp66 66 800000 +Ethernet528 49,50,51,52,53,54,55,56 etp67 67 800000 +Ethernet536 9,10,11,12,13,14,15,16 etp68 68 800000 +Ethernet544 73,74,75,76,77,78,79,80 etp69 69 800000 +Ethernet552 113,114,115,116,117,118,119,120 etp70 70 800000 +Ethernet560 89,90,91,92,93,94,95,96 etp71 71 800000 +Ethernet568 81,82,83,84,85,86,87,88 etp72 72 800000 +Ethernet576 129,130,131,132,133,134,135,136 etp73 73 800000 +Ethernet584 161,162,163,164,165,166,167,168 etp74 74 800000 +Ethernet592 345,346,347,348,349,350,351,352 etp75 75 800000 +Ethernet600 337,338,339,340,341,342,343,344 etp76 76 800000 +Ethernet608 385,386,387,388,389,390,391,392 etp77 77 800000 +Ethernet616 417,418,419,420,421,422,423,424 etp78 78 800000 +Ethernet624 441,442,443,444,445,446,447,448 etp79 79 800000 +Ethernet632 425,426,427,428,429,430,431,432 etp80 80 800000 +Ethernet640 633,634,635,636,637,638,639,640 etp81 81 800000 +Ethernet648 617,618,619,620,621,622,623,624 etp82 82 800000 +Ethernet656 577,578,579,580,581,582,583,584 etp83 83 800000 +Ethernet664 609,610,611,612,613,614,615,616 etp84 84 800000 +Ethernet672 665,666,667,668,669,670,671,672 etp85 85 800000 +Ethernet680 657,658,659,660,661,662,663,664 etp86 86 800000 +Ethernet688 833,834,835,836,837,838,839,840 etp87 87 800000 +Ethernet696 865,866,867,868,869,870,871,872 etp88 88 800000 +Ethernet704 921,922,923,924,925,926,927,928 etp89 89 800000 +Ethernet712 913,914,915,916,917,918,919,920 etp90 90 800000 +Ethernet720 905,906,907,908,909,910,911,912 etp91 91 800000 +Ethernet728 945,946,947,948,949,950,951,952 etp92 92 800000 +Ethernet736 1009,1010,1011,1012,1013,1014,1015,1016 etp93 93 800000 +Ethernet744 969,970,971,972,973,974,975,976 etp94 94 800000 +Ethernet752 977,978,979,980,981,982,983,984 etp95 95 800000 +Ethernet760 985,986,987,988,989,990,991,992 etp96 96 800000 +Ethernet768 209,210,211,212,213,214,215,216 etp97 97 800000 +Ethernet776 193,194,195,196,197,198,199,200 etp98 98 800000 +Ethernet784 225,226,227,228,229,230,231,232 etp99 99 800000 +Ethernet792 217,218,219,220,221,222,223,224 etp100 100 800000 +Ethernet800 281,282,283,284,285,286,287,288 etp101 101 800000 +Ethernet808 289,290,291,292,293,294,295,296 etp102 102 800000 +Ethernet816 257,258,259,260,261,262,263,264 etp103 103 800000 +Ethernet824 273,274,275,276,277,278,279,280 etp104 104 800000 +Ethernet832 201,202,203,204,205,206,207,208 etp105 105 800000 +Ethernet840 233,234,235,236,237,238,239,240 etp106 106 800000 +Ethernet848 241,242,243,244,245,246,247,248 etp107 107 800000 +Ethernet856 249,250,251,252,253,254,255,256 etp108 108 800000 +Ethernet864 185,186,187,188,189,190,191,192 etp109 109 800000 +Ethernet872 177,178,179,180,181,182,183,184 etp110 110 800000 +Ethernet880 169,170,171,172,173,174,175,176 etp111 111 800000 +Ethernet888 137,138,139,140,141,142,143,144 etp112 112 800000 +Ethernet896 841,842,843,844,845,846,847,848 etp113 113 800000 +Ethernet904 873,874,875,876,877,878,879,880 etp114 114 800000 +Ethernet912 881,882,883,884,885,886,887,888 etp115 115 800000 +Ethernet920 889,890,891,892,893,894,895,896 etp116 116 800000 +Ethernet928 825,826,827,828,829,830,831,832 etp117 117 800000 +Ethernet936 817,818,819,820,821,822,823,824 etp118 118 800000 +Ethernet944 809,810,811,812,813,814,815,816 etp119 119 800000 +Ethernet952 777,778,779,780,781,782,783,784 etp120 120 800000 +Ethernet960 721,722,723,724,725,726,727,728 etp121 121 800000 +Ethernet968 705,706,707,708,709,710,711,712 etp122 122 800000 +Ethernet976 737,738,739,740,741,742,743,744 etp123 123 800000 +Ethernet984 729,730,731,732,733,734,735,736 etp124 124 800000 +Ethernet992 793,794,795,796,797,798,799,800 etp125 125 800000 +Ethernet1000 801,802,803,804,805,806,807,808 etp126 126 800000 +Ethernet1008 785,786,787,788,789,790,791,792 etp127 127 800000 +Ethernet1016 769,770,771,772,773,774,775,776 etp128 128 800000 +Ethernet1024 1026,1027,1028,1029 etp129 129 100000 +Ethernet1025 0 etp130 130 1000 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sai.profile b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sai.profile new file mode 100644 index 0000000000..1f8c5eff68 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th6-m2-w6950-o128-lpo-n-128x800G.config.yml diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sap_bcm_81394.cfg b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sap_bcm_81394.cfg new file mode 100644 index 0000000000..c8b29b322c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/sap_bcm_81394.cfg @@ -0,0 +1,246 @@ +# Configuration file version number. +# The current sap_bcm_81394.c does not read this field; it is compatibility/identification information. +# Modifying it will not affect the initialization process of the 81394 driver. +version=1 + +# ==================== +# Global Initialization Parameters +# ==================== + +# Number of slots on the board. +# sap_aperta_config_init() first reads this value into the global g_slot_num, +# then sap_bcm_platform_init() calls sap_slot_init() for 0 to g_slot_num-1. +# Missing this field will cause configuration initialization to fail directly. +plp_slot_num=1 + +# MDIO access type. The ':1' in the key is not a PHY address, but the mdio_id. +# The code first reads plp_phy_mdio_id:0x30=1, then looks up plp_mdio_accs_type:1. +# The value comes from sap_mdio_type_e: +# 0 = MAC +# 1 = SYSFS +# 2 = SYSFS_CUST +# The current value 2 indicates using the custom sysfs MDIO access path. +plp_mdio_accs_type:1=2 + +# Firmware loading method, saved to the global g_fw_load_method. +# The definitions in the 81394 driver are: +# 0 = Do not load +# 1 = Unicast load +# 2 = Broadcast load +# 3 = EEPROM load +# 4 = upgrade path +# 5 = skip +# 6 = full process +# The current value 1 means downloading firmware to each PHY via unicast. +plp_fw_load_method=1 + +# Enable or disable I2C slave. +# The code reads this into g_i2c_slave_en, but in the current main flow of the 81394, +# the corresponding register write logic is completely commented out. +# Therefore, this value is currently a "parsed but not effective by default" field. +plp_i2c_slave_en=0 + +# AVS I2C response address. +# This is also read into g_avs_i2c_resp_addr and used by sap_bcm_avs_init() to assemble register values. +# However, AVS initialization is not actually enabled in the current boot path, so this is just a reserved configuration. +avs_i2c_resp_addr=0x35 + +# Default enable/disable link training for the port's system side. +# If there is no per-port configuration for init_linktrain_sys, each port inherits this global value. +# In sap_aperta_post_port_init(), it calls sap_bcm_linktraining_set(..., true) only if the value is 1. +# 0 means do not automatically enable LT. +plp_port_linktrain_sys=0 + +# Default enable/disable link training for the port's line side. +# The semantics are the same as plp_port_linktrain_sys, applying to the line side. +plp_port_linktrain_line=0 + +# ==================== +# Profile 1 VCO Presets +# ==================== + +# VCO selection for Profile 1, octal 0, system side. +# The 81394 code forcibly reads this and saves it to phy_info->vco_octal_0_sys. +# Confirmed from public headers: +# 0 = bcmplpVco51G +# 1 = bcmplpVco53G +# The current value 1 means 53G VCO. +# Note: In this version of the 81394 implementation, this value is read but not used further in mode_config_set. +# It seems more like a field retained to share the configuration format with other chips in the family. +plp_profile_1_init_vco_octal_0_sys=1 + +# VCO selection for Profile 1, octal 0, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_0_line=1 + +# VCO selection for Profile 1, octal 1, system side. +# The current board type uses only one PHY at address 0x30 and the profile uses lanes=0,1, +# but the code still requires the VCO for octal 1 to be configured, otherwise configuration parsing fails. +plp_profile_1_init_vco_octal_1_sys=1 + +# VCO selection for Profile 1, octal 1, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_1_line=1 + +# ==================== +# Profile 1: 100G, split=1, Single port with 4 lanes +# Key format: plp_profile__speed__split_.: +# This is changed to a single 100G port, hence split_num=1, port_id=0. +# +# In the 81394 code, split_num is not hardcoded, but calculated by: +# phy_info->lane_num / port_info->lanes +# Therefore, to target split_1.0, the init_lanes below needs to provide 4 lane entries, +# and init_ports_lane_num must be configured as 4, indicating a 4-lane aggregated port. +# ==================== + +# FEC mode for the line side. +# For the 100G 4x25G scenario, the semantics from the original file are retained, where 3 = RSFEC. +# This still uses the 25.78125G/lane NRZ path, not 2x50G PAM4. +plp_profile_1_speed_100000_split_1.0:fec_line=3 + +# FEC mode for the system side. +# Consistent with the line side, configured as 3 = RSFEC. +plp_profile_1_speed_100000_split_1.0:fec_sys=3 + +# Interface type for the line side. +# In bcm_pm_interface_t, 7 = bcm_pm_InterfaceKR4. +# This is changed from the single-lane KR to 4-lane KR4, matching the 100G 4-lane port form factor. +plp_profile_1_speed_100000_split_1.0:iftype_line=7 + +# Interface type for the system side. +# Also changed to 7 = KR4, maintaining the lane count and interface width consistency between system/line sides. +plp_profile_1_speed_100000_split_1.0:iftype_sys=7 + +# Line side lane bitmask. +# 0xF = 0000 1111b, indicating selection of 4 consecutive lanes. +# With speed=100000, the code calculates the per-lane speed as 25.78125G. +plp_profile_1_speed_100000_split_1.0:lanemap_line=0xF + +# System side lane bitmask. +# Same as the line side, indicating a 4-lane passthrough port, not a gearbox/reverse-gearbox. +plp_profile_1_speed_100000_split_1.0:lanemap_sys=0xF + +# Force NR (No Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_sys=0x0 + +# Force NR (No Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_line=0x0 + +# Force ER (Eye Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_sys=0x0 + +# Force ER (Eye Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_line=0x0 + + +# ==================== +# PHY List +# ==================== + +# List of PHY addresses to initialize. +# sap_aperta_config_init() generates g_bcm_phy_infos based on this array. +# Currently, there is only one PHY at address 0x30. +plp_phy_addrs=0x30 + +# ==================== +# PHY 0x30 Base Attributes +# PHY address resolution method: +# bus_id = (phy_addr & 0x7c00)>>10; +# mdio_index = (phy_addr & 0x3e0)>>5; +# phy_addr = phy_addr & 0x1f; +# return dfd_utest_mdiodev_rd(mdio_index+bus_id, phy_addr, reg_addr, data); +# ==================== + +# The unit to which the PHY is bound. +# sap_slot_init() filters by unit and card_id to determine if this PHY should be initialized in the current round. +plp_phy_unit_id:0x30=0 + +# The card/slot number the PHY belongs to. +# The PHY is initialized only when this matches the outer slot_id. +plp_phy_card_id:0x30=0 + +# The mdio_id used by this PHY. +# The code will then use this mdio_id to look up plp_mdio_accs_type:. +plp_phy_mdio_id:0x30=1 + +# PHY chip name. +# For this version of the 81394 code, this is a compatibility field, as the chip_name is hardcoded to "aperta" in the source. +# Modifying it will not change the chip name used by the driver. +plp_phy_chip_name:0x30=aperta + +# MACsec option. +# The current 81394 file only reads and saves this to phy_info->macsec_option, with no subsequent use observed. +# Therefore, this is more of a reserved field. +plp_phy_macsec_option:0x30=0x0 + +# PTP option. +# Similar to macsec_option, currently only parsed and saved, not consumed in the main 81394 flow. +plp_phy_ptp_option:0x30=0x0 + +# The initialization profile ID used by this PHY. +# The '1' in all subsequent plp_profile_1_* key names is determined by this value. +plp_phy_init_profile_id:0x30=1 + +# The lane list for this PHY under Profile 1. +# This is changed to 0,1,2,3. This does not mean 4 independent logical ports, +# but rather to make phy_info->lane_num = 4, causing the code to calculate split_num = 1. +# The number of logical ports actually created is still determined by the next line, init_ports. +plp_profile_1_init_lanes:0x30=0-3 + +# The list of logical port numbers presented externally by this PHY under Profile 1. +# Changed to create only one logical port, port 1, to carry the 1x100G module. +plp_profile_1_init_ports:0x30=1 + +# The number of lanes occupied by each logical port under Profile 1. +# Changed to a single port occupying 4 lanes. +plp_profile_1_init_ports_lane_num:0x30=4 + +# The initial speed of each logical port under Profile 1. +# Changed to 100000 Mbps for a single port, i.e., 100G. +plp_profile_1_init_speed_mode:0x30=100000 + +# ==================== +# PHY 0x30 Global Lane Swap and Polarity Configuration +# These keys apply to the entire PHY, not a single port. +# ==================== + +# System side TX lane mapping. +# This value is parsed as 8 nibbles, lane by lane. +# lane_map_tx[lane_index] = GET_LANE_SWAP_OCTAL(value, lane_index). +# 0x76543210 represents logical 0->0, 1->1, 2->2... 7->7, which is an identity mapping. +plp_phy_tx_lane_map_sys:0x30=0x76543210 + +# System side RX lane mapping. +# Currently also an identity mapping. +plp_phy_rx_lane_map_sys:0x30=0x76543210 + +# Line side TX lane mapping. +# 0x76543120 indicates a lane swap on the line side, no longer a direct passthrough. +# The code calls bcm_plp_rxtx_laneswap_set() in sap_aperta_phy_init() to apply this. +plp_phy_tx_lane_map_line:0x30=0x76542301 + +# Line side RX lane mapping. +# Currently the same as TX, indicating that RX/TX both follow the same line-side swapping rules. +plp_phy_rx_lane_map_line:0x30=0x76542301 + +# Line side TX polarity flip bitmap. +# In sap_aperta_phy_init(), the current polarity is read, XORed with this value, and then written back. +# Therefore, a bit=1 means flip the polarity for the corresponding lane; 0 means leave it unchanged. +# The current 0x0 means no polarity flip on the line side TX. +plp_tx_polarity_flip_line:0x30=0x0 + +# Line side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the line side RX. +plp_rx_polarity_flip_line:0x30=0xF + +# System side TX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side TX. +plp_tx_polarity_flip_sys:0x30=0x0 + +# System side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side RX. +plp_rx_polarity_flip_sys:0x30=0x0 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/th6-m2-w6950-o128-lpo-n-128x800G.config.yml b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/th6-m2-w6950-o128-lpo-n-128x800G.config.yml new file mode 100644 index 0000000000..232e09bcf8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128-LPO-N/th6-m2-w6950-o128-lpo-n-128x800G.config.yml @@ -0,0 +1,2182 @@ +--- +device: + 0: + DEVICE_CONFIG: + AUTOLOAD_BOARD_SETTINGS: 0 +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12360745 + RX_LANE_MAP: 0x34726150 + TX_POLARITY_FLIP: 0x57 + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327140 + RX_LANE_MAP: 0x60317425 + TX_POLARITY_FLIP: 0x99 + RX_POLARITY_FLIP: 0xa6 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23145670 + RX_LANE_MAP: 0x57462103 + TX_POLARITY_FLIP: 0x6e + RX_POLARITY_FLIP: 0xe6 + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45726013 + RX_LANE_MAP: 0x12360475 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0x78 + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17204653 + RX_LANE_MAP: 0x54036127 + TX_POLARITY_FLIP: 0x3f + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x14027653 + RX_LANE_MAP: 0x54217036 + TX_POLARITY_FLIP: 0x45 + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26351407 + RX_LANE_MAP: 0x52407163 + TX_POLARITY_FLIP: 0x43 + RX_POLARITY_FLIP: 0xef + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670321 + RX_LANE_MAP: 0x53274610 + TX_POLARITY_FLIP: 0xad + RX_POLARITY_FLIP: 0x27 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21705463 + RX_LANE_MAP: 0x46327105 + TX_POLARITY_FLIP: 0x95 + RX_POLARITY_FLIP: 0xbf + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12057463 + RX_LANE_MAP: 0x51740236 + TX_POLARITY_FLIP: 0xc8 + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67105243 + RX_LANE_MAP: 0x40236715 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23164507 + RX_LANE_MAP: 0x45712063 + TX_POLARITY_FLIP: 0xd7 + RX_POLARITY_FLIP: 0x4c + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46570213 + RX_LANE_MAP: 0x71546032 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0xae + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17453206 + RX_LANE_MAP: 0x61257430 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x9b + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327041 + RX_LANE_MAP: 0x50361427 + TX_POLARITY_FLIP: 0xe2 + RX_POLARITY_FLIP: 0x7 + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x57624301 + TX_POLARITY_FLIP: 0x0d + RX_POLARITY_FLIP: 0x5f + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01374526 + RX_LANE_MAP: 0x64751032 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0xe6 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13024675 + RX_LANE_MAP: 0x61304275 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0x5e + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x16452307 + RX_LANE_MAP: 0x50346721 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0x47 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32604571 + RX_LANE_MAP: 0x67205314 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0x3f + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46120573 + RX_LANE_MAP: 0x13526407 + TX_POLARITY_FLIP: 0x2e + RX_POLARITY_FLIP: 0x9 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x30412657 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xfb + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13207465 + RX_LANE_MAP: 0x20316475 + TX_POLARITY_FLIP: 0x01 + RX_POLARITY_FLIP: 0xc7 + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x61305274 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23107465 + RX_LANE_MAP: 0x32107654 + TX_POLARITY_FLIP: 0x62 + RX_POLARITY_FLIP: 0x66 + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0x8 + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x62307145 + TX_POLARITY_FLIP: 0x9d + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x31064752 + RX_LANE_MAP: 0x02135764 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0x35 + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12357064 + RX_LANE_MAP: 0x03216457 + TX_POLARITY_FLIP: 0x81 + RX_POLARITY_FLIP: 0xdc + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106745 + RX_LANE_MAP: 0x61034275 + TX_POLARITY_FLIP: 0x11 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32014756 + RX_LANE_MAP: 0x13024576 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0x31 + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02376154 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xd5 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 33 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x02637154 + TX_POLARITY_FLIP: 0xe7 + RX_POLARITY_FLIP: 0xdf + ? + PC_PM_ID: 34 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0xfe + ? + PC_PM_ID: 35 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02134765 + RX_LANE_MAP: 0x13026745 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0x7d + ? + PC_PM_ID: 36 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23016745 + RX_LANE_MAP: 0x30162745 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0x36 + ? + PC_PM_ID: 37 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30412675 + RX_LANE_MAP: 0x32051674 + TX_POLARITY_FLIP: 0xa7 + RX_POLARITY_FLIP: 0xe4 + ? + PC_PM_ID: 38 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x6e + ? + PC_PM_ID: 39 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x01534267 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0xd6 + ? + PC_PM_ID: 40 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x7e + ? + PC_PM_ID: 41 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x46357201 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0xc5 + ? + PC_PM_ID: 42 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x10325746 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0x11 + ? + PC_PM_ID: 43 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65073421 + RX_LANE_MAP: 0x53026714 + TX_POLARITY_FLIP: 0x7e + RX_POLARITY_FLIP: 0x3a + ? + PC_PM_ID: 44 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21057463 + RX_LANE_MAP: 0x47513260 + TX_POLARITY_FLIP: 0x65 + RX_POLARITY_FLIP: 0xf8 + ? + PC_PM_ID: 45 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47061235 + RX_LANE_MAP: 0x41276530 + TX_POLARITY_FLIP: 0x34 + RX_POLARITY_FLIP: 0x0e + ? + PC_PM_ID: 46 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x01437265 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 47 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x13607254 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0xbb + ? + PC_PM_ID: 48 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x13025476 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0x31 + ? + PC_PM_ID: 49 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70152643 + RX_LANE_MAP: 0x76512043 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 50 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x04635271 + RX_LANE_MAP: 0x67235014 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0xda + ? + PC_PM_ID: 51 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x76540213 + RX_LANE_MAP: 0x51376240 + TX_POLARITY_FLIP: 0xf1 + RX_POLARITY_FLIP: 0x3b + ? + PC_PM_ID: 52 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12375460 + RX_LANE_MAP: 0x54261037 + TX_POLARITY_FLIP: 0xe1 + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 53 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64301572 + RX_LANE_MAP: 0x63107425 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0xe8 + ? + PC_PM_ID: 54 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45213670 + RX_LANE_MAP: 0x41062537 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0xf7 + ? + PC_PM_ID: 55 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25461073 + RX_LANE_MAP: 0x73215640 + TX_POLARITY_FLIP: 0xec + RX_POLARITY_FLIP: 0xf1 + ? + PC_PM_ID: 56 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30264571 + RX_LANE_MAP: 0x67452031 + TX_POLARITY_FLIP: 0x38 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 57 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0xdc + ? + PC_PM_ID: 58 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0x80 + ? + PC_PM_ID: 59 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x23017654 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x69 + ? + PC_PM_ID: 60 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0xcc + ? + PC_PM_ID: 61 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x02341675 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 62 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x23106754 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0xd9 + ? + PC_PM_ID: 63 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36170254 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x8c + ? + PC_PM_ID: 64 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xd0 + RX_POLARITY_FLIP: 0x80 + ? + PC_PM_ID: 65 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0x7a + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 66 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x13 + RX_POLARITY_FLIP: 0xbf + ? + PC_PM_ID: 67 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x32106745 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x69 + ? + PC_PM_ID: 68 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0xa3 + RX_POLARITY_FLIP: 0x33 + ? + PC_PM_ID: 69 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x20436157 + TX_POLARITY_FLIP: 0xd3 + RX_POLARITY_FLIP: 0xcb + ? + PC_PM_ID: 70 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x32017645 + TX_POLARITY_FLIP: 0x63 + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 71 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63712045 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 72 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x23 + RX_POLARITY_FLIP: 0xbf + ? + PC_PM_ID: 73 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13762540 + RX_LANE_MAP: 0x51764320 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 74 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x62135470 + RX_LANE_MAP: 0x64025317 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x15 + ? + PC_PM_ID: 75 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54761302 + RX_LANE_MAP: 0x50326741 + TX_POLARITY_FLIP: 0x0b + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 76 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x34075261 + RX_LANE_MAP: 0x57021634 + TX_POLARITY_FLIP: 0x5a + RX_POLARITY_FLIP: 0x0f + ? + PC_PM_ID: 77 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75201463 + RX_LANE_MAP: 0x70126435 + TX_POLARITY_FLIP: 0xe4 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 78 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67013542 + RX_LANE_MAP: 0x26034517 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x80 + ? + PC_PM_ID: 79 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46257310 + RX_LANE_MAP: 0x70265143 + TX_POLARITY_FLIP: 0x4c + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 80 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21354670 + RX_LANE_MAP: 0x45673120 + TX_POLARITY_FLIP: 0xab + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 81 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41237506 + TX_POLARITY_FLIP: 0x80 + RX_POLARITY_FLIP: 0x7b + ? + PC_PM_ID: 82 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x01237564 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0x22 + ? + PC_PM_ID: 83 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x24173560 + RX_LANE_MAP: 0x62015734 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0x0f + ? + PC_PM_ID: 84 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03247561 + RX_LANE_MAP: 0x51476032 + TX_POLARITY_FLIP: 0xf6 + RX_POLARITY_FLIP: 0x0d + ? + PC_PM_ID: 85 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06473512 + RX_LANE_MAP: 0x40256731 + TX_POLARITY_FLIP: 0x3e + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 86 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x10342756 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0x36 + ? + PC_PM_ID: 87 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x31062745 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 88 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x31204567 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0x32 + ? + PC_PM_ID: 89 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64751302 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0x4 + ? + PC_PM_ID: 90 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0xfd + ? + PC_PM_ID: 91 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65471302 + RX_LANE_MAP: 0x54762031 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0x41 + ? + PC_PM_ID: 92 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670123 + RX_LANE_MAP: 0x54726103 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0x93 + ? + PC_PM_ID: 93 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75264130 + RX_LANE_MAP: 0x47615023 + TX_POLARITY_FLIP: 0x25 + RX_POLARITY_FLIP: 0xd8 + ? + PC_PM_ID: 94 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x6e + ? + PC_PM_ID: 95 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x10352476 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0xe9 + ? + PC_PM_ID: 96 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0xbd + ? + PC_PM_ID: 97 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65741023 + RX_LANE_MAP: 0x45670123 + TX_POLARITY_FLIP: 0x76 + RX_POLARITY_FLIP: 0x99 + ? + PC_PM_ID: 98 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0x84 + RX_POLARITY_FLIP: 0xef + ? + PC_PM_ID: 99 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x45713062 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 100 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52470631 + RX_LANE_MAP: 0x46753120 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x53 + ? + PC_PM_ID: 101 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64703512 + RX_LANE_MAP: 0x75461230 + TX_POLARITY_FLIP: 0xbd + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 102 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45671032 + RX_LANE_MAP: 0x57243016 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0x63 + ? + PC_PM_ID: 103 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56470132 + RX_LANE_MAP: 0x67542031 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x73 + ? + PC_PM_ID: 104 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54613702 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0xa8 + RX_POLARITY_FLIP: 0xf7 + ? + PC_PM_ID: 105 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36054721 + RX_LANE_MAP: 0x75643210 + TX_POLARITY_FLIP: 0xb7 + RX_POLARITY_FLIP: 0x46 + ? + PC_PM_ID: 106 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75642031 + RX_LANE_MAP: 0x57240316 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x85 + ? + PC_PM_ID: 107 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45160723 + RX_LANE_MAP: 0x51376420 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0xbc + ? + PC_PM_ID: 108 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65104273 + RX_LANE_MAP: 0x64325017 + TX_POLARITY_FLIP: 0xc9 + RX_POLARITY_FLIP: 0xe4 + ? + PC_PM_ID: 109 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75320641 + RX_LANE_MAP: 0x62501437 + TX_POLARITY_FLIP: 0xd1 + RX_POLARITY_FLIP: 0x7e + ? + PC_PM_ID: 110 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x75621403 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0x20 + ? + PC_PM_ID: 111 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65742013 + RX_LANE_MAP: 0x57461302 + TX_POLARITY_FLIP: 0xbf + RX_POLARITY_FLIP: 0x1c + ? + PC_PM_ID: 112 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x47250316 + TX_POLARITY_FLIP: 0xf9 + RX_POLARITY_FLIP: 0x11 + ? + PC_PM_ID: 113 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74305162 + RX_LANE_MAP: 0x75014236 + TX_POLARITY_FLIP: 0x8e + RX_POLARITY_FLIP: 0xfe + ? + PC_PM_ID: 114 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03147562 + RX_LANE_MAP: 0x74513602 + TX_POLARITY_FLIP: 0x0e + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 115 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x42305761 + RX_LANE_MAP: 0x63214705 + TX_POLARITY_FLIP: 0x08 + RX_POLARITY_FLIP: 0x5 + ? + PC_PM_ID: 116 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17254603 + RX_LANE_MAP: 0x71456320 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 117 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x57461302 + RX_LANE_MAP: 0x72506431 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 118 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45170632 + RX_LANE_MAP: 0x60247531 + TX_POLARITY_FLIP: 0x55 + RX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 119 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x40127653 + RX_LANE_MAP: 0x16325407 + TX_POLARITY_FLIP: 0x9f + RX_POLARITY_FLIP: 0xea + ? + PC_PM_ID: 120 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41035267 + TX_POLARITY_FLIP: 0x97 + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 121 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124507 + RX_LANE_MAP: 0x30716254 + TX_POLARITY_FLIP: 0xa2 + RX_POLARITY_FLIP: 0x7c + ? + PC_PM_ID: 122 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x41027653 + RX_LANE_MAP: 0x71326405 + TX_POLARITY_FLIP: 0x22 + RX_POLARITY_FLIP: 0xc3 + ? + PC_PM_ID: 123 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10265473 + RX_LANE_MAP: 0x46570321 + TX_POLARITY_FLIP: 0xbc + RX_POLARITY_FLIP: 0x46 + ? + PC_PM_ID: 124 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10327546 + RX_LANE_MAP: 0x06371425 + TX_POLARITY_FLIP: 0x44 + RX_POLARITY_FLIP: 0x1d + ? + PC_PM_ID: 125 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26304751 + RX_LANE_MAP: 0x67215304 + TX_POLARITY_FLIP: 0x05 + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 126 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06327451 + RX_LANE_MAP: 0x76305124 + TX_POLARITY_FLIP: 0x9b + RX_POLARITY_FLIP: 0x9b + ? + PC_PM_ID: 127 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37241506 + RX_LANE_MAP: 0x40526371 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 128 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67452103 + RX_LANE_MAP: 0x50264713 + TX_POLARITY_FLIP: 0x58 + RX_POLARITY_FLIP: 0x9d + ? + PC_PM_ID: 129 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x0123 + RX_LANE_MAP: 0x0123 + TX_POLARITY_FLIP: 0x0 + RX_POLARITY_FLIP: 0x0 +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 105 + : + PC_PHYS_PORT_ID: 185 + ? + PORT_ID: 120 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 121 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 123 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 138 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 16 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 139 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 141 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 156 + : + PC_PHYS_PORT_ID: 257 + ? + PORT_ID: 157 + : + PC_PHYS_PORT_ID: 265 + ? + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 273 + ? + PORT_ID: 159 + : + PC_PHYS_PORT_ID: 281 + ? + PORT_ID: 174 + : + PC_PHYS_PORT_ID: 289 + ? + PORT_ID: 175 + : + PC_PHYS_PORT_ID: 297 + ? + PORT_ID: 176 + : + PC_PHYS_PORT_ID: 305 + ? + PORT_ID: 177 + : + PC_PHYS_PORT_ID: 313 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 192 + : + PC_PHYS_PORT_ID: 321 + ? + PORT_ID: 193 + : + PC_PHYS_PORT_ID: 329 + ? + PORT_ID: 194 + : + PC_PHYS_PORT_ID: 337 + ? + PORT_ID: 195 + : + PC_PHYS_PORT_ID: 345 + ? + PORT_ID: 210 + : + PC_PHYS_PORT_ID: 353 + ? + PORT_ID: 211 + : + PC_PHYS_PORT_ID: 361 + ? + PORT_ID: 212 + : + PC_PHYS_PORT_ID: 369 + ? + PORT_ID: 213 + : + PC_PHYS_PORT_ID: 377 + ? + PORT_ID: 228 + : + PC_PHYS_PORT_ID: 385 + ? + PORT_ID: 31 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 229 + : + PC_PHYS_PORT_ID: 393 + ? + PORT_ID: 230 + : + PC_PHYS_PORT_ID: 401 + ? + PORT_ID: 231 + : + PC_PHYS_PORT_ID: 409 + ? + PORT_ID: 246 + : + PC_PHYS_PORT_ID: 417 + ? + PORT_ID: 247 + : + PC_PHYS_PORT_ID: 425 + ? + PORT_ID: 248 + : + PC_PHYS_PORT_ID: 433 + ? + PORT_ID: 249 + : + PC_PHYS_PORT_ID: 441 + ? + PORT_ID: 264 + : + PC_PHYS_PORT_ID: 449 + ? + PORT_ID: 265 + : + PC_PHYS_PORT_ID: 457 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 266 + : + PC_PHYS_PORT_ID: 465 + ? + PORT_ID: 267 + : + PC_PHYS_PORT_ID: 473 + ? + PORT_ID: 282 + : + PC_PHYS_PORT_ID: 481 + ? + PORT_ID: 283 + : + PC_PHYS_PORT_ID: 489 + ? + PORT_ID: 284 + : + PC_PHYS_PORT_ID: 497 + ? + PORT_ID: 285 + : + PC_PHYS_PORT_ID: 505 + ? + PORT_ID: 300 + : + PC_PHYS_PORT_ID: 513 + ? + PORT_ID: 301 + : + PC_PHYS_PORT_ID: 521 + ? + PORT_ID: 302 + : + PC_PHYS_PORT_ID: 529 + ? + PORT_ID: 33 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 303 + : + PC_PHYS_PORT_ID: 537 + ? + PORT_ID: 318 + : + PC_PHYS_PORT_ID: 545 + ? + PORT_ID: 319 + : + PC_PHYS_PORT_ID: 553 + ? + PORT_ID: 320 + : + PC_PHYS_PORT_ID: 561 + ? + PORT_ID: 321 + : + PC_PHYS_PORT_ID: 569 + ? + PORT_ID: 336 + : + PC_PHYS_PORT_ID: 577 + ? + PORT_ID: 337 + : + PC_PHYS_PORT_ID: 585 + ? + PORT_ID: 338 + : + PC_PHYS_PORT_ID: 593 + ? + PORT_ID: 339 + : + PC_PHYS_PORT_ID: 601 + ? + PORT_ID: 354 + : + PC_PHYS_PORT_ID: 609 + ? + PORT_ID: 355 + : + PC_PHYS_PORT_ID: 617 + ? + PORT_ID: 356 + : + PC_PHYS_PORT_ID: 625 + ? + PORT_ID: 357 + : + PC_PHYS_PORT_ID: 633 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 372 + : + PC_PHYS_PORT_ID: 641 + ? + PORT_ID: 373 + : + PC_PHYS_PORT_ID: 649 + ? + PORT_ID: 374 + : + PC_PHYS_PORT_ID: 657 + ? + PORT_ID: 375 + : + PC_PHYS_PORT_ID: 665 + ? + PORT_ID: 390 + : + PC_PHYS_PORT_ID: 673 + ? + PORT_ID: 391 + : + PC_PHYS_PORT_ID: 681 + ? + PORT_ID: 392 + : + PC_PHYS_PORT_ID: 689 + ? + PORT_ID: 393 + : + PC_PHYS_PORT_ID: 697 + ? + PORT_ID: 408 + : + PC_PHYS_PORT_ID: 705 + ? + PORT_ID: 49 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 409 + : + PC_PHYS_PORT_ID: 713 + ? + PORT_ID: 410 + : + PC_PHYS_PORT_ID: 721 + ? + PORT_ID: 411 + : + PC_PHYS_PORT_ID: 729 + ? + PORT_ID: 426 + : + PC_PHYS_PORT_ID: 737 + ? + PORT_ID: 427 + : + PC_PHYS_PORT_ID: 745 + ? + PORT_ID: 428 + : + PC_PHYS_PORT_ID: 753 + ? + PORT_ID: 429 + : + PC_PHYS_PORT_ID: 761 + ? + PORT_ID: 444 + : + PC_PHYS_PORT_ID: 769 + ? + PORT_ID: 445 + : + PC_PHYS_PORT_ID: 777 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 446 + : + PC_PHYS_PORT_ID: 785 + ? + PORT_ID: 447 + : + PC_PHYS_PORT_ID: 793 + ? + PORT_ID: 462 + : + PC_PHYS_PORT_ID: 801 + ? + PORT_ID: 463 + : + PC_PHYS_PORT_ID: 809 + ? + PORT_ID: 464 + : + PC_PHYS_PORT_ID: 817 + ? + PORT_ID: 465 + : + PC_PHYS_PORT_ID: 825 + ? + PORT_ID: 480 + : + PC_PHYS_PORT_ID: 833 + ? + PORT_ID: 481 + : + PC_PHYS_PORT_ID: 841 + ? + PORT_ID: 482 + : + PC_PHYS_PORT_ID: 849 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 483 + : + PC_PHYS_PORT_ID: 857 + ? + PORT_ID: 498 + : + PC_PHYS_PORT_ID: 865 + ? + PORT_ID: 499 + : + PC_PHYS_PORT_ID: 873 + ? + PORT_ID: 500 + : + PC_PHYS_PORT_ID: 881 + ? + PORT_ID: 501 + : + PC_PHYS_PORT_ID: 889 + ? + PORT_ID: 14 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 516 + : + PC_PHYS_PORT_ID: 897 + ? + PORT_ID: 517 + : + PC_PHYS_PORT_ID: 905 + ? + PORT_ID: 518 + : + PC_PHYS_PORT_ID: 913 + ? + PORT_ID: 519 + : + PC_PHYS_PORT_ID: 921 + ? + PORT_ID: 534 + : + PC_PHYS_PORT_ID: 929 + ? + PORT_ID: 535 + : + PC_PHYS_PORT_ID: 937 + ? + PORT_ID: 536 + : + PC_PHYS_PORT_ID: 945 + ? + PORT_ID: 537 + : + PC_PHYS_PORT_ID: 953 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 552 + : + PC_PHYS_PORT_ID: 961 + ? + PORT_ID: 553 + : + PC_PHYS_PORT_ID: 969 + ? + PORT_ID: 554 + : + PC_PHYS_PORT_ID: 977 + ? + PORT_ID: 555 + : + PC_PHYS_PORT_ID: 985 + ? + PORT_ID: 570 + : + PC_PHYS_PORT_ID: 993 + ? + PORT_ID: 571 + : + PC_PHYS_PORT_ID: 1001 + ? + PORT_ID: 572 + : + PC_PHYS_PORT_ID: 1009 + ? + PORT_ID: 573 + : + PC_PHYS_PORT_ID: 1017 + ? + PORT_ID: 67 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 69 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 84 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 85 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 86 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 87 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 102 + : + PC_PHYS_PORT_ID: 161 + ? + PORT_ID: 103 + : + PC_PHYS_PORT_ID: 169 + ? + PORT_ID: 104 + : + PC_PHYS_PORT_ID: 177 + ? + PORT_ID: 268 + : + PC_PHYS_PORT_ID: 1026 + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + ENABLE: 1 + SPEED: 800000 + NUM_LANES: 8 + FEC_MODE: PC_FEC_RS544_2XN_IEEE + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [268] + : + ENABLE: 1 + SPEED: 100000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS528 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 +... + +--- +device: + 0: + PC_PMD_FIRMWARE: + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE + ? + PORT_ID: [268] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + stat_custom_receive0_management_mode: 1 + pktio_mode: 1 + sai_pfc_defaults_disable: 1 + sai_mac_policy_vfp_group: 0 + sai_skip_create_sys_efp_grp: 1 + sai_rdma_udf_disable: 1 + sai_trap_fp_action_drop_copy_to_cpu: 1 + sai_crm_hw_nh_group_cnt: 0 + riot_overlay_l3_intf_mem_size: 4096 + riot_overlay_l3_egress_mem_size: 8192 + l3_ecmp_member_first_lkup_mem_size: 8192 + l3_ecmp_member_secondary_mem_size: 8192 + failover_fixed_nh_offset_enable: 1 + sai_optimized_mmu: 0 + sai_async_fdb_nbr_enable: 1 + bcm_linkscan_interval: 100000 + sai_pfc_dlr_init_capability: 2 + sai_stats_support_mask: 0x804 +... + +--- +device: + 0: + # IFP mode + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... + +--- +bcm_device: + 0: + port: + "*": + encap_mode: IEEE +... diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/default_sku b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/default_sku new file mode 100644 index 0000000000..6f88352d2c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/default_sku @@ -0,0 +1 @@ +M2-W6950-O128 l2 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/hwsku.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/hwsku.json new file mode 100644 index 0000000000..276fda2943 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/hwsku.json @@ -0,0 +1,654 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet136": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet144": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet152": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet160": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet168": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet176": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet184": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet192": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet200": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet208": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet216": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet224": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet232": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet240": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet248": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet256": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet264": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet272": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet280": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet288": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet296": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet304": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet312": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet320": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet328": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet336": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet344": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet352": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet360": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet368": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet376": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet384": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet392": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet400": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet408": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet416": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet424": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet432": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet440": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet448": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet456": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet464": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet472": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet480": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet488": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet496": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet504": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet512": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet520": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet528": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet536": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet544": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet552": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet560": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet568": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet576": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet584": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet592": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet600": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet608": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet616": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet624": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet632": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet640": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet648": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet656": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet664": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet672": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet680": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet688": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet696": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet704": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet712": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet720": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet728": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet736": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet744": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet752": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet760": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet768": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet776": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet784": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet792": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet800": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet808": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet816": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet824": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet832": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet840": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet848": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet856": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet864": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet872": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet880": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet888": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet896": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet904": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet912": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet920": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet928": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet936": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet944": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet952": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet960": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet968": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet976": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet984": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet992": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1000": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1008": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1016": { + "default_brkout_mode": "1x800G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1024": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1025": { + "default_brkout_mode": "1x1G", + "autoneg": "off", + "fec": "none" + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/media_settings.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/media_settings.json new file mode 100644 index 0000000000..d745a055bc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/media_settings.json @@ -0,0 +1,8196 @@ +{ + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "2": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "3": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "4": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "5": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "6": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "7": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "8": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "9": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000088", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "10": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "11": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000088", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "12": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000088", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "13": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000088", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000088", + "lane6": "0x00000084", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "14": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "15": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000088", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "16": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000088", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "17": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000088", + "lane2": "0x00000084", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "18": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "19": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000084", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "20": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000088", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "21": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000084", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "22": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000084", + "lane5": "0x00000088", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "23": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "24": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "25": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "26": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "27": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "28": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "29": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "30": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "31": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "32": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "33": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "34": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "35": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "36": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000006", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "37": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0xfffffffc", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "38": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "39": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "40": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "41": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0x00000000", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "42": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "43": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "44": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "45": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "46": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "47": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "48": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000006", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000006", + "lane4": "0x00000006", + "lane5": "0x00000006", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "49": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000006", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000006", + "lane4": "0x00000006", + "lane5": "0x00000006", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe0", + "lane2": "0xffffffec", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "50": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000006", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000006", + "lane4": "0x00000006", + "lane5": "0x00000006", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe8", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "51": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffe0", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "52": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "53": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "54": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "55": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "56": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "57": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "58": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "59": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "60": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "61": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "62": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "63": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0x00000000", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "64": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "65": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "66": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "67": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "68": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "69": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "70": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000080", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "71": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0xfffffffc", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "72": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "73": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "74": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "75": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "76": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "77": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000006", + "lane4": "0x00000004", + "lane5": "0x00000006", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffe8", + "lane4": "0xffffffec", + "lane5": "0xffffffe8", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "78": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000006", + "lane4": "0x00000006", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "79": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000006", + "lane4": "0x00000006", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "80": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000006", + "lane4": "0x00000004", + "lane5": "0x00000006", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe0", + "lane5": "0xffffffe8", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "81": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000006", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000006", + "lane4": "0x00000006", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe8", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "82": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000006", + "lane3": "0x00000006", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000006" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe8", + "lane3": "0xffffffe8", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "83": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000006", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffe0", + "lane2": "0xffffffec", + "lane3": "0xffffffe8", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "84": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000006", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe8", + "lane1": "0xffffffe0", + "lane2": "0xffffffec", + "lane3": "0xffffffe0", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffe0", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "85": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "86": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0xfffffffc", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "87": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000084", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "88": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000084", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "89": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "90": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "91": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088", + "lane4": "0x00000088", + "lane5": "0x00000088", + "lane6": "0x00000088", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "92": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000088", + "lane2": "0x00000084", + "lane3": "0x00000088", + "lane4": "0x00000084", + "lane5": "0x00000088", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "93": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "94": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "95": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "96": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "97": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "98": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "99": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "100": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "101": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "102": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "103": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "104": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "105": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "106": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000080" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "107": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "108": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000080", + "lane3": "0x00000084", + "lane4": "0x00000080", + "lane5": "0x00000084", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "109": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000080", + "lane5": "0x00000084", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "110": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000080", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "111": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000080", + "lane3": "0x00000080", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "112": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000080", + "lane2": "0x00000080", + "lane3": "0x00000084", + "lane4": "0x00000080", + "lane5": "0x00000080", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "113": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "114": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000080", + "lane3": "0x00000080", + "lane4": "0x00000080", + "lane5": "0x00000080", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc", + "lane4": "0xfffffffc", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "115": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "116": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe0", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000084", + "lane2": "0x00000080", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0xfffffffc", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "117": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "118": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "119": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000080", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0xfffffffc", + "lane2": "0x00000000", + "lane3": "0xfffffffc", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "120": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "121": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "122": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "123": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "124": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "125": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "126": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000080", + "lane2": "0x00000080", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000080", + "lane6": "0x00000080", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0xfffffffc", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0xfffffffc", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "127": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "128": { + "Default": { + "pre3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre2": { + "lane0": "0x00000004", + "lane1": "0x00000004", + "lane2": "0x00000004", + "lane3": "0x00000004", + "lane4": "0x00000004", + "lane5": "0x00000004", + "lane6": "0x00000004", + "lane7": "0x00000004" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe0", + "lane3": "0xffffffe4", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000080", + "lane1": "0x00000080", + "lane2": "0x00000084", + "lane3": "0x00000080", + "lane4": "0x00000084", + "lane5": "0x00000084", + "lane6": "0x00000084", + "lane7": "0x00000084" + }, + "post1": { + "lane0": "0x00000000", + "lane1": "0xfffffffc", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/port_config.ini b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/port_config.ini new file mode 100644 index 0000000000..6b950df1d2 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/port_config.ini @@ -0,0 +1,131 @@ +# name lanes alias index speed +Ethernet0 265,266,267,268,269,270,271,272 etp1 1 800000 +Ethernet8 297,298,299,300,301,302,303,304 etp2 2 800000 +Ethernet16 305,306,307,308,309,310,311,312 etp3 3 800000 +Ethernet24 313,314,315,316,317,318,319,320 etp4 4 800000 +Ethernet32 377,378,379,380,381,382,383,384 etp5 5 800000 +Ethernet40 369,370,371,372,373,374,375,376 etp6 6 800000 +Ethernet48 361,362,363,364,365,366,367,368 etp7 7 800000 +Ethernet56 329,330,331,332,333,334,335,336 etp8 8 800000 +Ethernet64 505,506,507,508,509,510,511,512 etp9 9 800000 +Ethernet72 497,498,499,500,501,502,503,504 etp10 10 800000 +Ethernet80 489,490,491,492,493,494,495,496 etp11 11 800000 +Ethernet88 457,458,459,460,461,462,463,464 etp12 12 800000 +Ethernet96 449,450,451,452,453,454,455,456 etp13 13 800000 +Ethernet104 465,466,467,468,469,470,471,472 etp14 14 800000 +Ethernet112 481,482,483,484,485,486,487,488 etp15 15 800000 +Ethernet120 473,474,475,476,477,478,479,480 etp16 16 800000 +Ethernet128 537,538,539,540,541,542,543,544 etp17 17 800000 +Ethernet136 545,546,547,548,549,550,551,552 etp18 18 800000 +Ethernet144 529,530,531,532,533,534,535,536 etp19 19 800000 +Ethernet152 513,514,515,516,517,518,519,520 etp20 20 800000 +Ethernet160 521,522,523,524,525,526,527,528 etp21 21 800000 +Ethernet168 553,554,555,556,557,558,559,560 etp22 22 800000 +Ethernet176 561,562,563,564,565,566,567,568 etp23 23 800000 +Ethernet184 569,570,571,572,573,574,575,576 etp24 24 800000 +Ethernet192 649,650,651,652,653,654,655,656 etp25 25 800000 +Ethernet200 681,682,683,684,685,686,687,688 etp26 26 800000 +Ethernet208 689,690,691,692,693,694,695,696 etp27 27 800000 +Ethernet216 697,698,699,700,701,702,703,704 etp28 28 800000 +Ethernet224 761,762,763,764,765,766,767,768 etp29 29 800000 +Ethernet232 753,754,755,756,757,758,759,760 etp30 30 800000 +Ethernet240 713,714,715,716,717,718,719,720 etp31 31 800000 +Ethernet248 745,746,747,748,749,750,751,752 etp32 32 800000 +Ethernet256 33,34,35,36,37,38,39,40 etp33 33 800000 +Ethernet264 1,2,3,4,5,6,7,8 etp34 34 800000 +Ethernet272 41,42,43,44,45,46,47,48 etp35 35 800000 +Ethernet280 57,58,59,60,61,62,63,64 etp36 36 800000 +Ethernet288 121,122,123,124,125,126,127,128 etp37 37 800000 +Ethernet296 105,106,107,108,109,110,111,112 etp38 38 800000 +Ethernet304 65,66,67,68,69,70,71,72 etp39 39 800000 +Ethernet312 97,98,99,100,101,102,103,104 etp40 40 800000 +Ethernet320 153,154,155,156,157,158,159,160 etp41 41 800000 +Ethernet328 145,146,147,148,149,150,151,152 etp42 42 800000 +Ethernet336 321,322,323,324,325,326,327,328 etp43 43 800000 +Ethernet344 353,354,355,356,357,358,359,360 etp44 44 800000 +Ethernet352 409,410,411,412,413,414,415,416 etp45 45 800000 +Ethernet360 401,402,403,404,405,406,407,408 etp46 46 800000 +Ethernet368 393,394,395,396,397,398,399,400 etp47 47 800000 +Ethernet376 433,434,435,436,437,438,439,440 etp48 48 800000 +Ethernet384 585,586,587,588,589,590,591,592 etp49 49 800000 +Ethernet392 625,626,627,628,629,630,631,632 etp50 50 800000 +Ethernet400 601,602,603,604,605,606,607,608 etp51 51 800000 +Ethernet408 593,594,595,596,597,598,599,600 etp52 52 800000 +Ethernet416 641,642,643,644,645,646,647,648 etp53 53 800000 +Ethernet424 673,674,675,676,677,678,679,680 etp54 54 800000 +Ethernet432 857,858,859,860,861,862,863,864 etp55 55 800000 +Ethernet440 849,850,851,852,853,854,855,856 etp56 56 800000 +Ethernet448 897,898,899,900,901,902,903,904 etp57 57 800000 +Ethernet456 929,930,931,932,933,934,935,936 etp58 58 800000 +Ethernet464 953,954,955,956,957,958,959,960 etp59 59 800000 +Ethernet472 937,938,939,940,941,942,943,944 etp60 60 800000 +Ethernet480 1001,1002,1003,1004,1005,1006,1007,1008 etp61 61 800000 +Ethernet488 1017,1018,1019,1020,1021,1022,1023,1024 etp62 62 800000 +Ethernet496 993,994,995,996,997,998,999,1000 etp63 63 800000 +Ethernet504 961,962,963,964,965,966,967,968 etp64 64 800000 +Ethernet512 17,18,19,20,21,22,23,24 etp65 65 800000 +Ethernet520 25,26,27,28,29,30,31,32 etp66 66 800000 +Ethernet528 49,50,51,52,53,54,55,56 etp67 67 800000 +Ethernet536 9,10,11,12,13,14,15,16 etp68 68 800000 +Ethernet544 73,74,75,76,77,78,79,80 etp69 69 800000 +Ethernet552 113,114,115,116,117,118,119,120 etp70 70 800000 +Ethernet560 89,90,91,92,93,94,95,96 etp71 71 800000 +Ethernet568 81,82,83,84,85,86,87,88 etp72 72 800000 +Ethernet576 129,130,131,132,133,134,135,136 etp73 73 800000 +Ethernet584 161,162,163,164,165,166,167,168 etp74 74 800000 +Ethernet592 345,346,347,348,349,350,351,352 etp75 75 800000 +Ethernet600 337,338,339,340,341,342,343,344 etp76 76 800000 +Ethernet608 385,386,387,388,389,390,391,392 etp77 77 800000 +Ethernet616 417,418,419,420,421,422,423,424 etp78 78 800000 +Ethernet624 441,442,443,444,445,446,447,448 etp79 79 800000 +Ethernet632 425,426,427,428,429,430,431,432 etp80 80 800000 +Ethernet640 633,634,635,636,637,638,639,640 etp81 81 800000 +Ethernet648 617,618,619,620,621,622,623,624 etp82 82 800000 +Ethernet656 577,578,579,580,581,582,583,584 etp83 83 800000 +Ethernet664 609,610,611,612,613,614,615,616 etp84 84 800000 +Ethernet672 665,666,667,668,669,670,671,672 etp85 85 800000 +Ethernet680 657,658,659,660,661,662,663,664 etp86 86 800000 +Ethernet688 833,834,835,836,837,838,839,840 etp87 87 800000 +Ethernet696 865,866,867,868,869,870,871,872 etp88 88 800000 +Ethernet704 921,922,923,924,925,926,927,928 etp89 89 800000 +Ethernet712 913,914,915,916,917,918,919,920 etp90 90 800000 +Ethernet720 905,906,907,908,909,910,911,912 etp91 91 800000 +Ethernet728 945,946,947,948,949,950,951,952 etp92 92 800000 +Ethernet736 1009,1010,1011,1012,1013,1014,1015,1016 etp93 93 800000 +Ethernet744 969,970,971,972,973,974,975,976 etp94 94 800000 +Ethernet752 977,978,979,980,981,982,983,984 etp95 95 800000 +Ethernet760 985,986,987,988,989,990,991,992 etp96 96 800000 +Ethernet768 209,210,211,212,213,214,215,216 etp97 97 800000 +Ethernet776 193,194,195,196,197,198,199,200 etp98 98 800000 +Ethernet784 225,226,227,228,229,230,231,232 etp99 99 800000 +Ethernet792 217,218,219,220,221,222,223,224 etp100 100 800000 +Ethernet800 281,282,283,284,285,286,287,288 etp101 101 800000 +Ethernet808 289,290,291,292,293,294,295,296 etp102 102 800000 +Ethernet816 257,258,259,260,261,262,263,264 etp103 103 800000 +Ethernet824 273,274,275,276,277,278,279,280 etp104 104 800000 +Ethernet832 201,202,203,204,205,206,207,208 etp105 105 800000 +Ethernet840 233,234,235,236,237,238,239,240 etp106 106 800000 +Ethernet848 241,242,243,244,245,246,247,248 etp107 107 800000 +Ethernet856 249,250,251,252,253,254,255,256 etp108 108 800000 +Ethernet864 185,186,187,188,189,190,191,192 etp109 109 800000 +Ethernet872 177,178,179,180,181,182,183,184 etp110 110 800000 +Ethernet880 169,170,171,172,173,174,175,176 etp111 111 800000 +Ethernet888 137,138,139,140,141,142,143,144 etp112 112 800000 +Ethernet896 841,842,843,844,845,846,847,848 etp113 113 800000 +Ethernet904 873,874,875,876,877,878,879,880 etp114 114 800000 +Ethernet912 881,882,883,884,885,886,887,888 etp115 115 800000 +Ethernet920 889,890,891,892,893,894,895,896 etp116 116 800000 +Ethernet928 825,826,827,828,829,830,831,832 etp117 117 800000 +Ethernet936 817,818,819,820,821,822,823,824 etp118 118 800000 +Ethernet944 809,810,811,812,813,814,815,816 etp119 119 800000 +Ethernet952 777,778,779,780,781,782,783,784 etp120 120 800000 +Ethernet960 721,722,723,724,725,726,727,728 etp121 121 800000 +Ethernet968 705,706,707,708,709,710,711,712 etp122 122 800000 +Ethernet976 737,738,739,740,741,742,743,744 etp123 123 800000 +Ethernet984 729,730,731,732,733,734,735,736 etp124 124 800000 +Ethernet992 793,794,795,796,797,798,799,800 etp125 125 800000 +Ethernet1000 801,802,803,804,805,806,807,808 etp126 126 800000 +Ethernet1008 785,786,787,788,789,790,791,792 etp127 127 800000 +Ethernet1016 769,770,771,772,773,774,775,776 etp128 128 800000 +Ethernet1024 1026,1027,1028,1029 etp129 129 100000 +Ethernet1025 0 etp130 130 1000 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sai.profile b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sai.profile new file mode 100644 index 0000000000..79417b3fa0 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th6-m2-w6950-o128-128x800G.config.yml diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sap_bcm_81394.cfg b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sap_bcm_81394.cfg new file mode 100644 index 0000000000..9db307eda1 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/sap_bcm_81394.cfg @@ -0,0 +1,246 @@ +# Configuration file version number. +# The current sap_bcm_81394.c does not read this field; it is compatibility/identification information. +# Modifying it will not affect the initialization process of the 81394 driver. +version=1 + +# ==================== +# Global Initialization Parameters +# ==================== + +# Number of slots on the board. +# sap_aperta_config_init() first reads this value into the global g_slot_num, +# then sap_bcm_platform_init() calls sap_slot_init() for 0 to g_slot_num-1. +# Missing this field will cause configuration initialization to fail directly. +plp_slot_num=1 + +# MDIO access type. The ':1' in the key is not a PHY address, but the mdio_id. +# The code first reads plp_phy_mdio_id:0x30=1, then looks up plp_mdio_accs_type:1. +# The value comes from sap_mdio_type_e: +# 0 = MAC +# 1 = SYSFS +# 2 = SYSFS_CUST +# The current value 2 indicates using the custom sysfs MDIO access path. +plp_mdio_accs_type:1=2 + +# Firmware loading method, saved to the global g_fw_load_method. +# The definitions in the 81394 driver are: +# 0 = Do not load +# 1 = Unicast load +# 2 = Broadcast load +# 3 = EEPROM load +# 4 = upgrade path +# 5 = skip +# 6 = full process +# The current value 1 means downloading firmware to each PHY via unicast. +plp_fw_load_method=1 + +# Enable or disable I2C slave. +# The code reads this into g_i2c_slave_en, but in the current main flow of the 81394, +# the corresponding register write logic is completely commented out. +# Therefore, this value is currently a "parsed but not effective by default" field. +plp_i2c_slave_en=0 + +# AVS I2C response address. +# This is also read into g_avs_i2c_resp_addr and used by sap_bcm_avs_init() to assemble register values. +# However, AVS initialization is not actually enabled in the current boot path, so this is just a reserved configuration. +avs_i2c_resp_addr=0x35 + +# Default enable/disable link training for the port's system side. +# If there is no per-port configuration for init_linktrain_sys, each port inherits this global value. +# In sap_aperta_post_port_init(), it calls sap_bcm_linktraining_set(..., true) only if the value is 1. +# 0 means do not automatically enable LT. +plp_port_linktrain_sys=0 + +# Default enable/disable link training for the port's line side. +# The semantics are the same as plp_port_linktrain_sys, applying to the line side. +plp_port_linktrain_line=0 + +# ==================== +# Profile 1 VCO Presets +# ==================== + +# VCO selection for Profile 1, octal 0, system side. +# The 81394 code forcibly reads this and saves it to phy_info->vco_octal_0_sys. +# Confirmed from public headers: +# 0 = bcmplpVco51G +# 1 = bcmplpVco53G +# The current value 1 means 53G VCO. +# Note: In this version of the 81394 implementation, this value is read but not used further in mode_config_set. +# It seems more like a field retained to share the configuration format with other chips in the family. +plp_profile_1_init_vco_octal_0_sys=1 + +# VCO selection for Profile 1, octal 0, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_0_line=1 + +# VCO selection for Profile 1, octal 1, system side. +# The current board type uses only one PHY at address 0x30 and the profile uses lanes=0,1, +# but the code still requires the VCO for octal 1 to be configured, otherwise configuration parsing fails. +plp_profile_1_init_vco_octal_1_sys=1 + +# VCO selection for Profile 1, octal 1, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_1_line=1 + +# ==================== +# Profile 1: 100G, split=1, Single port with 4 lanes +# Key format: plp_profile__speed__split_.: +# This is changed to a single 100G port, hence split_num=1, port_id=0. +# +# In the 81394 code, split_num is not hardcoded, but calculated by: +# phy_info->lane_num / port_info->lanes +# Therefore, to target split_1.0, the init_lanes below needs to provide 4 lane entries, +# and init_ports_lane_num must be configured as 4, indicating a 4-lane aggregated port. +# ==================== + +# FEC mode for the line side. +# For the 100G 4x25G scenario, the semantics from the original file are retained, where 3 = RSFEC. +# This still uses the 25.78125G/lane NRZ path, not 2x50G PAM4. +plp_profile_1_speed_100000_split_1.0:fec_line=3 + +# FEC mode for the system side. +# Consistent with the line side, configured as 3 = RSFEC. +plp_profile_1_speed_100000_split_1.0:fec_sys=3 + +# Interface type for the line side. +# In bcm_pm_interface_t, 7 = bcm_pm_InterfaceKR4. +# This is changed from the single-lane KR to 4-lane KR4, matching the 100G 4-lane port form factor. +plp_profile_1_speed_100000_split_1.0:iftype_line=7 + +# Interface type for the system side. +# Also changed to 7 = KR4, maintaining the lane count and interface width consistency between system/line sides. +plp_profile_1_speed_100000_split_1.0:iftype_sys=7 + +# Line side lane bitmask. +# 0xF = 0000 1111b, indicating selection of 4 consecutive lanes. +# With speed=100000, the code calculates the per-lane speed as 25.78125G. +plp_profile_1_speed_100000_split_1.0:lanemap_line=0xF + +# System side lane bitmask. +# Same as the line side, indicating a 4-lane passthrough port, not a gearbox/reverse-gearbox. +plp_profile_1_speed_100000_split_1.0:lanemap_sys=0xF + +# Force NR (No Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_sys=0x0 + +# Force NR (No Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_line=0x0 + +# Force ER (Eye Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_sys=0x0 + +# Force ER (Eye Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_line=0x0 + + +# ==================== +# PHY List +# ==================== + +# List of PHY addresses to initialize. +# sap_aperta_config_init() generates g_bcm_phy_infos based on this array. +# Currently, there is only one PHY at address 0x30. +plp_phy_addrs=0x30 + +# ==================== +# PHY 0x30 Base Attributes +# PHY address resolution method: +# bus_id = (phy_addr & 0x7c00)>>10; +# mdio_index = (phy_addr & 0x3e0)>>5; +# phy_addr = phy_addr & 0x1f; +# return dfd_utest_mdiodev_rd(mdio_index+bus_id, phy_addr, reg_addr, data); +# ==================== + +# The unit to which the PHY is bound. +# sap_slot_init() filters by unit and card_id to determine if this PHY should be initialized in the current round. +plp_phy_unit_id:0x30=0 + +# The card/slot number the PHY belongs to. +# The PHY is initialized only when this matches the outer slot_id. +plp_phy_card_id:0x30=0 + +# The mdio_id used by this PHY. +# The code will then use this mdio_id to look up plp_mdio_accs_type:. +plp_phy_mdio_id:0x30=1 + +# PHY chip name. +# For this version of the 81394 code, this is a compatibility field, as the chip_name is hardcoded to "aperta" in the source. +# Modifying it will not change the chip name used by the driver. +plp_phy_chip_name:0x30=aperta + +# MACsec option. +# The current 81394 file only reads and saves this to phy_info->macsec_option, with no subsequent use observed. +# Therefore, this is more of a reserved field. +plp_phy_macsec_option:0x30=0x0 + +# PTP option. +# Similar to macsec_option, currently only parsed and saved, not consumed in the main 81394 flow. +plp_phy_ptp_option:0x30=0x0 + +# The initialization profile ID used by this PHY. +# The '1' in all subsequent plp_profile_1_* key names is determined by this value. +plp_phy_init_profile_id:0x30=1 + +# The lane list for this PHY under Profile 1. +# This is changed to 0,1,2,3. This does not mean 4 independent logical ports, +# but rather to make phy_info->lane_num = 4, causing the code to calculate split_num = 1. +# The number of logical ports actually created is still determined by the next line, init_ports. +plp_profile_1_init_lanes:0x30=0-3 + +# The list of logical port numbers presented externally by this PHY under Profile 1. +# Changed to create only one logical port, port 1, to carry the 1x100G module. +plp_profile_1_init_ports:0x30=1 + +# The number of lanes occupied by each logical port under Profile 1. +# Changed to a single port occupying 4 lanes. +plp_profile_1_init_ports_lane_num:0x30=4 + +# The initial speed of each logical port under Profile 1. +# Changed to 100000 Mbps for a single port, i.e., 100G. +plp_profile_1_init_speed_mode:0x30=100000 + +# ==================== +# PHY 0x30 Global Lane Swap and Polarity Configuration +# These keys apply to the entire PHY, not a single port. +# ==================== + +# System side TX lane mapping. +# This value is parsed as 8 nibbles, lane by lane. +# lane_map_tx[lane_index] = GET_LANE_SWAP_OCTAL(value, lane_index). +# 0x76543210 represents logical 0->0, 1->1, 2->2... 7->7, which is an identity mapping. +plp_phy_tx_lane_map_sys:0x30=0x76543210 + +# System side RX lane mapping. +# Currently also an identity mapping. +plp_phy_rx_lane_map_sys:0x30=0x76543210 + +# Line side TX lane mapping. +# 0x76543120 indicates a lane swap on the line side, no longer a direct passthrough. +# The code calls bcm_plp_rxtx_laneswap_set() in sap_aperta_phy_init() to apply this. +plp_phy_tx_lane_map_line:0x30=0x76542301 + +# Line side RX lane mapping. +# Currently the same as TX, indicating that RX/TX both follow the same line-side swapping rules. +plp_phy_rx_lane_map_line:0x30=0x76542301 + +# Line side TX polarity flip bitmap. +# In sap_aperta_phy_init(), the current polarity is read, XORed with this value, and then written back. +# Therefore, a bit=1 means flip the polarity for the corresponding lane; 0 means leave it unchanged. +# The current 0x0 means no polarity flip on the line side TX. +plp_tx_polarity_flip_line:0x30=0x0 + +# Line side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the line side RX. +plp_rx_polarity_flip_line:0x30=0xF + +# System side TX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side TX. +plp_tx_polarity_flip_sys:0x30=0x0 + +# System side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side RX. +plp_rx_polarity_flip_sys:0x30=0x0 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/th6-m2-w6950-o128-128x800G.config.yml b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/th6-m2-w6950-o128-128x800G.config.yml new file mode 100644 index 0000000000..2d933f9eb8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-O128/th6-m2-w6950-o128-128x800G.config.yml @@ -0,0 +1,2182 @@ +--- +device: + 0: + DEVICE_CONFIG: + AUTOLOAD_BOARD_SETTINGS: 0 +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12360745 + RX_LANE_MAP: 0x34726150 + TX_POLARITY_FLIP: 0x57 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327140 + RX_LANE_MAP: 0x60317425 + TX_POLARITY_FLIP: 0x99 + RX_POLARITY_FLIP: 0x59 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23145670 + RX_LANE_MAP: 0x57462103 + TX_POLARITY_FLIP: 0x6e + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45726013 + RX_LANE_MAP: 0x12360475 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0x87 + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17204653 + RX_LANE_MAP: 0x54036127 + TX_POLARITY_FLIP: 0x3f + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x14027653 + RX_LANE_MAP: 0x54217036 + TX_POLARITY_FLIP: 0x45 + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26351407 + RX_LANE_MAP: 0x52407163 + TX_POLARITY_FLIP: 0x43 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670321 + RX_LANE_MAP: 0x53274610 + TX_POLARITY_FLIP: 0xad + RX_POLARITY_FLIP: 0xd8 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21705463 + RX_LANE_MAP: 0x46327105 + TX_POLARITY_FLIP: 0x95 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12057463 + RX_LANE_MAP: 0x51740236 + TX_POLARITY_FLIP: 0xc8 + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67105243 + RX_LANE_MAP: 0x40236715 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0x05 + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23164507 + RX_LANE_MAP: 0x45712063 + TX_POLARITY_FLIP: 0xd7 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46570213 + RX_LANE_MAP: 0x71546032 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0x51 + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17453206 + RX_LANE_MAP: 0x61257430 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x64 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327041 + RX_LANE_MAP: 0x50361427 + TX_POLARITY_FLIP: 0xe2 + RX_POLARITY_FLIP: 0xf8 + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x57624301 + TX_POLARITY_FLIP: 0x0d + RX_POLARITY_FLIP: 0xa0 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01374526 + RX_LANE_MAP: 0x64751032 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13024675 + RX_LANE_MAP: 0x61304275 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xa1 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x16452307 + RX_LANE_MAP: 0x50346721 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0xb8 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32604571 + RX_LANE_MAP: 0x67205314 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46120573 + RX_LANE_MAP: 0x13526407 + TX_POLARITY_FLIP: 0x2e + RX_POLARITY_FLIP: 0xf6 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x30412657 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x04 + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13207465 + RX_LANE_MAP: 0x20316475 + TX_POLARITY_FLIP: 0x01 + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x61305274 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23107465 + RX_LANE_MAP: 0x32107654 + TX_POLARITY_FLIP: 0x62 + RX_POLARITY_FLIP: 0x99 + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0xf7 + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x62307145 + TX_POLARITY_FLIP: 0x9d + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x31064752 + RX_LANE_MAP: 0x02135764 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xca + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12357064 + RX_LANE_MAP: 0x03216457 + TX_POLARITY_FLIP: 0x81 + RX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106745 + RX_LANE_MAP: 0x61034275 + TX_POLARITY_FLIP: 0x11 + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32014756 + RX_LANE_MAP: 0x13024576 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02376154 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xd5 + RX_POLARITY_FLIP: 0xef + ? + PC_PM_ID: 33 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x02637154 + TX_POLARITY_FLIP: 0xe7 + RX_POLARITY_FLIP: 0x20 + ? + PC_PM_ID: 34 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0x01 + ? + PC_PM_ID: 35 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02134765 + RX_LANE_MAP: 0x13026745 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0x82 + ? + PC_PM_ID: 36 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23016745 + RX_LANE_MAP: 0x30162745 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xc9 + ? + PC_PM_ID: 37 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30412675 + RX_LANE_MAP: 0x32051674 + TX_POLARITY_FLIP: 0xa7 + RX_POLARITY_FLIP: 0x1b + ? + PC_PM_ID: 38 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x91 + ? + PC_PM_ID: 39 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x01534267 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x29 + ? + PC_PM_ID: 40 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 41 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x46357201 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x3a + ? + PC_PM_ID: 42 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x10325746 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0xee + ? + PC_PM_ID: 43 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65073421 + RX_LANE_MAP: 0x53026714 + TX_POLARITY_FLIP: 0x7e + RX_POLARITY_FLIP: 0xc5 + ? + PC_PM_ID: 44 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21057463 + RX_LANE_MAP: 0x47513260 + TX_POLARITY_FLIP: 0x65 + RX_POLARITY_FLIP: 0x07 + ? + PC_PM_ID: 45 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47061235 + RX_LANE_MAP: 0x41276530 + TX_POLARITY_FLIP: 0x34 + RX_POLARITY_FLIP: 0xf1 + ? + PC_PM_ID: 46 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x01437265 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 47 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x13607254 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x44 + ? + PC_PM_ID: 48 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x13025476 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 49 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70152643 + RX_LANE_MAP: 0x76512043 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 50 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x04635271 + RX_LANE_MAP: 0x67235014 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x25 + ? + PC_PM_ID: 51 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x76540213 + RX_LANE_MAP: 0x51376240 + TX_POLARITY_FLIP: 0xf1 + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 52 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12375460 + RX_LANE_MAP: 0x54261037 + TX_POLARITY_FLIP: 0xe1 + RX_POLARITY_FLIP: 0x0f + ? + PC_PM_ID: 53 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64301572 + RX_LANE_MAP: 0x63107425 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 54 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45213670 + RX_LANE_MAP: 0x41062537 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 55 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25461073 + RX_LANE_MAP: 0x73215640 + TX_POLARITY_FLIP: 0xec + RX_POLARITY_FLIP: 0x0e + ? + PC_PM_ID: 56 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30264571 + RX_LANE_MAP: 0x67452031 + TX_POLARITY_FLIP: 0x38 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 57 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 58 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 59 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x23017654 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x96 + ? + PC_PM_ID: 60 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x33 + ? + PC_PM_ID: 61 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x02341675 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0xc7 + ? + PC_PM_ID: 62 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x23106754 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x26 + ? + PC_PM_ID: 63 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36170254 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x73 + ? + PC_PM_ID: 64 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xd0 + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 65 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0x7a + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 66 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x13 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 67 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x32106745 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x96 + ? + PC_PM_ID: 68 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0xa3 + RX_POLARITY_FLIP: 0xcc + ? + PC_PM_ID: 69 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x20436157 + TX_POLARITY_FLIP: 0xd3 + RX_POLARITY_FLIP: 0x34 + ? + PC_PM_ID: 70 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x32017645 + TX_POLARITY_FLIP: 0x63 + RX_POLARITY_FLIP: 0xe6 + ? + PC_PM_ID: 71 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63712045 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x4c + ? + PC_PM_ID: 72 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x23 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 73 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13762540 + RX_LANE_MAP: 0x51764320 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 74 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x62135470 + RX_LANE_MAP: 0x64025317 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xea + ? + PC_PM_ID: 75 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54761302 + RX_LANE_MAP: 0x50326741 + TX_POLARITY_FLIP: 0x0b + RX_POLARITY_FLIP: 0x7e + ? + PC_PM_ID: 76 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x34075261 + RX_LANE_MAP: 0x57021634 + TX_POLARITY_FLIP: 0x5a + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 77 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75201463 + RX_LANE_MAP: 0x70126435 + TX_POLARITY_FLIP: 0xe4 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 78 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67013542 + RX_LANE_MAP: 0x26034517 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 79 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46257310 + RX_LANE_MAP: 0x70265143 + TX_POLARITY_FLIP: 0x4c + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 80 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21354670 + RX_LANE_MAP: 0x45673120 + TX_POLARITY_FLIP: 0xab + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 81 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41237506 + TX_POLARITY_FLIP: 0x80 + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 82 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x01237564 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0xdd + ? + PC_PM_ID: 83 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x24173560 + RX_LANE_MAP: 0x62015734 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 84 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03247561 + RX_LANE_MAP: 0x51476032 + TX_POLARITY_FLIP: 0xf6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 85 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06473512 + RX_LANE_MAP: 0x40256731 + TX_POLARITY_FLIP: 0x3e + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 86 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x10342756 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0xc9 + ? + PC_PM_ID: 87 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x31062745 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 88 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x31204567 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0xcd + ? + PC_PM_ID: 89 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64751302 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0xfb + ? + PC_PM_ID: 90 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0x02 + ? + PC_PM_ID: 91 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65471302 + RX_LANE_MAP: 0x54762031 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0xbe + ? + PC_PM_ID: 92 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670123 + RX_LANE_MAP: 0x54726103 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0x6c + ? + PC_PM_ID: 93 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75264130 + RX_LANE_MAP: 0x47615023 + TX_POLARITY_FLIP: 0x25 + RX_POLARITY_FLIP: 0x27 + ? + PC_PM_ID: 94 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x91 + ? + PC_PM_ID: 95 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x10352476 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x16 + ? + PC_PM_ID: 96 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x42 + ? + PC_PM_ID: 97 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65741023 + RX_LANE_MAP: 0x45670123 + TX_POLARITY_FLIP: 0x76 + RX_POLARITY_FLIP: 0x66 + ? + PC_PM_ID: 98 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0x84 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 99 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x45713062 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 100 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52470631 + RX_LANE_MAP: 0x46753120 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xac + ? + PC_PM_ID: 101 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64703512 + RX_LANE_MAP: 0x75461230 + TX_POLARITY_FLIP: 0xbd + RX_POLARITY_FLIP: 0x3b + ? + PC_PM_ID: 102 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45671032 + RX_LANE_MAP: 0x57243016 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0x9c + ? + PC_PM_ID: 103 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56470132 + RX_LANE_MAP: 0x67542031 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x8c + ? + PC_PM_ID: 104 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54613702 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0xa8 + RX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 105 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36054721 + RX_LANE_MAP: 0x75643210 + TX_POLARITY_FLIP: 0xb7 + RX_POLARITY_FLIP: 0xb9 + ? + PC_PM_ID: 106 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75642031 + RX_LANE_MAP: 0x57240316 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x7a + ? + PC_PM_ID: 107 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45160723 + RX_LANE_MAP: 0x51376420 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x43 + ? + PC_PM_ID: 108 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65104273 + RX_LANE_MAP: 0x64325017 + TX_POLARITY_FLIP: 0xc9 + RX_POLARITY_FLIP: 0x1b + ? + PC_PM_ID: 109 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75320641 + RX_LANE_MAP: 0x62501437 + TX_POLARITY_FLIP: 0xd1 + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 110 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x75621403 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xdf + ? + PC_PM_ID: 111 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65742013 + RX_LANE_MAP: 0x57461302 + TX_POLARITY_FLIP: 0xbf + RX_POLARITY_FLIP: 0xe3 + ? + PC_PM_ID: 112 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x47250316 + TX_POLARITY_FLIP: 0xf9 + RX_POLARITY_FLIP: 0xee + ? + PC_PM_ID: 113 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74305162 + RX_LANE_MAP: 0x75014236 + TX_POLARITY_FLIP: 0x8e + RX_POLARITY_FLIP: 0x01 + ? + PC_PM_ID: 114 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03147562 + RX_LANE_MAP: 0x74513602 + TX_POLARITY_FLIP: 0x0e + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 115 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x42305761 + RX_LANE_MAP: 0x63214705 + TX_POLARITY_FLIP: 0x08 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 116 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17254603 + RX_LANE_MAP: 0x71456320 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 117 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x57461302 + RX_LANE_MAP: 0x72506431 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 118 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45170632 + RX_LANE_MAP: 0x60247531 + TX_POLARITY_FLIP: 0x55 + RX_POLARITY_FLIP: 0xde + ? + PC_PM_ID: 119 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x40127653 + RX_LANE_MAP: 0x16325407 + TX_POLARITY_FLIP: 0x9f + RX_POLARITY_FLIP: 0x15 + ? + PC_PM_ID: 120 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41035267 + TX_POLARITY_FLIP: 0x97 + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 121 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124507 + RX_LANE_MAP: 0x30716254 + TX_POLARITY_FLIP: 0xa2 + RX_POLARITY_FLIP: 0x83 + ? + PC_PM_ID: 122 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x41027653 + RX_LANE_MAP: 0x71326405 + TX_POLARITY_FLIP: 0x22 + RX_POLARITY_FLIP: 0x3c + ? + PC_PM_ID: 123 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10265473 + RX_LANE_MAP: 0x46570321 + TX_POLARITY_FLIP: 0xbc + RX_POLARITY_FLIP: 0xb9 + ? + PC_PM_ID: 124 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10327546 + RX_LANE_MAP: 0x06371425 + TX_POLARITY_FLIP: 0x44 + RX_POLARITY_FLIP: 0xe2 + ? + PC_PM_ID: 125 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26304751 + RX_LANE_MAP: 0x67215304 + TX_POLARITY_FLIP: 0x05 + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 126 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06327451 + RX_LANE_MAP: 0x76305124 + TX_POLARITY_FLIP: 0x9b + RX_POLARITY_FLIP: 0x64 + ? + PC_PM_ID: 127 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37241506 + RX_LANE_MAP: 0x40526371 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0xbf + ? + PC_PM_ID: 128 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67452103 + RX_LANE_MAP: 0x50264713 + TX_POLARITY_FLIP: 0x58 + RX_POLARITY_FLIP: 0x62 + ? + PC_PM_ID: 129 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x0123 + RX_LANE_MAP: 0x0123 + TX_POLARITY_FLIP: 0x0 + RX_POLARITY_FLIP: 0x0 +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 105 + : + PC_PHYS_PORT_ID: 185 + ? + PORT_ID: 120 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 121 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 123 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 138 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 16 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 139 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 141 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 156 + : + PC_PHYS_PORT_ID: 257 + ? + PORT_ID: 157 + : + PC_PHYS_PORT_ID: 265 + ? + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 273 + ? + PORT_ID: 159 + : + PC_PHYS_PORT_ID: 281 + ? + PORT_ID: 174 + : + PC_PHYS_PORT_ID: 289 + ? + PORT_ID: 175 + : + PC_PHYS_PORT_ID: 297 + ? + PORT_ID: 176 + : + PC_PHYS_PORT_ID: 305 + ? + PORT_ID: 177 + : + PC_PHYS_PORT_ID: 313 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 192 + : + PC_PHYS_PORT_ID: 321 + ? + PORT_ID: 193 + : + PC_PHYS_PORT_ID: 329 + ? + PORT_ID: 194 + : + PC_PHYS_PORT_ID: 337 + ? + PORT_ID: 195 + : + PC_PHYS_PORT_ID: 345 + ? + PORT_ID: 210 + : + PC_PHYS_PORT_ID: 353 + ? + PORT_ID: 211 + : + PC_PHYS_PORT_ID: 361 + ? + PORT_ID: 212 + : + PC_PHYS_PORT_ID: 369 + ? + PORT_ID: 213 + : + PC_PHYS_PORT_ID: 377 + ? + PORT_ID: 228 + : + PC_PHYS_PORT_ID: 385 + ? + PORT_ID: 31 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 229 + : + PC_PHYS_PORT_ID: 393 + ? + PORT_ID: 230 + : + PC_PHYS_PORT_ID: 401 + ? + PORT_ID: 231 + : + PC_PHYS_PORT_ID: 409 + ? + PORT_ID: 246 + : + PC_PHYS_PORT_ID: 417 + ? + PORT_ID: 247 + : + PC_PHYS_PORT_ID: 425 + ? + PORT_ID: 248 + : + PC_PHYS_PORT_ID: 433 + ? + PORT_ID: 249 + : + PC_PHYS_PORT_ID: 441 + ? + PORT_ID: 264 + : + PC_PHYS_PORT_ID: 449 + ? + PORT_ID: 265 + : + PC_PHYS_PORT_ID: 457 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 266 + : + PC_PHYS_PORT_ID: 465 + ? + PORT_ID: 267 + : + PC_PHYS_PORT_ID: 473 + ? + PORT_ID: 282 + : + PC_PHYS_PORT_ID: 481 + ? + PORT_ID: 283 + : + PC_PHYS_PORT_ID: 489 + ? + PORT_ID: 284 + : + PC_PHYS_PORT_ID: 497 + ? + PORT_ID: 285 + : + PC_PHYS_PORT_ID: 505 + ? + PORT_ID: 300 + : + PC_PHYS_PORT_ID: 513 + ? + PORT_ID: 301 + : + PC_PHYS_PORT_ID: 521 + ? + PORT_ID: 302 + : + PC_PHYS_PORT_ID: 529 + ? + PORT_ID: 33 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 303 + : + PC_PHYS_PORT_ID: 537 + ? + PORT_ID: 318 + : + PC_PHYS_PORT_ID: 545 + ? + PORT_ID: 319 + : + PC_PHYS_PORT_ID: 553 + ? + PORT_ID: 320 + : + PC_PHYS_PORT_ID: 561 + ? + PORT_ID: 321 + : + PC_PHYS_PORT_ID: 569 + ? + PORT_ID: 336 + : + PC_PHYS_PORT_ID: 577 + ? + PORT_ID: 337 + : + PC_PHYS_PORT_ID: 585 + ? + PORT_ID: 338 + : + PC_PHYS_PORT_ID: 593 + ? + PORT_ID: 339 + : + PC_PHYS_PORT_ID: 601 + ? + PORT_ID: 354 + : + PC_PHYS_PORT_ID: 609 + ? + PORT_ID: 355 + : + PC_PHYS_PORT_ID: 617 + ? + PORT_ID: 356 + : + PC_PHYS_PORT_ID: 625 + ? + PORT_ID: 357 + : + PC_PHYS_PORT_ID: 633 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 372 + : + PC_PHYS_PORT_ID: 641 + ? + PORT_ID: 373 + : + PC_PHYS_PORT_ID: 649 + ? + PORT_ID: 374 + : + PC_PHYS_PORT_ID: 657 + ? + PORT_ID: 375 + : + PC_PHYS_PORT_ID: 665 + ? + PORT_ID: 390 + : + PC_PHYS_PORT_ID: 673 + ? + PORT_ID: 391 + : + PC_PHYS_PORT_ID: 681 + ? + PORT_ID: 392 + : + PC_PHYS_PORT_ID: 689 + ? + PORT_ID: 393 + : + PC_PHYS_PORT_ID: 697 + ? + PORT_ID: 408 + : + PC_PHYS_PORT_ID: 705 + ? + PORT_ID: 49 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 409 + : + PC_PHYS_PORT_ID: 713 + ? + PORT_ID: 410 + : + PC_PHYS_PORT_ID: 721 + ? + PORT_ID: 411 + : + PC_PHYS_PORT_ID: 729 + ? + PORT_ID: 426 + : + PC_PHYS_PORT_ID: 737 + ? + PORT_ID: 427 + : + PC_PHYS_PORT_ID: 745 + ? + PORT_ID: 428 + : + PC_PHYS_PORT_ID: 753 + ? + PORT_ID: 429 + : + PC_PHYS_PORT_ID: 761 + ? + PORT_ID: 444 + : + PC_PHYS_PORT_ID: 769 + ? + PORT_ID: 445 + : + PC_PHYS_PORT_ID: 777 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 446 + : + PC_PHYS_PORT_ID: 785 + ? + PORT_ID: 447 + : + PC_PHYS_PORT_ID: 793 + ? + PORT_ID: 462 + : + PC_PHYS_PORT_ID: 801 + ? + PORT_ID: 463 + : + PC_PHYS_PORT_ID: 809 + ? + PORT_ID: 464 + : + PC_PHYS_PORT_ID: 817 + ? + PORT_ID: 465 + : + PC_PHYS_PORT_ID: 825 + ? + PORT_ID: 480 + : + PC_PHYS_PORT_ID: 833 + ? + PORT_ID: 481 + : + PC_PHYS_PORT_ID: 841 + ? + PORT_ID: 482 + : + PC_PHYS_PORT_ID: 849 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 483 + : + PC_PHYS_PORT_ID: 857 + ? + PORT_ID: 498 + : + PC_PHYS_PORT_ID: 865 + ? + PORT_ID: 499 + : + PC_PHYS_PORT_ID: 873 + ? + PORT_ID: 500 + : + PC_PHYS_PORT_ID: 881 + ? + PORT_ID: 501 + : + PC_PHYS_PORT_ID: 889 + ? + PORT_ID: 14 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 516 + : + PC_PHYS_PORT_ID: 897 + ? + PORT_ID: 517 + : + PC_PHYS_PORT_ID: 905 + ? + PORT_ID: 518 + : + PC_PHYS_PORT_ID: 913 + ? + PORT_ID: 519 + : + PC_PHYS_PORT_ID: 921 + ? + PORT_ID: 534 + : + PC_PHYS_PORT_ID: 929 + ? + PORT_ID: 535 + : + PC_PHYS_PORT_ID: 937 + ? + PORT_ID: 536 + : + PC_PHYS_PORT_ID: 945 + ? + PORT_ID: 537 + : + PC_PHYS_PORT_ID: 953 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 552 + : + PC_PHYS_PORT_ID: 961 + ? + PORT_ID: 553 + : + PC_PHYS_PORT_ID: 969 + ? + PORT_ID: 554 + : + PC_PHYS_PORT_ID: 977 + ? + PORT_ID: 555 + : + PC_PHYS_PORT_ID: 985 + ? + PORT_ID: 570 + : + PC_PHYS_PORT_ID: 993 + ? + PORT_ID: 571 + : + PC_PHYS_PORT_ID: 1001 + ? + PORT_ID: 572 + : + PC_PHYS_PORT_ID: 1009 + ? + PORT_ID: 573 + : + PC_PHYS_PORT_ID: 1017 + ? + PORT_ID: 67 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 69 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 84 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 85 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 86 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 87 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 102 + : + PC_PHYS_PORT_ID: 161 + ? + PORT_ID: 103 + : + PC_PHYS_PORT_ID: 169 + ? + PORT_ID: 104 + : + PC_PHYS_PORT_ID: 177 + ? + PORT_ID: 268 + : + PC_PHYS_PORT_ID: 1026 + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + ENABLE: 1 + SPEED: 800000 + NUM_LANES: 8 + FEC_MODE: PC_FEC_RS544_2XN_IEEE + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [268] + : + ENABLE: 1 + SPEED: 100000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS528 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 +... + +--- +device: + 0: + PC_PMD_FIRMWARE: + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE + ? + PORT_ID: [268] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + stat_custom_receive0_management_mode: 1 + pktio_mode: 1 + sai_pfc_defaults_disable: 1 + sai_mac_policy_vfp_group: 0 + sai_skip_create_sys_efp_grp: 1 + sai_rdma_udf_disable: 1 + sai_trap_fp_action_drop_copy_to_cpu: 1 + sai_crm_hw_nh_group_cnt: 0 + riot_overlay_l3_intf_mem_size: 4096 + riot_overlay_l3_egress_mem_size: 8192 + l3_ecmp_member_first_lkup_mem_size: 8192 + l3_ecmp_member_secondary_mem_size: 8192 + failover_fixed_nh_offset_enable: 1 + sai_optimized_mmu: 0 + sai_async_fdb_nbr_enable: 1 + bcm_linkscan_interval: 100000 + sai_pfc_dlr_init_capability: 2 + sai_stats_support_mask: 0x804 +... + +--- +device: + 0: + # IFP mode + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... + +--- +bcm_device: + 0: + port: + "*": + encap_mode: IEEE +... diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/default_sku b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/default_sku new file mode 100644 index 0000000000..ce71600eb7 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/default_sku @@ -0,0 +1 @@ +M2-W6950-Q256 l2 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/hwsku.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/hwsku.json new file mode 100644 index 0000000000..fcf051b52a --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/hwsku.json @@ -0,0 +1,654 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet136": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet144": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet152": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet160": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet168": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet176": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet184": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet192": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet200": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet208": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet216": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet224": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet232": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet240": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet248": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet256": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet264": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet272": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet280": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet288": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet296": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet304": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet312": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet320": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet328": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet336": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet344": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet352": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet360": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet368": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet376": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet384": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet392": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet400": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet408": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet416": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet424": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet432": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet440": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet448": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet456": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet464": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet472": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet480": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet488": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet496": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet504": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet512": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet520": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet528": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet536": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet544": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet552": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet560": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet568": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet576": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet584": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet592": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet600": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet608": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet616": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet624": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet632": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet640": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet648": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet656": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet664": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet672": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet680": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet688": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet696": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet704": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet712": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet720": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet728": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet736": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet744": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet752": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet760": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet768": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet776": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet784": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet792": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet800": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet808": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet816": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet824": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet832": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet840": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet848": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet856": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet864": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet872": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet880": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet888": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet896": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet904": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet912": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet920": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet928": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet936": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet944": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet952": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet960": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet968": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet976": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet984": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet992": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1000": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1008": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1016": { + "default_brkout_mode": "2x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1024": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1025": { + "default_brkout_mode": "1x1G", + "autoneg": "off", + "fec": "none" + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/media_settings.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/media_settings.json new file mode 100644 index 0000000000..267b5d2f3d --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/media_settings.json @@ -0,0 +1,8196 @@ +{ + "PORT_MEDIA_SETTINGS": { + "1": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "2": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "3": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "4": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "5": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "6": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "7": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "8": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "9": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "10": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "11": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "12": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "13": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "14": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "15": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "16": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "17": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "18": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "19": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "20": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "21": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "22": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "23": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "24": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "25": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "26": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "27": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "28": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "29": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "30": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "31": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "32": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000064", + "lane1": "0x00000064", + "lane2": "0x00000064", + "lane3": "0x00000064", + "lane4": "0x00000064", + "lane5": "0x00000064", + "lane6": "0x00000064", + "lane7": "0x00000064" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "33": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "34": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "35": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "36": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "37": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "38": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "39": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "40": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "41": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "42": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "43": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "44": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "45": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "46": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "47": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "48": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "49": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "50": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "51": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "52": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "53": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "54": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "55": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "56": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "57": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "58": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "59": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "60": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "61": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "62": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "63": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "64": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "65": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "66": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "67": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "68": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "69": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "70": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "71": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "72": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "73": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "74": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "75": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "76": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "77": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "78": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "79": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "80": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "81": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "82": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "83": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "84": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "85": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "86": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe0", + "lane1": "0xffffffe0", + "lane2": "0xffffffe0", + "lane3": "0xffffffe0", + "lane4": "0xffffffe0", + "lane5": "0xffffffe0", + "lane6": "0xffffffe0", + "lane7": "0xffffffe0" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "87": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "88": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "89": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "90": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "91": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "92": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "93": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "94": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "95": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "96": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000058", + "lane1": "0x00000058", + "lane2": "0x00000058", + "lane3": "0x00000058", + "lane4": "0x00000058", + "lane5": "0x00000058", + "lane6": "0x00000058", + "lane7": "0x00000058" + }, + "post1": { + "lane0": "0xffffffdc", + "lane1": "0xffffffdc", + "lane2": "0xffffffdc", + "lane3": "0xffffffdc", + "lane4": "0xffffffdc", + "lane5": "0xffffffdc", + "lane6": "0xffffffdc", + "lane7": "0xffffffdc" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "97": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "98": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "99": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "100": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "101": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "102": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "103": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "104": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "105": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "106": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "107": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "108": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "109": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "110": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "111": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "112": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "113": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "114": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "115": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "116": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "117": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "118": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "119": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "120": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "121": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "122": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "123": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "124": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "125": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "126": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "127": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + }, + "128": { + "Default": { + "pre3": { + "lane0": "0xffffffff", + "lane1": "0xffffffff", + "lane2": "0xffffffff", + "lane3": "0xffffffff", + "lane4": "0xffffffff", + "lane5": "0xffffffff", + "lane6": "0xffffffff", + "lane7": "0xffffffff" + }, + "pre2": { + "lane0": "0x00000005", + "lane1": "0x00000005", + "lane2": "0x00000005", + "lane3": "0x00000005", + "lane4": "0x00000005", + "lane5": "0x00000005", + "lane6": "0x00000005", + "lane7": "0x00000005" + }, + "pre1": { + "lane0": "0xffffffe4", + "lane1": "0xffffffe4", + "lane2": "0xffffffe4", + "lane3": "0xffffffe4", + "lane4": "0xffffffe4", + "lane5": "0xffffffe4", + "lane6": "0xffffffe4", + "lane7": "0xffffffe4" + }, + "main": { + "lane0": "0x00000054", + "lane1": "0x00000054", + "lane2": "0x00000054", + "lane3": "0x00000054", + "lane4": "0x00000054", + "lane5": "0x00000054", + "lane6": "0x00000054", + "lane7": "0x00000054" + }, + "post1": { + "lane0": "0xffffffec", + "lane1": "0xffffffec", + "lane2": "0xffffffec", + "lane3": "0xffffffec", + "lane4": "0xffffffec", + "lane5": "0xffffffec", + "lane6": "0xffffffec", + "lane7": "0xffffffec" + }, + "post2": { + "lane0": "0xfffffffa", + "lane1": "0xfffffffa", + "lane2": "0xfffffffa", + "lane3": "0xfffffffa", + "lane4": "0xfffffffa", + "lane5": "0xfffffffa", + "lane6": "0xfffffffa", + "lane7": "0xfffffffa" + } + } + } + } +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/port_config.ini b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/port_config.ini new file mode 100644 index 0000000000..1cf6f68c11 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/port_config.ini @@ -0,0 +1,259 @@ +# name lanes alias index speed +Ethernet0 265,266,267,268 etp1a 1 400000 +Ethernet4 269,270,271,272 etp1b 1 400000 +Ethernet8 297,298,299,300 etp2a 2 400000 +Ethernet12 301,302,303,304 etp2b 2 400000 +Ethernet16 305,306,307,308 etp3a 3 400000 +Ethernet20 309,310,311,312 etp3b 3 400000 +Ethernet24 313,314,315,316 etp4a 4 400000 +Ethernet28 317,318,319,320 etp4b 4 400000 +Ethernet32 377,378,379,380 etp5a 5 400000 +Ethernet36 381,382,383,384 etp5b 5 400000 +Ethernet40 369,370,371,372 etp6a 6 400000 +Ethernet44 373,374,375,376 etp6b 6 400000 +Ethernet48 361,362,363,364 etp7a 7 400000 +Ethernet52 365,366,367,368 etp7b 7 400000 +Ethernet56 329,330,331,332 etp8a 8 400000 +Ethernet60 333,334,335,336 etp8b 8 400000 +Ethernet64 505,506,507,508 etp9a 9 400000 +Ethernet68 509,510,511,512 etp9b 9 400000 +Ethernet72 497,498,499,500 etp10a 10 400000 +Ethernet76 501,502,503,504 etp10b 10 400000 +Ethernet80 489,490,491,492 etp11a 11 400000 +Ethernet84 493,494,495,496 etp11b 11 400000 +Ethernet88 457,458,459,460 etp12a 12 400000 +Ethernet92 461,462,463,464 etp12b 12 400000 +Ethernet96 449,450,451,452 etp13a 13 400000 +Ethernet100 453,454,455,456 etp13b 13 400000 +Ethernet104 465,466,467,468 etp14a 14 400000 +Ethernet108 469,470,471,472 etp14b 14 400000 +Ethernet112 481,482,483,484 etp15a 15 400000 +Ethernet116 485,486,487,488 etp15b 15 400000 +Ethernet120 473,474,475,476 etp16a 16 400000 +Ethernet124 477,478,479,480 etp16b 16 400000 +Ethernet128 537,538,539,540 etp17a 17 400000 +Ethernet132 541,542,543,544 etp17b 17 400000 +Ethernet136 545,546,547,548 etp18a 18 400000 +Ethernet140 549,550,551,552 etp18b 18 400000 +Ethernet144 529,530,531,532 etp19a 19 400000 +Ethernet148 533,534,535,536 etp19b 19 400000 +Ethernet152 513,514,515,516 etp20a 20 400000 +Ethernet156 517,518,519,520 etp20b 20 400000 +Ethernet160 521,522,523,524 etp21a 21 400000 +Ethernet164 525,526,527,528 etp21b 21 400000 +Ethernet168 553,554,555,556 etp22a 22 400000 +Ethernet172 557,558,559,560 etp22b 22 400000 +Ethernet176 561,562,563,564 etp23a 23 400000 +Ethernet180 565,566,567,568 etp23b 23 400000 +Ethernet184 569,570,571,572 etp24a 24 400000 +Ethernet188 573,574,575,576 etp24b 24 400000 +Ethernet192 649,650,651,652 etp25a 25 400000 +Ethernet196 653,654,655,656 etp25b 25 400000 +Ethernet200 681,682,683,684 etp26a 26 400000 +Ethernet204 685,686,687,688 etp26b 26 400000 +Ethernet208 689,690,691,692 etp27a 27 400000 +Ethernet212 693,694,695,696 etp27b 27 400000 +Ethernet216 697,698,699,700 etp28a 28 400000 +Ethernet220 701,702,703,704 etp28b 28 400000 +Ethernet224 761,762,763,764 etp29a 29 400000 +Ethernet228 765,766,767,768 etp29b 29 400000 +Ethernet232 753,754,755,756 etp30a 30 400000 +Ethernet236 757,758,759,760 etp30b 30 400000 +Ethernet240 713,714,715,716 etp31a 31 400000 +Ethernet244 717,718,719,720 etp31b 31 400000 +Ethernet248 745,746,747,748 etp32a 32 400000 +Ethernet252 749,750,751,752 etp32b 32 400000 +Ethernet256 33,34,35,36 etp33a 33 400000 +Ethernet260 37,38,39,40 etp33b 33 400000 +Ethernet264 1,2,3,4 etp34a 34 400000 +Ethernet268 5,6,7,8 etp34b 34 400000 +Ethernet272 41,42,43,44 etp35a 35 400000 +Ethernet276 45,46,47,48 etp35b 35 400000 +Ethernet280 57,58,59,60 etp36a 36 400000 +Ethernet284 61,62,63,64 etp36b 36 400000 +Ethernet288 121,122,123,124 etp37a 37 400000 +Ethernet292 125,126,127,128 etp37b 37 400000 +Ethernet296 105,106,107,108 etp38a 38 400000 +Ethernet300 109,110,111,112 etp38b 38 400000 +Ethernet304 65,66,67,68 etp39a 39 400000 +Ethernet308 69,70,71,72 etp39b 39 400000 +Ethernet312 97,98,99,100 etp40a 40 400000 +Ethernet316 101,102,103,104 etp40b 40 400000 +Ethernet320 153,154,155,156 etp41a 41 400000 +Ethernet324 157,158,159,160 etp41b 41 400000 +Ethernet328 145,146,147,148 etp42a 42 400000 +Ethernet332 149,150,151,152 etp42b 42 400000 +Ethernet336 321,322,323,324 etp43a 43 400000 +Ethernet340 325,326,327,328 etp43b 43 400000 +Ethernet344 353,354,355,356 etp44a 44 400000 +Ethernet348 357,358,359,360 etp44b 44 400000 +Ethernet352 409,410,411,412 etp45a 45 400000 +Ethernet356 413,414,415,416 etp45b 45 400000 +Ethernet360 401,402,403,404 etp46a 46 400000 +Ethernet364 405,406,407,408 etp46b 46 400000 +Ethernet368 393,394,395,396 etp47a 47 400000 +Ethernet372 397,398,399,400 etp47b 47 400000 +Ethernet376 433,434,435,436 etp48a 48 400000 +Ethernet380 437,438,439,440 etp48b 48 400000 +Ethernet384 585,586,587,588 etp49a 49 400000 +Ethernet388 589,590,591,592 etp49b 49 400000 +Ethernet392 625,626,627,628 etp50a 50 400000 +Ethernet396 629,630,631,632 etp50b 50 400000 +Ethernet400 601,602,603,604 etp51a 51 400000 +Ethernet404 605,606,607,608 etp51b 51 400000 +Ethernet408 593,594,595,596 etp52a 52 400000 +Ethernet412 597,598,599,600 etp52b 52 400000 +Ethernet416 641,642,643,644 etp53a 53 400000 +Ethernet420 645,646,647,648 etp53b 53 400000 +Ethernet424 673,674,675,676 etp54a 54 400000 +Ethernet428 677,678,679,680 etp54b 54 400000 +Ethernet432 857,858,859,860 etp55a 55 400000 +Ethernet436 861,862,863,864 etp55b 55 400000 +Ethernet440 849,850,851,852 etp56a 56 400000 +Ethernet444 853,854,855,856 etp56b 56 400000 +Ethernet448 897,898,899,900 etp57a 57 400000 +Ethernet452 901,902,903,904 etp57b 57 400000 +Ethernet456 929,930,931,932 etp58a 58 400000 +Ethernet460 933,934,935,936 etp58b 58 400000 +Ethernet464 953,954,955,956 etp59a 59 400000 +Ethernet468 957,958,959,960 etp59b 59 400000 +Ethernet472 937,938,939,940 etp60a 60 400000 +Ethernet476 941,942,943,944 etp60b 60 400000 +Ethernet480 1001,1002,1003,1004 etp61a 61 400000 +Ethernet484 1005,1006,1007,1008 etp61b 61 400000 +Ethernet488 1017,1018,1019,1020 etp62a 62 400000 +Ethernet492 1021,1022,1023,1024 etp62b 62 400000 +Ethernet496 993,994,995,996 etp63a 63 400000 +Ethernet500 997,998,999,1000 etp63b 63 400000 +Ethernet504 961,962,963,964 etp64a 64 400000 +Ethernet508 965,966,967,968 etp64b 64 400000 +Ethernet512 17,18,19,20 etp65a 65 400000 +Ethernet516 21,22,23,24 etp65b 65 400000 +Ethernet520 25,26,27,28 etp66a 66 400000 +Ethernet524 29,30,31,32 etp66b 66 400000 +Ethernet528 49,50,51,52 etp67a 67 400000 +Ethernet532 53,54,55,56 etp67b 67 400000 +Ethernet536 9,10,11,12 etp68a 68 400000 +Ethernet540 13,14,15,16 etp68b 68 400000 +Ethernet544 73,74,75,76 etp69a 69 400000 +Ethernet548 77,78,79,80 etp69b 69 400000 +Ethernet552 113,114,115,116 etp70a 70 400000 +Ethernet556 117,118,119,120 etp70b 70 400000 +Ethernet560 89,90,91,92 etp71a 71 400000 +Ethernet564 93,94,95,96 etp71b 71 400000 +Ethernet568 81,82,83,84 etp72a 72 400000 +Ethernet572 85,86,87,88 etp72b 72 400000 +Ethernet576 129,130,131,132 etp73a 73 400000 +Ethernet580 133,134,135,136 etp73b 73 400000 +Ethernet584 161,162,163,164 etp74a 74 400000 +Ethernet588 165,166,167,168 etp74b 74 400000 +Ethernet592 345,346,347,348 etp75a 75 400000 +Ethernet596 349,350,351,352 etp75b 75 400000 +Ethernet600 337,338,339,340 etp76a 76 400000 +Ethernet604 341,342,343,344 etp76b 76 400000 +Ethernet608 385,386,387,388 etp77a 77 400000 +Ethernet612 389,390,391,392 etp77b 77 400000 +Ethernet616 417,418,419,420 etp78a 78 400000 +Ethernet620 421,422,423,424 etp78b 78 400000 +Ethernet624 441,442,443,444 etp79a 79 400000 +Ethernet628 445,446,447,448 etp79b 79 400000 +Ethernet632 425,426,427,428 etp80a 80 400000 +Ethernet636 429,430,431,432 etp80b 80 400000 +Ethernet640 633,634,635,636 etp81a 81 400000 +Ethernet644 637,638,639,640 etp81b 81 400000 +Ethernet648 617,618,619,620 etp82a 82 400000 +Ethernet652 621,622,623,624 etp82b 82 400000 +Ethernet656 577,578,579,580 etp83a 83 400000 +Ethernet660 581,582,583,584 etp83b 83 400000 +Ethernet664 609,610,611,612 etp84a 84 400000 +Ethernet668 613,614,615,616 etp84b 84 400000 +Ethernet672 665,666,667,668 etp85a 85 400000 +Ethernet676 669,670,671,672 etp85b 85 400000 +Ethernet680 657,658,659,660 etp86a 86 400000 +Ethernet684 661,662,663,664 etp86b 86 400000 +Ethernet688 833,834,835,836 etp87a 87 400000 +Ethernet692 837,838,839,840 etp87b 87 400000 +Ethernet696 865,866,867,868 etp88a 88 400000 +Ethernet700 869,870,871,872 etp88b 88 400000 +Ethernet704 921,922,923,924 etp89a 89 400000 +Ethernet708 925,926,927,928 etp89b 89 400000 +Ethernet712 913,914,915,916 etp90a 90 400000 +Ethernet716 917,918,919,920 etp90b 90 400000 +Ethernet720 905,906,907,908 etp91a 91 400000 +Ethernet724 909,910,911,912 etp91b 91 400000 +Ethernet728 945,946,947,948 etp92a 92 400000 +Ethernet732 949,950,951,952 etp92b 92 400000 +Ethernet736 1009,1010,1011,1012 etp93a 93 400000 +Ethernet740 1013,1014,1015,1016 etp93b 93 400000 +Ethernet744 969,970,971,972 etp94a 94 400000 +Ethernet748 973,974,975,976 etp94b 94 400000 +Ethernet752 977,978,979,980 etp95a 95 400000 +Ethernet756 981,982,983,984 etp95b 95 400000 +Ethernet760 985,986,987,988 etp96a 96 400000 +Ethernet764 989,990,991,992 etp96b 96 400000 +Ethernet768 209,210,211,212 etp97a 97 400000 +Ethernet772 213,214,215,216 etp97b 97 400000 +Ethernet776 193,194,195,196 etp98a 98 400000 +Ethernet780 197,198,199,200 etp98b 98 400000 +Ethernet784 225,226,227,228 etp99a 99 400000 +Ethernet788 229,230,231,232 etp99b 99 400000 +Ethernet792 217,218,219,220 etp100a 100 400000 +Ethernet796 221,222,223,224 etp100b 100 400000 +Ethernet800 281,282,283,284 etp101a 101 400000 +Ethernet804 285,286,287,288 etp101b 101 400000 +Ethernet808 289,290,291,292 etp102a 102 400000 +Ethernet812 293,294,295,296 etp102b 102 400000 +Ethernet816 257,258,259,260 etp103a 103 400000 +Ethernet820 261,262,263,264 etp103b 103 400000 +Ethernet824 273,274,275,276 etp104a 104 400000 +Ethernet828 277,278,279,280 etp104b 104 400000 +Ethernet832 201,202,203,204 etp105a 105 400000 +Ethernet836 205,206,207,208 etp105b 105 400000 +Ethernet840 233,234,235,236 etp106a 106 400000 +Ethernet844 237,238,239,240 etp106b 106 400000 +Ethernet848 241,242,243,244 etp107a 107 400000 +Ethernet852 245,246,247,248 etp107b 107 400000 +Ethernet856 249,250,251,252 etp108a 108 400000 +Ethernet860 253,254,255,256 etp108b 108 400000 +Ethernet864 185,186,187,188 etp109a 109 400000 +Ethernet868 189,190,191,192 etp109b 109 400000 +Ethernet872 177,178,179,180 etp110a 110 400000 +Ethernet876 181,182,183,184 etp110b 110 400000 +Ethernet880 169,170,171,172 etp111a 111 400000 +Ethernet884 173,174,175,176 etp111b 111 400000 +Ethernet888 137,138,139,140 etp112a 112 400000 +Ethernet892 141,142,143,144 etp112b 112 400000 +Ethernet896 841,842,843,844 etp113a 113 400000 +Ethernet900 845,846,847,848 etp113b 113 400000 +Ethernet904 873,874,875,876 etp114a 114 400000 +Ethernet908 877,878,879,880 etp114b 114 400000 +Ethernet912 881,882,883,884 etp115a 115 400000 +Ethernet916 885,886,887,888 etp115b 115 400000 +Ethernet920 889,890,891,892 etp116a 116 400000 +Ethernet924 893,894,895,896 etp116b 116 400000 +Ethernet928 825,826,827,828 etp117a 117 400000 +Ethernet932 829,830,831,832 etp117b 117 400000 +Ethernet936 817,818,819,820 etp118a 118 400000 +Ethernet940 821,822,823,824 etp118b 118 400000 +Ethernet944 809,810,811,812 etp119a 119 400000 +Ethernet948 813,814,815,816 etp119b 119 400000 +Ethernet952 777,778,779,780 etp120a 120 400000 +Ethernet956 781,782,783,784 etp120b 120 400000 +Ethernet960 721,722,723,724 etp121a 121 400000 +Ethernet964 725,726,727,728 etp121b 121 400000 +Ethernet968 705,706,707,708 etp122a 122 400000 +Ethernet972 709,710,711,712 etp122b 122 400000 +Ethernet976 737,738,739,740 etp123a 123 400000 +Ethernet980 741,742,743,744 etp123b 123 400000 +Ethernet984 729,730,731,732 etp124a 124 400000 +Ethernet988 733,734,735,736 etp124b 124 400000 +Ethernet992 793,794,795,796 etp125a 125 400000 +Ethernet996 797,798,799,800 etp125b 125 400000 +Ethernet1000 801,802,803,804 etp126a 126 400000 +Ethernet1004 805,806,807,808 etp126b 126 400000 +Ethernet1008 785,786,787,788 etp127a 127 400000 +Ethernet1012 789,790,791,792 etp127b 127 400000 +Ethernet1016 769,770,771,772 etp128a 128 400000 +Ethernet1020 773,774,775,776 etp128b 128 400000 +Ethernet1024 1026,1027,1028,1029 etp129 129 100000 +Ethernet1025 0 etp130 130 1000 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sai.profile b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sai.profile new file mode 100644 index 0000000000..3a8aa684dd --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th6-m2-w6950-q256-256x400G.config.yml diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sap_bcm_81394.cfg b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sap_bcm_81394.cfg new file mode 100644 index 0000000000..c8b29b322c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/sap_bcm_81394.cfg @@ -0,0 +1,246 @@ +# Configuration file version number. +# The current sap_bcm_81394.c does not read this field; it is compatibility/identification information. +# Modifying it will not affect the initialization process of the 81394 driver. +version=1 + +# ==================== +# Global Initialization Parameters +# ==================== + +# Number of slots on the board. +# sap_aperta_config_init() first reads this value into the global g_slot_num, +# then sap_bcm_platform_init() calls sap_slot_init() for 0 to g_slot_num-1. +# Missing this field will cause configuration initialization to fail directly. +plp_slot_num=1 + +# MDIO access type. The ':1' in the key is not a PHY address, but the mdio_id. +# The code first reads plp_phy_mdio_id:0x30=1, then looks up plp_mdio_accs_type:1. +# The value comes from sap_mdio_type_e: +# 0 = MAC +# 1 = SYSFS +# 2 = SYSFS_CUST +# The current value 2 indicates using the custom sysfs MDIO access path. +plp_mdio_accs_type:1=2 + +# Firmware loading method, saved to the global g_fw_load_method. +# The definitions in the 81394 driver are: +# 0 = Do not load +# 1 = Unicast load +# 2 = Broadcast load +# 3 = EEPROM load +# 4 = upgrade path +# 5 = skip +# 6 = full process +# The current value 1 means downloading firmware to each PHY via unicast. +plp_fw_load_method=1 + +# Enable or disable I2C slave. +# The code reads this into g_i2c_slave_en, but in the current main flow of the 81394, +# the corresponding register write logic is completely commented out. +# Therefore, this value is currently a "parsed but not effective by default" field. +plp_i2c_slave_en=0 + +# AVS I2C response address. +# This is also read into g_avs_i2c_resp_addr and used by sap_bcm_avs_init() to assemble register values. +# However, AVS initialization is not actually enabled in the current boot path, so this is just a reserved configuration. +avs_i2c_resp_addr=0x35 + +# Default enable/disable link training for the port's system side. +# If there is no per-port configuration for init_linktrain_sys, each port inherits this global value. +# In sap_aperta_post_port_init(), it calls sap_bcm_linktraining_set(..., true) only if the value is 1. +# 0 means do not automatically enable LT. +plp_port_linktrain_sys=0 + +# Default enable/disable link training for the port's line side. +# The semantics are the same as plp_port_linktrain_sys, applying to the line side. +plp_port_linktrain_line=0 + +# ==================== +# Profile 1 VCO Presets +# ==================== + +# VCO selection for Profile 1, octal 0, system side. +# The 81394 code forcibly reads this and saves it to phy_info->vco_octal_0_sys. +# Confirmed from public headers: +# 0 = bcmplpVco51G +# 1 = bcmplpVco53G +# The current value 1 means 53G VCO. +# Note: In this version of the 81394 implementation, this value is read but not used further in mode_config_set. +# It seems more like a field retained to share the configuration format with other chips in the family. +plp_profile_1_init_vco_octal_0_sys=1 + +# VCO selection for Profile 1, octal 0, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_0_line=1 + +# VCO selection for Profile 1, octal 1, system side. +# The current board type uses only one PHY at address 0x30 and the profile uses lanes=0,1, +# but the code still requires the VCO for octal 1 to be configured, otherwise configuration parsing fails. +plp_profile_1_init_vco_octal_1_sys=1 + +# VCO selection for Profile 1, octal 1, line side. +# The current value 1 = 53G VCO. +plp_profile_1_init_vco_octal_1_line=1 + +# ==================== +# Profile 1: 100G, split=1, Single port with 4 lanes +# Key format: plp_profile__speed__split_.: +# This is changed to a single 100G port, hence split_num=1, port_id=0. +# +# In the 81394 code, split_num is not hardcoded, but calculated by: +# phy_info->lane_num / port_info->lanes +# Therefore, to target split_1.0, the init_lanes below needs to provide 4 lane entries, +# and init_ports_lane_num must be configured as 4, indicating a 4-lane aggregated port. +# ==================== + +# FEC mode for the line side. +# For the 100G 4x25G scenario, the semantics from the original file are retained, where 3 = RSFEC. +# This still uses the 25.78125G/lane NRZ path, not 2x50G PAM4. +plp_profile_1_speed_100000_split_1.0:fec_line=3 + +# FEC mode for the system side. +# Consistent with the line side, configured as 3 = RSFEC. +plp_profile_1_speed_100000_split_1.0:fec_sys=3 + +# Interface type for the line side. +# In bcm_pm_interface_t, 7 = bcm_pm_InterfaceKR4. +# This is changed from the single-lane KR to 4-lane KR4, matching the 100G 4-lane port form factor. +plp_profile_1_speed_100000_split_1.0:iftype_line=7 + +# Interface type for the system side. +# Also changed to 7 = KR4, maintaining the lane count and interface width consistency between system/line sides. +plp_profile_1_speed_100000_split_1.0:iftype_sys=7 + +# Line side lane bitmask. +# 0xF = 0000 1111b, indicating selection of 4 consecutive lanes. +# With speed=100000, the code calculates the per-lane speed as 25.78125G. +plp_profile_1_speed_100000_split_1.0:lanemap_line=0xF + +# System side lane bitmask. +# Same as the line side, indicating a 4-lane passthrough port, not a gearbox/reverse-gearbox. +plp_profile_1_speed_100000_split_1.0:lanemap_sys=0xF + +# Force NR (No Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_sys=0x0 + +# Force NR (No Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_nr_line=0x0 + +# Force ER (Eye Retimer) bitmap for the system side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_sys=0x0 + +# Force ER (Eye Retimer) bitmap for the line side. +# Currently not forced, keep as 0. +plp_profile_1_speed_100000_split_1.0:force_er_line=0x0 + + +# ==================== +# PHY List +# ==================== + +# List of PHY addresses to initialize. +# sap_aperta_config_init() generates g_bcm_phy_infos based on this array. +# Currently, there is only one PHY at address 0x30. +plp_phy_addrs=0x30 + +# ==================== +# PHY 0x30 Base Attributes +# PHY address resolution method: +# bus_id = (phy_addr & 0x7c00)>>10; +# mdio_index = (phy_addr & 0x3e0)>>5; +# phy_addr = phy_addr & 0x1f; +# return dfd_utest_mdiodev_rd(mdio_index+bus_id, phy_addr, reg_addr, data); +# ==================== + +# The unit to which the PHY is bound. +# sap_slot_init() filters by unit and card_id to determine if this PHY should be initialized in the current round. +plp_phy_unit_id:0x30=0 + +# The card/slot number the PHY belongs to. +# The PHY is initialized only when this matches the outer slot_id. +plp_phy_card_id:0x30=0 + +# The mdio_id used by this PHY. +# The code will then use this mdio_id to look up plp_mdio_accs_type:. +plp_phy_mdio_id:0x30=1 + +# PHY chip name. +# For this version of the 81394 code, this is a compatibility field, as the chip_name is hardcoded to "aperta" in the source. +# Modifying it will not change the chip name used by the driver. +plp_phy_chip_name:0x30=aperta + +# MACsec option. +# The current 81394 file only reads and saves this to phy_info->macsec_option, with no subsequent use observed. +# Therefore, this is more of a reserved field. +plp_phy_macsec_option:0x30=0x0 + +# PTP option. +# Similar to macsec_option, currently only parsed and saved, not consumed in the main 81394 flow. +plp_phy_ptp_option:0x30=0x0 + +# The initialization profile ID used by this PHY. +# The '1' in all subsequent plp_profile_1_* key names is determined by this value. +plp_phy_init_profile_id:0x30=1 + +# The lane list for this PHY under Profile 1. +# This is changed to 0,1,2,3. This does not mean 4 independent logical ports, +# but rather to make phy_info->lane_num = 4, causing the code to calculate split_num = 1. +# The number of logical ports actually created is still determined by the next line, init_ports. +plp_profile_1_init_lanes:0x30=0-3 + +# The list of logical port numbers presented externally by this PHY under Profile 1. +# Changed to create only one logical port, port 1, to carry the 1x100G module. +plp_profile_1_init_ports:0x30=1 + +# The number of lanes occupied by each logical port under Profile 1. +# Changed to a single port occupying 4 lanes. +plp_profile_1_init_ports_lane_num:0x30=4 + +# The initial speed of each logical port under Profile 1. +# Changed to 100000 Mbps for a single port, i.e., 100G. +plp_profile_1_init_speed_mode:0x30=100000 + +# ==================== +# PHY 0x30 Global Lane Swap and Polarity Configuration +# These keys apply to the entire PHY, not a single port. +# ==================== + +# System side TX lane mapping. +# This value is parsed as 8 nibbles, lane by lane. +# lane_map_tx[lane_index] = GET_LANE_SWAP_OCTAL(value, lane_index). +# 0x76543210 represents logical 0->0, 1->1, 2->2... 7->7, which is an identity mapping. +plp_phy_tx_lane_map_sys:0x30=0x76543210 + +# System side RX lane mapping. +# Currently also an identity mapping. +plp_phy_rx_lane_map_sys:0x30=0x76543210 + +# Line side TX lane mapping. +# 0x76543120 indicates a lane swap on the line side, no longer a direct passthrough. +# The code calls bcm_plp_rxtx_laneswap_set() in sap_aperta_phy_init() to apply this. +plp_phy_tx_lane_map_line:0x30=0x76542301 + +# Line side RX lane mapping. +# Currently the same as TX, indicating that RX/TX both follow the same line-side swapping rules. +plp_phy_rx_lane_map_line:0x30=0x76542301 + +# Line side TX polarity flip bitmap. +# In sap_aperta_phy_init(), the current polarity is read, XORed with this value, and then written back. +# Therefore, a bit=1 means flip the polarity for the corresponding lane; 0 means leave it unchanged. +# The current 0x0 means no polarity flip on the line side TX. +plp_tx_polarity_flip_line:0x30=0x0 + +# Line side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the line side RX. +plp_rx_polarity_flip_line:0x30=0xF + +# System side TX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side TX. +plp_tx_polarity_flip_sys:0x30=0x0 + +# System side RX polarity flip bitmap. +# The current 0x0 means no polarity flip on the system side RX. +plp_rx_polarity_flip_sys:0x30=0x0 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/th6-m2-w6950-q256-256x400G.config.yml b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/th6-m2-w6950-q256-256x400G.config.yml new file mode 100644 index 0000000000..fb087656e0 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/M2-W6950-Q256/th6-m2-w6950-q256-256x400G.config.yml @@ -0,0 +1,2182 @@ +--- +device: + 0: + DEVICE_CONFIG: + AUTOLOAD_BOARD_SETTINGS: 0 +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12360745 + RX_LANE_MAP: 0x34726150 + TX_POLARITY_FLIP: 0x57 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327140 + RX_LANE_MAP: 0x60317425 + TX_POLARITY_FLIP: 0x99 + RX_POLARITY_FLIP: 0x59 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23145670 + RX_LANE_MAP: 0x57462103 + TX_POLARITY_FLIP: 0x6e + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45726013 + RX_LANE_MAP: 0x12360475 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0x87 + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17204653 + RX_LANE_MAP: 0x54036127 + TX_POLARITY_FLIP: 0x3f + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x14027653 + RX_LANE_MAP: 0x54217036 + TX_POLARITY_FLIP: 0x45 + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26351407 + RX_LANE_MAP: 0x52407163 + TX_POLARITY_FLIP: 0x43 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670321 + RX_LANE_MAP: 0x53274610 + TX_POLARITY_FLIP: 0xad + RX_POLARITY_FLIP: 0xd8 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21705463 + RX_LANE_MAP: 0x46327105 + TX_POLARITY_FLIP: 0x95 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12057463 + RX_LANE_MAP: 0x51740236 + TX_POLARITY_FLIP: 0xc8 + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67105243 + RX_LANE_MAP: 0x40236715 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0x05 + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23164507 + RX_LANE_MAP: 0x45712063 + TX_POLARITY_FLIP: 0xd7 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46570213 + RX_LANE_MAP: 0x71546032 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0x51 + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17453206 + RX_LANE_MAP: 0x61257430 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x64 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56327041 + RX_LANE_MAP: 0x50361427 + TX_POLARITY_FLIP: 0xe2 + RX_POLARITY_FLIP: 0xf8 + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x57624301 + TX_POLARITY_FLIP: 0x0d + RX_POLARITY_FLIP: 0xa0 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01374526 + RX_LANE_MAP: 0x64751032 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13024675 + RX_LANE_MAP: 0x61304275 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xa1 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x16452307 + RX_LANE_MAP: 0x50346721 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0xb8 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32604571 + RX_LANE_MAP: 0x67205314 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46120573 + RX_LANE_MAP: 0x13526407 + TX_POLARITY_FLIP: 0x2e + RX_POLARITY_FLIP: 0xf6 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x30412657 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x04 + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13207465 + RX_LANE_MAP: 0x20316475 + TX_POLARITY_FLIP: 0x01 + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x61305274 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23107465 + RX_LANE_MAP: 0x32107654 + TX_POLARITY_FLIP: 0x62 + RX_POLARITY_FLIP: 0x99 + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20731645 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0xf7 + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027654 + RX_LANE_MAP: 0x62307145 + TX_POLARITY_FLIP: 0x9d + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x31064752 + RX_LANE_MAP: 0x02135764 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xca + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12357064 + RX_LANE_MAP: 0x03216457 + TX_POLARITY_FLIP: 0x81 + RX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106745 + RX_LANE_MAP: 0x61034275 + TX_POLARITY_FLIP: 0x11 + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32014756 + RX_LANE_MAP: 0x13024576 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02376154 + RX_LANE_MAP: 0x03612547 + TX_POLARITY_FLIP: 0xd5 + RX_POLARITY_FLIP: 0xef + ? + PC_PM_ID: 33 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x02637154 + TX_POLARITY_FLIP: 0xe7 + RX_POLARITY_FLIP: 0x20 + ? + PC_PM_ID: 34 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0x01 + ? + PC_PM_ID: 35 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02134765 + RX_LANE_MAP: 0x13026745 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0x82 + ? + PC_PM_ID: 36 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23016745 + RX_LANE_MAP: 0x30162745 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xc9 + ? + PC_PM_ID: 37 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30412675 + RX_LANE_MAP: 0x32051674 + TX_POLARITY_FLIP: 0xa7 + RX_POLARITY_FLIP: 0x1b + ? + PC_PM_ID: 38 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x91 + ? + PC_PM_ID: 39 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x01534267 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x29 + ? + PC_PM_ID: 40 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x23507164 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 41 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x07324651 + RX_LANE_MAP: 0x46357201 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x3a + ? + PC_PM_ID: 42 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x10325746 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0xee + ? + PC_PM_ID: 43 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65073421 + RX_LANE_MAP: 0x53026714 + TX_POLARITY_FLIP: 0x7e + RX_POLARITY_FLIP: 0xc5 + ? + PC_PM_ID: 44 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21057463 + RX_LANE_MAP: 0x47513260 + TX_POLARITY_FLIP: 0x65 + RX_POLARITY_FLIP: 0x07 + ? + PC_PM_ID: 45 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47061235 + RX_LANE_MAP: 0x41276530 + TX_POLARITY_FLIP: 0x34 + RX_POLARITY_FLIP: 0xf1 + ? + PC_PM_ID: 46 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x01437265 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 47 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x13607254 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x44 + ? + PC_PM_ID: 48 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x13025476 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 49 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70152643 + RX_LANE_MAP: 0x76512043 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 50 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x04635271 + RX_LANE_MAP: 0x67235014 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x25 + ? + PC_PM_ID: 51 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x76540213 + RX_LANE_MAP: 0x51376240 + TX_POLARITY_FLIP: 0xf1 + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 52 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x12375460 + RX_LANE_MAP: 0x54261037 + TX_POLARITY_FLIP: 0xe1 + RX_POLARITY_FLIP: 0x0f + ? + PC_PM_ID: 53 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64301572 + RX_LANE_MAP: 0x63107425 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 54 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45213670 + RX_LANE_MAP: 0x41062537 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 55 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25461073 + RX_LANE_MAP: 0x73215640 + TX_POLARITY_FLIP: 0xec + RX_POLARITY_FLIP: 0x0e + ? + PC_PM_ID: 56 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30264571 + RX_LANE_MAP: 0x67452031 + TX_POLARITY_FLIP: 0x38 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 57 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0x23 + ? + PC_PM_ID: 58 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 59 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x23017654 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x96 + ? + PC_PM_ID: 60 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36270154 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x33 + ? + PC_PM_ID: 61 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x02341675 + TX_POLARITY_FLIP: 0x20 + RX_POLARITY_FLIP: 0xc7 + ? + PC_PM_ID: 62 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x23106754 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x26 + ? + PC_PM_ID: 63 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x36170254 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x73 + ? + PC_PM_ID: 64 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x20341765 + TX_POLARITY_FLIP: 0xd0 + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 65 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36270154 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0x7a + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 66 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02736154 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x13 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 67 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32105764 + RX_LANE_MAP: 0x32106745 + TX_POLARITY_FLIP: 0x46 + RX_POLARITY_FLIP: 0x96 + ? + PC_PM_ID: 68 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63721045 + TX_POLARITY_FLIP: 0xa3 + RX_POLARITY_FLIP: 0xcc + ? + PC_PM_ID: 69 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02341675 + RX_LANE_MAP: 0x20436157 + TX_POLARITY_FLIP: 0xd3 + RX_POLARITY_FLIP: 0x34 + ? + PC_PM_ID: 70 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106457 + RX_LANE_MAP: 0x32017645 + TX_POLARITY_FLIP: 0x63 + RX_POLARITY_FLIP: 0xe6 + ? + PC_PM_ID: 71 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x63721045 + RX_LANE_MAP: 0x63712045 + TX_POLARITY_FLIP: 0xb5 + RX_POLARITY_FLIP: 0x4c + ? + PC_PM_ID: 72 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20371645 + RX_LANE_MAP: 0x02437156 + TX_POLARITY_FLIP: 0x23 + RX_POLARITY_FLIP: 0x40 + ? + PC_PM_ID: 73 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13762540 + RX_LANE_MAP: 0x51764320 + TX_POLARITY_FLIP: 0xe0 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 74 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x62135470 + RX_LANE_MAP: 0x64025317 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xea + ? + PC_PM_ID: 75 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54761302 + RX_LANE_MAP: 0x50326741 + TX_POLARITY_FLIP: 0x0b + RX_POLARITY_FLIP: 0x7e + ? + PC_PM_ID: 76 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x34075261 + RX_LANE_MAP: 0x57021634 + TX_POLARITY_FLIP: 0x5a + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 77 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75201463 + RX_LANE_MAP: 0x70126435 + TX_POLARITY_FLIP: 0xe4 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 78 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67013542 + RX_LANE_MAP: 0x26034517 + TX_POLARITY_FLIP: 0xde + RX_POLARITY_FLIP: 0x7f + ? + PC_PM_ID: 79 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46257310 + RX_LANE_MAP: 0x70265143 + TX_POLARITY_FLIP: 0x4c + RX_POLARITY_FLIP: 0xf5 + ? + PC_PM_ID: 80 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x21354670 + RX_LANE_MAP: 0x45673120 + TX_POLARITY_FLIP: 0xab + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 81 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41237506 + TX_POLARITY_FLIP: 0x80 + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 82 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10324756 + RX_LANE_MAP: 0x01237564 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0xdd + ? + PC_PM_ID: 83 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x24173560 + RX_LANE_MAP: 0x62015734 + TX_POLARITY_FLIP: 0xc5 + RX_POLARITY_FLIP: 0xf0 + ? + PC_PM_ID: 84 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03247561 + RX_LANE_MAP: 0x51476032 + TX_POLARITY_FLIP: 0xf6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 85 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06473512 + RX_LANE_MAP: 0x40256731 + TX_POLARITY_FLIP: 0x3e + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 86 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02375164 + RX_LANE_MAP: 0x10342756 + TX_POLARITY_FLIP: 0x2b + RX_POLARITY_FLIP: 0xc9 + ? + PC_PM_ID: 87 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01237564 + RX_LANE_MAP: 0x31062745 + TX_POLARITY_FLIP: 0xdb + RX_POLARITY_FLIP: 0x88 + ? + PC_PM_ID: 88 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02137564 + RX_LANE_MAP: 0x31204567 + TX_POLARITY_FLIP: 0x74 + RX_POLARITY_FLIP: 0xcd + ? + PC_PM_ID: 89 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64751302 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0x24 + RX_POLARITY_FLIP: 0xfb + ? + PC_PM_ID: 90 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x01375264 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0x7f + RX_POLARITY_FLIP: 0x02 + ? + PC_PM_ID: 91 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65471302 + RX_LANE_MAP: 0x54762031 + TX_POLARITY_FLIP: 0x1b + RX_POLARITY_FLIP: 0xbe + ? + PC_PM_ID: 92 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45670123 + RX_LANE_MAP: 0x54726103 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0x6c + ? + PC_PM_ID: 93 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75264130 + RX_LANE_MAP: 0x47615023 + TX_POLARITY_FLIP: 0x25 + RX_POLARITY_FLIP: 0x27 + ? + PC_PM_ID: 94 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20314756 + RX_LANE_MAP: 0x10324576 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x91 + ? + PC_PM_ID: 95 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x20315746 + RX_LANE_MAP: 0x10352476 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x16 + ? + PC_PM_ID: 96 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10732546 + RX_LANE_MAP: 0x32051746 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x42 + ? + PC_PM_ID: 97 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65741023 + RX_LANE_MAP: 0x45670123 + TX_POLARITY_FLIP: 0x76 + RX_POLARITY_FLIP: 0x66 + ? + PC_PM_ID: 98 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0x84 + RX_POLARITY_FLIP: 0x10 + ? + PC_PM_ID: 99 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x45713062 + TX_POLARITY_FLIP: 0x89 + RX_POLARITY_FLIP: 0x55 + ? + PC_PM_ID: 100 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52470631 + RX_LANE_MAP: 0x46753120 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0xac + ? + PC_PM_ID: 101 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64703512 + RX_LANE_MAP: 0x75461230 + TX_POLARITY_FLIP: 0xbd + RX_POLARITY_FLIP: 0x3b + ? + PC_PM_ID: 102 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45671032 + RX_LANE_MAP: 0x57243016 + TX_POLARITY_FLIP: 0xbb + RX_POLARITY_FLIP: 0x9c + ? + PC_PM_ID: 103 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x56470132 + RX_LANE_MAP: 0x67542031 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x8c + ? + PC_PM_ID: 104 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54613702 + RX_LANE_MAP: 0x74521630 + TX_POLARITY_FLIP: 0xa8 + RX_POLARITY_FLIP: 0x08 + ? + PC_PM_ID: 105 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36054721 + RX_LANE_MAP: 0x75643210 + TX_POLARITY_FLIP: 0xb7 + RX_POLARITY_FLIP: 0xb9 + ? + PC_PM_ID: 106 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75642031 + RX_LANE_MAP: 0x57240316 + TX_POLARITY_FLIP: 0xf7 + RX_POLARITY_FLIP: 0x7a + ? + PC_PM_ID: 107 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45160723 + RX_LANE_MAP: 0x51376420 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x43 + ? + PC_PM_ID: 108 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65104273 + RX_LANE_MAP: 0x64325017 + TX_POLARITY_FLIP: 0xc9 + RX_POLARITY_FLIP: 0x1b + ? + PC_PM_ID: 109 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x75320641 + RX_LANE_MAP: 0x62501437 + TX_POLARITY_FLIP: 0xd1 + RX_POLARITY_FLIP: 0x81 + ? + PC_PM_ID: 110 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45167320 + RX_LANE_MAP: 0x75621403 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xdf + ? + PC_PM_ID: 111 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x65742013 + RX_LANE_MAP: 0x57461302 + TX_POLARITY_FLIP: 0xbf + RX_POLARITY_FLIP: 0xe3 + ? + PC_PM_ID: 112 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54760213 + RX_LANE_MAP: 0x47250316 + TX_POLARITY_FLIP: 0xf9 + RX_POLARITY_FLIP: 0xee + ? + PC_PM_ID: 113 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74305162 + RX_LANE_MAP: 0x75014236 + TX_POLARITY_FLIP: 0x8e + RX_POLARITY_FLIP: 0x01 + ? + PC_PM_ID: 114 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03147562 + RX_LANE_MAP: 0x74513602 + TX_POLARITY_FLIP: 0x0e + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 115 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x42305761 + RX_LANE_MAP: 0x63214705 + TX_POLARITY_FLIP: 0x08 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 116 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x17254603 + RX_LANE_MAP: 0x71456320 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x13 + ? + PC_PM_ID: 117 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x57461302 + RX_LANE_MAP: 0x72506431 + TX_POLARITY_FLIP: 0x69 + RX_POLARITY_FLIP: 0xaa + ? + PC_PM_ID: 118 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45170632 + RX_LANE_MAP: 0x60247531 + TX_POLARITY_FLIP: 0x55 + RX_POLARITY_FLIP: 0xde + ? + PC_PM_ID: 119 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x40127653 + RX_LANE_MAP: 0x16325407 + TX_POLARITY_FLIP: 0x9f + RX_POLARITY_FLIP: 0x15 + ? + PC_PM_ID: 120 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124750 + RX_LANE_MAP: 0x41035267 + TX_POLARITY_FLIP: 0x97 + RX_POLARITY_FLIP: 0x0a + ? + PC_PM_ID: 121 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36124507 + RX_LANE_MAP: 0x30716254 + TX_POLARITY_FLIP: 0xa2 + RX_POLARITY_FLIP: 0x83 + ? + PC_PM_ID: 122 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x41027653 + RX_LANE_MAP: 0x71326405 + TX_POLARITY_FLIP: 0x22 + RX_POLARITY_FLIP: 0x3c + ? + PC_PM_ID: 123 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10265473 + RX_LANE_MAP: 0x46570321 + TX_POLARITY_FLIP: 0xbc + RX_POLARITY_FLIP: 0xb9 + ? + PC_PM_ID: 124 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x10327546 + RX_LANE_MAP: 0x06371425 + TX_POLARITY_FLIP: 0x44 + RX_POLARITY_FLIP: 0xe2 + ? + PC_PM_ID: 125 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26304751 + RX_LANE_MAP: 0x67215304 + TX_POLARITY_FLIP: 0x05 + RX_POLARITY_FLIP: 0x77 + ? + PC_PM_ID: 126 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x06327451 + RX_LANE_MAP: 0x76305124 + TX_POLARITY_FLIP: 0x9b + RX_POLARITY_FLIP: 0x64 + ? + PC_PM_ID: 127 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37241506 + RX_LANE_MAP: 0x40526371 + TX_POLARITY_FLIP: 0x64 + RX_POLARITY_FLIP: 0xbf + ? + PC_PM_ID: 128 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x67452103 + RX_LANE_MAP: 0x50264713 + TX_POLARITY_FLIP: 0x58 + RX_POLARITY_FLIP: 0x62 + ? + PC_PM_ID: 129 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x0123 + RX_LANE_MAP: 0x0123 + TX_POLARITY_FLIP: 0x0 + RX_POLARITY_FLIP: 0x0 +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 105 + : + PC_PHYS_PORT_ID: 185 + ? + PORT_ID: 120 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 121 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 123 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 138 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 16 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 139 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 141 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 156 + : + PC_PHYS_PORT_ID: 257 + ? + PORT_ID: 157 + : + PC_PHYS_PORT_ID: 265 + ? + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 273 + ? + PORT_ID: 159 + : + PC_PHYS_PORT_ID: 281 + ? + PORT_ID: 174 + : + PC_PHYS_PORT_ID: 289 + ? + PORT_ID: 175 + : + PC_PHYS_PORT_ID: 297 + ? + PORT_ID: 176 + : + PC_PHYS_PORT_ID: 305 + ? + PORT_ID: 177 + : + PC_PHYS_PORT_ID: 313 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 192 + : + PC_PHYS_PORT_ID: 321 + ? + PORT_ID: 193 + : + PC_PHYS_PORT_ID: 329 + ? + PORT_ID: 194 + : + PC_PHYS_PORT_ID: 337 + ? + PORT_ID: 195 + : + PC_PHYS_PORT_ID: 345 + ? + PORT_ID: 210 + : + PC_PHYS_PORT_ID: 353 + ? + PORT_ID: 211 + : + PC_PHYS_PORT_ID: 361 + ? + PORT_ID: 212 + : + PC_PHYS_PORT_ID: 369 + ? + PORT_ID: 213 + : + PC_PHYS_PORT_ID: 377 + ? + PORT_ID: 228 + : + PC_PHYS_PORT_ID: 385 + ? + PORT_ID: 31 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 229 + : + PC_PHYS_PORT_ID: 393 + ? + PORT_ID: 230 + : + PC_PHYS_PORT_ID: 401 + ? + PORT_ID: 231 + : + PC_PHYS_PORT_ID: 409 + ? + PORT_ID: 246 + : + PC_PHYS_PORT_ID: 417 + ? + PORT_ID: 247 + : + PC_PHYS_PORT_ID: 425 + ? + PORT_ID: 248 + : + PC_PHYS_PORT_ID: 433 + ? + PORT_ID: 249 + : + PC_PHYS_PORT_ID: 441 + ? + PORT_ID: 264 + : + PC_PHYS_PORT_ID: 449 + ? + PORT_ID: 265 + : + PC_PHYS_PORT_ID: 457 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 266 + : + PC_PHYS_PORT_ID: 465 + ? + PORT_ID: 267 + : + PC_PHYS_PORT_ID: 473 + ? + PORT_ID: 282 + : + PC_PHYS_PORT_ID: 481 + ? + PORT_ID: 283 + : + PC_PHYS_PORT_ID: 489 + ? + PORT_ID: 284 + : + PC_PHYS_PORT_ID: 497 + ? + PORT_ID: 285 + : + PC_PHYS_PORT_ID: 505 + ? + PORT_ID: 300 + : + PC_PHYS_PORT_ID: 513 + ? + PORT_ID: 301 + : + PC_PHYS_PORT_ID: 521 + ? + PORT_ID: 302 + : + PC_PHYS_PORT_ID: 529 + ? + PORT_ID: 33 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 303 + : + PC_PHYS_PORT_ID: 537 + ? + PORT_ID: 318 + : + PC_PHYS_PORT_ID: 545 + ? + PORT_ID: 319 + : + PC_PHYS_PORT_ID: 553 + ? + PORT_ID: 320 + : + PC_PHYS_PORT_ID: 561 + ? + PORT_ID: 321 + : + PC_PHYS_PORT_ID: 569 + ? + PORT_ID: 336 + : + PC_PHYS_PORT_ID: 577 + ? + PORT_ID: 337 + : + PC_PHYS_PORT_ID: 585 + ? + PORT_ID: 338 + : + PC_PHYS_PORT_ID: 593 + ? + PORT_ID: 339 + : + PC_PHYS_PORT_ID: 601 + ? + PORT_ID: 354 + : + PC_PHYS_PORT_ID: 609 + ? + PORT_ID: 355 + : + PC_PHYS_PORT_ID: 617 + ? + PORT_ID: 356 + : + PC_PHYS_PORT_ID: 625 + ? + PORT_ID: 357 + : + PC_PHYS_PORT_ID: 633 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 372 + : + PC_PHYS_PORT_ID: 641 + ? + PORT_ID: 373 + : + PC_PHYS_PORT_ID: 649 + ? + PORT_ID: 374 + : + PC_PHYS_PORT_ID: 657 + ? + PORT_ID: 375 + : + PC_PHYS_PORT_ID: 665 + ? + PORT_ID: 390 + : + PC_PHYS_PORT_ID: 673 + ? + PORT_ID: 391 + : + PC_PHYS_PORT_ID: 681 + ? + PORT_ID: 392 + : + PC_PHYS_PORT_ID: 689 + ? + PORT_ID: 393 + : + PC_PHYS_PORT_ID: 697 + ? + PORT_ID: 408 + : + PC_PHYS_PORT_ID: 705 + ? + PORT_ID: 49 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 409 + : + PC_PHYS_PORT_ID: 713 + ? + PORT_ID: 410 + : + PC_PHYS_PORT_ID: 721 + ? + PORT_ID: 411 + : + PC_PHYS_PORT_ID: 729 + ? + PORT_ID: 426 + : + PC_PHYS_PORT_ID: 737 + ? + PORT_ID: 427 + : + PC_PHYS_PORT_ID: 745 + ? + PORT_ID: 428 + : + PC_PHYS_PORT_ID: 753 + ? + PORT_ID: 429 + : + PC_PHYS_PORT_ID: 761 + ? + PORT_ID: 444 + : + PC_PHYS_PORT_ID: 769 + ? + PORT_ID: 445 + : + PC_PHYS_PORT_ID: 777 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 446 + : + PC_PHYS_PORT_ID: 785 + ? + PORT_ID: 447 + : + PC_PHYS_PORT_ID: 793 + ? + PORT_ID: 462 + : + PC_PHYS_PORT_ID: 801 + ? + PORT_ID: 463 + : + PC_PHYS_PORT_ID: 809 + ? + PORT_ID: 464 + : + PC_PHYS_PORT_ID: 817 + ? + PORT_ID: 465 + : + PC_PHYS_PORT_ID: 825 + ? + PORT_ID: 480 + : + PC_PHYS_PORT_ID: 833 + ? + PORT_ID: 481 + : + PC_PHYS_PORT_ID: 841 + ? + PORT_ID: 482 + : + PC_PHYS_PORT_ID: 849 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 483 + : + PC_PHYS_PORT_ID: 857 + ? + PORT_ID: 498 + : + PC_PHYS_PORT_ID: 865 + ? + PORT_ID: 499 + : + PC_PHYS_PORT_ID: 873 + ? + PORT_ID: 500 + : + PC_PHYS_PORT_ID: 881 + ? + PORT_ID: 501 + : + PC_PHYS_PORT_ID: 889 + ? + PORT_ID: 14 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 516 + : + PC_PHYS_PORT_ID: 897 + ? + PORT_ID: 517 + : + PC_PHYS_PORT_ID: 905 + ? + PORT_ID: 518 + : + PC_PHYS_PORT_ID: 913 + ? + PORT_ID: 519 + : + PC_PHYS_PORT_ID: 921 + ? + PORT_ID: 534 + : + PC_PHYS_PORT_ID: 929 + ? + PORT_ID: 535 + : + PC_PHYS_PORT_ID: 937 + ? + PORT_ID: 536 + : + PC_PHYS_PORT_ID: 945 + ? + PORT_ID: 537 + : + PC_PHYS_PORT_ID: 953 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 552 + : + PC_PHYS_PORT_ID: 961 + ? + PORT_ID: 553 + : + PC_PHYS_PORT_ID: 969 + ? + PORT_ID: 554 + : + PC_PHYS_PORT_ID: 977 + ? + PORT_ID: 555 + : + PC_PHYS_PORT_ID: 985 + ? + PORT_ID: 570 + : + PC_PHYS_PORT_ID: 993 + ? + PORT_ID: 571 + : + PC_PHYS_PORT_ID: 1001 + ? + PORT_ID: 572 + : + PC_PHYS_PORT_ID: 1009 + ? + PORT_ID: 573 + : + PC_PHYS_PORT_ID: 1017 + ? + PORT_ID: 67 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 69 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 84 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 85 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 86 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 87 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 102 + : + PC_PHYS_PORT_ID: 161 + ? + PORT_ID: 103 + : + PC_PHYS_PORT_ID: 169 + ? + PORT_ID: 104 + : + PC_PHYS_PORT_ID: 177 + ? + PORT_ID: 268 + : + PC_PHYS_PORT_ID: 1026 + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + ENABLE: 1 + SPEED: 400000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS544_2XN + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [268] + : + ENABLE: 1 + SPEED: 100000 + NUM_LANES: 4 + FEC_MODE: PC_FEC_RS528 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 +... + +--- +device: + 0: + PC_PMD_FIRMWARE: + ? + PORT_ID: [13, 14, 15, 16, 30, 31, 32, 33, 48, 49, 50, 51, 66, 67, 68, 69, 84, 85, 86, 87, 102, 103, 104, 105, 120, 121, 122, 123, 138, 139, 140, 141, 156, 157, 158, 159, 174, 175, 176, 177, 192, 193, 194, 195, 210, 211, 212, 213, 228, 229, 230, 231, 246, 247, 248, 249, 264, 265, 266, 267, 282, 283, 284, 285, 300, 301, 302, 303, 318, 319, 320, 321, 336, 337, 338, 339, 354, 355, 356, 357, 372, 373, 374, 375, 390, 391, 392, 393, 408, 409, 410, 411, 426, 427, 428, 429, 444, 445, 446, 447, 462, 463, 464, 465, 480, 481, 482, 483, 498, 499, 500, 501, 516, 517, 518, 519, 534, 535, 536, 537, 552, 553, 554, 555, 570, 571, 572, 573] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE + ? + PORT_ID: [268] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + stat_custom_receive0_management_mode: 1 + pktio_mode: 1 + sai_pfc_defaults_disable: 1 + sai_mac_policy_vfp_group: 0 + sai_skip_create_sys_efp_grp: 1 + sai_rdma_udf_disable: 1 + sai_trap_fp_action_drop_copy_to_cpu: 1 + sai_crm_hw_nh_group_cnt: 0 + riot_overlay_l3_intf_mem_size: 4096 + riot_overlay_l3_egress_mem_size: 8192 + l3_ecmp_member_first_lkup_mem_size: 8192 + l3_ecmp_member_secondary_mem_size: 8192 + failover_fixed_nh_offset_enable: 1 + sai_optimized_mmu: 0 + sai_async_fdb_nbr_enable: 1 + bcm_linkscan_interval: 100000 + sai_pfc_dlr_init_capability: 2 + sai_stats_support_mask: 0x804 +... + +--- +device: + 0: + # IFP mode + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... + +--- +bcm_device: + 0: + port: + "*": + encap_mode: IEEE +... diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/bmc.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/bmc.json new file mode 100644 index 0000000000..93af8e0bf2 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/bmc.json @@ -0,0 +1,6 @@ +{ + "bmc_if_name": "usb0", + "bmc_if_addr": "169.254.100.2", + "bmc_addr": "169.254.100.1", + "bmc_net_mask": "255.255.255.252" +} \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/custom_led.bin b/device/micas/x86_64-micas_m2-w6950-128oc-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..e87dc0cf82f54941e9332f56b8ab1920514a0a6e GIT binary patch literal 810 zcmYk3O-R#m7{{NN`LgJs%$Lo#HUF3`>9Fk((~JB6?T2#_OoP%HIHxeXd2`UA5rs1- zmL8m2D)i^n%v3%kGx7tbuQf2E?-*SRr2$r3WuZ* zNgw)K$%iz-3n8H`NWW03S>O zAse+4l9BA>AUDM*O&QA3Ii1l7Rmlbjc5p)kmcRo+NI)Ds7{mm|F@_oR(lSkxpQ5xw z)9mLc?{JROT;+2v^D!6T7|Kut3)&E|6;GfFXK)TV$Uqum;N>M=<_Npl!FD!sfsUz6 zMY6DsTN$|(EZ_hmcwrf)!4FZ`fob$(6n8L(X^hYkc_>H;ij#+foZvXeIKyXr!UZle G8U6v|&-q&b literal 0 HcmV?d00001 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/default_sku b/device/micas/x86_64-micas_m2-w6950-128oc-r0/default_sku new file mode 100644 index 0000000000..6f88352d2c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/default_sku @@ -0,0 +1 @@ +M2-W6950-O128 l2 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/dev.xml b/device/micas/x86_64-micas_m2-w6950-128oc-r0/dev.xml new file mode 100644 index 0000000000..3da8d7a760 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/dev.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/fru.py b/device/micas/x86_64-micas_m2-w6950-128oc-r0/fru.py new file mode 100644 index 0000000000..f95164e036 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/installer.conf b/device/micas/x86_64-micas_m2-w6950-128oc-r0/installer.conf new file mode 100644 index 0000000000..6c510bc3bd --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/installer.conf @@ -0,0 +1,42 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="modprobe.blacklist=ixgbe,wb_ixgbe,ice,i2c_designware_platform,wb_i2c_designware_platform,i2c_piix4,i2c_asf,spi_amd,cdc_subset" +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +ONIE_IMAGE_PART_SIZE=1048576 + +create_eth_fix_rules(){ + [ -n "$demo_mnt" ] || return + + [ "$install_env" = "onie" -a -n "$demo_dev" ] && { + mkdir -p $demo_mnt + ${onie_bin} mount -t ext4 -o defaults,rw $demo_dev $demo_mnt || { + echo "Error: Unable to mount $demo_dev on $demo_mnt,link creating failed." + } + } + [ -n "$demo_mnt" -a -n "$image_dir" -a -d "$demo_mnt/$image_dir" ] && { + mkdir -p $demo_mnt/$image_dir/rw/etc/systemd/network/ + + # Fix Intel E610/E810 Ethernet interface names by PCI path + # 02:00.0 -> eth1, 02:00.1 -> eth2 (E610 10GBASE-T) + # 03:00.0..3 -> eth3..eth6 (E810-C backplane) + for entry in \ + "1:0000:02:00.0" \ + "2:0000:02:00.1" \ + "3:0000:03:00.0" \ + "4:0000:03:00.1" \ + "5:0000:03:00.2" \ + "6:0000:03:00.3"; do + idx=${entry%%:*} + bdf=${entry#*:} + cat > $demo_mnt/$image_dir/rw/etc/systemd/network/20-eth${idx}.link < Optional[str]: + """Get breakout mode of the port from database 4""" + try: + key = f"BREAKOUT_CFG|{port_name}" + data = self.redis_db4.hgetall(key) + return data.get('brkout_mode') + except Exception as e: + logger.error(f"Failed to get breakout mode for {port_name}: {e}") + return None + + def get_netdev_oper_status(self, port_name: str) -> Optional[str]: + """Get netdev_oper_status of the port from database 6""" + try: + key = f"PORT_TABLE|{port_name}" + data = self.redis_db6.hgetall(key) + return data.get('netdev_oper_status') + except Exception as e: + logger.error(f"Failed to get netdev_oper_status for {port_name}: {e}") + return None + + def get_all_ethernet_ports(self) -> List[str]: + """Get all Ethernet ports from database 4""" + ports = [] + try: + keys = self.redis_db4.keys("BREAKOUT_CFG|Ethernet*") + for key in keys: + port = key.replace("BREAKOUT_CFG|", "") + ports.append(port) + except Exception as e: + logger.error(f"Failed to get Ethernet port list: {e}") + return sorted(ports) + + def get_reg(self, port: int): + if port not in PORT_TO_REG: + logger.info(f"Invalid port {port}") + return None + logger.info(f"get_reg port:{port}, reg:{PORT_TO_REG[port]}") + return PORT_TO_REG[port] + + def execute_sap_command(self, port_name: str, led_status: int): + """Execute sap command""" + port_num = int(port_name.replace('Ethernet', '')) + port_reg = self.get_reg(port_num) + if port_reg is None: + logger.info(f"port_reg is None port:{port_name}") + return + if port_num < 512: + cmd = f"dfd_debug sysfs_data_wr /dev/cpld15 {port_reg} {led_status}" + else: + cmd = f"dfd_debug sysfs_data_wr /dev/cpld16 {port_reg} {led_status}" + try: + result = subprocess.run( + cmd.split(), + shell=False, # Explicitly set to False for security + capture_output=True, + text=True, + timeout=5 + ) + if result.returncode == 0: + logger.info(f"Command executed successfully: {' '.join(cmd)}") + else: + logger.error(f"Command execution failed: {' '.join(cmd)}, error: {result.stderr}") + except subprocess.TimeoutExpired: + logger.error(f"Command execution timeout (5s): {' '.join(cmd)}") + except Exception as e: + logger.error(f"Command execution exception: {' '.join(cmd)}, error: {e}") + + def reset_all_port_reg(self): + logger.info("LED switch monitoring will be stop, set all port reg to default") + for port_num in PORT_TO_REG.keys(): + port_name = f"Ethernet{port_num}" + self.execute_sap_command(port_name, LED_SWITCH_CONTROL) + + def handle_special_port(self): + """Handle Ethernet1024 specially - directly monitor its netdev_oper_status""" + netdev_status = self.get_netdev_oper_status(SPECIAL_PORT) + if netdev_status is None: + logger.warning(f"Failed to get netdev_oper_status for special port {SPECIAL_PORT}") + return + + old_status = self.last_special_port_status + + if netdev_status == 'up': + if old_status != 'up': + logger.info(f"Special port {SPECIAL_PORT} status changed to up, executing sap LED_GREEN_ON") + self.execute_sap_command(SPECIAL_PORT, LED_GREEN_ON) + self.last_special_port_status = 'up' + elif netdev_status == 'down': + if old_status != 'down': + logger.info(f"Special port {SPECIAL_PORT} status changed to down, executing sap LED_OFF") + self.execute_sap_command(SPECIAL_PORT, LED_OFF) + self.last_special_port_status = 'down' + + def handle_1x800g(self, port: str, current_statuses: Dict[str, str], status_key: str): + """Handle 1x800G breakout mode - monitor single port""" + # Skip special port as it's handled separately + if port == SPECIAL_PORT: + return + + netdev_status = self.get_netdev_oper_status(port) + if netdev_status is None: + return + + old_status = current_statuses.get(status_key) + + if netdev_status == 'up': + if old_status != 'up': + logger.info(f"1x800G port {port} status changed to up, executing sap LED_GREEN_ON") + self.execute_sap_command(port, LED_GREEN_ON) + current_statuses[status_key] = 'up' + elif netdev_status == 'down': + if old_status != 'down': + logger.info(f"1x800G port {port} status changed to down, executing sap LED_OFF") + self.execute_sap_command(port, LED_OFF) + current_statuses[status_key] = 'down' + + def handle_2x400g(self, port: str, current_statuses: Dict[str, str], status_key: str): + """Handle 2x400G breakout mode - monitor port and port+4""" + # Skip if any port in the group is the special port + port_num = int(port.replace('Ethernet', '')) + port1 = port + port2 = f"Ethernet{port_num + 4}" + + if port1 == SPECIAL_PORT or port2 == SPECIAL_PORT: + # Special port is handled separately, skip group processing + return + + status1 = self.get_netdev_oper_status(port1) + status2 = self.get_netdev_oper_status(port2) + + if status1 is None or status2 is None: + return + + all_up = (status1 == 'up' and status2 == 'up') + all_down = (status1 == 'down' and status2 == 'down') + + old_status = current_statuses.get(status_key) + + if all_up: + if old_status != 'up': + logger.info(f"2x400G port group {port1} and {port2} both up, executing sap LED_GREEN_ON") + self.execute_sap_command(port, LED_GREEN_ON) + current_statuses[status_key] = 'up' + elif all_down: + if old_status != 'down': + logger.info(f"2x400G port group {port1} and {port2} both down, executing sap LED_OFF") + self.execute_sap_command(port, LED_OFF) + current_statuses[status_key] = 'down' + else: + if old_status != 'mixed': + logger.info(f"2x400G port group {port1}({status1}) and {port2}({status2}) mixed, executing sap LED_YELLOW_ON") + self.execute_sap_command(port, LED_YELLOW_ON) + current_statuses[status_key] = 'mixed' + + def handle_4x200g(self, port: str, current_statuses: Dict[str, str], status_key: str): + """Handle 4x200G breakout mode - monitor port, port+2, port+4, port+6""" + port_num = int(port.replace('Ethernet', '')) + ports = [ + port, + f"Ethernet{port_num + 2}", + f"Ethernet{port_num + 4}", + f"Ethernet{port_num + 6}" + ] + + # Skip if any port in the group is the special port + if SPECIAL_PORT in ports: + return + + statuses = [] + for p in ports: + status = self.get_netdev_oper_status(p) + if status is None: + return + statuses.append(status) + + all_up = all(s == 'up' for s in statuses) + all_down = all(s == 'down' for s in statuses) + + old_status = current_statuses.get(status_key) + + if all_up: + if old_status != 'up': + logger.info(f"4x200G port group {ports} all up, executing sap LED_GREEN_ON") + self.execute_sap_command(port, LED_GREEN_ON) + current_statuses[status_key] = 'up' + elif all_down: + if old_status != 'down': + logger.info(f"4x200G port group {ports} all down, executing sap LED_OFF") + self.execute_sap_command(port, LED_OFF) + current_statuses[status_key] = 'down' + else: + if old_status != 'mixed': + status_str = ','.join([f"{p}({s})" for p, s in zip(ports, statuses)]) + logger.info(f"4x200G port group {status_str} mixed, executing sap LED_YELLOW_ON") + self.execute_sap_command(port, LED_YELLOW_ON) + current_statuses[status_key] = 'mixed' + + def handle_8x100g(self, port: str, current_statuses: Dict[str, str], status_key: str): + """Handle 8x100G breakout mode - monitor port, port+1, ..., port+7""" + port_num = int(port.replace('Ethernet', '')) + ports = [f"Ethernet{port_num + i}" for i in range(8)] + + # Skip if any port in the group is the special port + if SPECIAL_PORT in ports: + return + + statuses = [] + for p in ports: + status = self.get_netdev_oper_status(p) + if status is None: + return + statuses.append(status) + + all_up = all(s == 'up' for s in statuses) + all_down = all(s == 'down' for s in statuses) + + old_status = current_statuses.get(status_key) + + if all_up: + if old_status != 'up': + logger.info(f"8x100G port group {ports[0]}...{ports[-1]} all up, executing sap LED_GREEN_ON") + self.execute_sap_command(port, LED_GREEN_ON) + current_statuses[status_key] = 'up' + elif all_down: + if old_status != 'down': + logger.info(f"8x100G port group {ports[0]}...{ports[-1]} all down, executing sap LED_OFF") + self.execute_sap_command(port, LED_OFF) + current_statuses[status_key] = 'down' + else: + if old_status != 'mixed': + logger.info(f"8x100G port group {ports[0]}...{ports[-1]} mixed, executing sap LED_YELLOW_ON") + self.execute_sap_command(port, LED_YELLOW_ON) + current_statuses[status_key] = 'mixed' + + def monitor_loop(self, stop_event: threading.Event): + """Main monitoring loop""" + logger.info("Monitor thread started") + + while not stop_event.is_set(): + try: + # Reconnect to Redis if disconnected + if not self.initialized or not self.redis_db4 or not self.redis_db6: + if not self.connect_redis(): + time.sleep(5) + continue + self.initialized = True + + # Handle special port Ethernet1024 first + self.handle_special_port() + + # Get all Ethernet ports + ports = self.get_all_ethernet_ports() + + # Track processed ports to avoid duplicate processing + processed_ports = set() + + for port in ports: + # Skip special port as it's handled separately + if port == SPECIAL_PORT: + continue + + if port in processed_ports: + continue + + brkout_mode = self.get_brkout_mode(port) + + if brkout_mode == '1x800G': + status_key = f"{port}_1x800G" + self.handle_1x800g(port, self.last_status, status_key) + processed_ports.add(port) + + elif brkout_mode == '2x400G': + status_key = f"{port}_2x400G" + self.handle_2x400g(port, self.last_status, status_key) + # Mark related ports to avoid duplicate processing + port_num = int(port.replace('Ethernet', '')) + processed_ports.add(port) + processed_ports.add(f"Ethernet{port_num + 4}") + + elif brkout_mode == '4x200G': + status_key = f"{port}_4x200G" + self.handle_4x200g(port, self.last_status, status_key) + port_num = int(port.replace('Ethernet', '')) + for i in range(0, 8, 2): + processed_ports.add(f"Ethernet{port_num + i}") + + elif brkout_mode == '8x100G': + status_key = f"{port}_8x100G" + self.handle_8x100g(port, self.last_status, status_key) + port_num = int(port.replace('Ethernet', '')) + for i in range(8): + processed_ports.add(f"Ethernet{port_num + i}") + + except Exception as e: + logger.error(f"Monitor loop exception: {e}") + + # Wait 2 seconds before next iteration + stop_event.wait(2) + + logger.info("Monitor thread stopped") + + def start(self): + """Start monitoring""" + global monitor_thread, stop_event + + if monitor_thread is not None and monitor_thread.is_alive(): + logger.warning("Monitor thread already running") + return + + stop_event.clear() + monitor_thread = threading.Thread(target=self.monitor_loop, args=(stop_event,), daemon=True) + monitor_thread.start() + logger.info("LED switch monitoring started") + + def stop(self): + """Stop monitoring""" + global monitor_thread + self.reset_all_port_reg() + if monitor_thread is None or not monitor_thread.is_alive(): + logger.warning("Monitor thread not running") + return + + stop_event.set() + monitor_thread.join(timeout=5) + monitor_thread = None + logger.info("LED switch monitoring stopped") + + +# Global monitor instance +monitor = LedSwitchMonitor() + + +def signal_handler(signum, frame): + """Signal handler for graceful shutdown""" + logger.info(f"Received signal {signum}, exiting...") + monitor.stop() + sys.exit(0) + + +def main(): + """Main function""" + if len(sys.argv) != 2: + print("Usage: python ledswitch_monitor.py {start|stop}") + sys.exit(1) + + command = sys.argv[1] + + # Register signal handlers + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + if command == 'start': + monitor.start() + # Keep main thread running + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + monitor.stop() + elif command == 'stop': + monitor.stop() + else: + print(f"Unknown command: {command}") + print("Usage: python ledswitch_monitor.py {start|stop}") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/monitor.py b/device/micas/x86_64-micas_m2-w6950-128oc-r0/monitor.py new file mode 100644 index 0000000000..5fc287892e --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/monitor.py @@ -0,0 +1,402 @@ +#!/usr/bin/python3 +# * onboard temperature sensors +# * FAN trays +# * PSU +# +import os +from lxml import etree as ET +import glob +import json +from decimal import Decimal +from fru import ipmifru + + +MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + +CONFIG_NAME = "dev.xml" + + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def getPMCreg(location): + retval = 'ERR' + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) + try: + with open(location, 'r') as fd: + retval = fd.read() + except Exception as error: + return "ERR %s" % str(error) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +# Get a mailbox register +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = reg_name + filepath = glob.glob(mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) + mb_reg_file = filepath[0] + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) + try: + with open(mb_reg_file, 'rb') as fd: + retval = fd.read() + retval = typeTostr(retval) + except Exception as error: + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +class checktype(): + def __init__(self, test1): + self.test1 = test1 + + @staticmethod + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) + return value_t + except Exception as e: + value_t = "ERR %s" % str(e) + return value_t + + # fanFRU + @staticmethod + def decodeBinByValue(retval): + fru = ipmifru() + fru.decodeBin(retval) + return fru + + @staticmethod + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name.strip() == psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) + + +class status(): + def __init__(self, productname): + self.productname = productname + + @staticmethod + def getETroot(filename): + tree = ET.parse(filename) + root = tree.getroot() + return root + + @staticmethod + def getDecodValue(collection, decode): + decodes = collection.find('decode') + testdecode = decodes.find(decode) + test = {} + if testdecode is None: + return test + for neighbor in testdecode.iter('code'): + test[neighbor.attrib["key"]] = neighbor.attrib["value"] + return test + + @staticmethod + def getfileValue(location): + return checktype.getValue(location, " ", " ") + + @staticmethod + def getETValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + prob_t = {} + prob_t.update(neighbor.attrib) + prob_t['errcode'] = 0 + prob_t['errmsg'] = '' + for pros in neighbor.iter("property"): + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) + if ret.get('e2type') == 'fru' and ret.get("name") == "fru": + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" + else: + val = ret["type"] + if 'bit' not in ret.keys(): + bit = "0" + else: + bit = ret["bit"] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] + if str(s) != ret["default"]: + prob_t['errcode'] = -1 + break + else: + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) + else: + s = rt[str(s).replace("\x00", "").rstrip()] + name = ret["name"] + prob_t[name] = str(s) + a.append(prob_t) + + @staticmethod + def getCPUValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + location = neighbor.attrib["location"] + L = [] + for dirpath, dirnames, filenames in os.walk(location): + for file in filenames: + if file.endswith("input"): + L.append(os.path.join(dirpath, file)) + L = sorted(L, reverse=False) + for i in range(len(L)): + prob_t = {} + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 + a.append(prob_t) + + @staticmethod + def getFileName(): + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + + @staticmethod + def checkFan(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "fan" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getTemp(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "temp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getPsu(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "psu" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getcputemp(ret): + _filename = status.getFileName() + _tagname = "cpus" + status.getCPUValue(ret, _filename, _tagname) + + @staticmethod + def getDcdc(ret): + _filename = status.getFileName() + _tagname = "dcdc" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/pcie.yaml b/device/micas/x86_64-micas_m2-w6950-128oc-r0/pcie.yaml new file mode 100644 index 0000000000..3aef6107f5 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/pcie.yaml @@ -0,0 +1,285 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 14d8 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Root + Complex' +- bus: '00' + dev: '00' + fn: '2' + id: 14d9 + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge IOMMU' +- bus: '00' + dev: '01' + fn: '0' + id: 14da + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy + Host Bridge' +- bus: '00' + dev: '01' + fn: '1' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '01' + fn: '2' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '01' + fn: '3' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '01' + fn: '4' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '01' + fn: '5' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '02' + fn: '0' + id: 14da + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy + Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '02' + fn: '2' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '03' + fn: '0' + id: 14da + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy + Host Bridge' +- bus: '00' + dev: '03' + fn: '1' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '03' + fn: '2' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '03' + fn: '3' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '03' + fn: '4' + id: 14db + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP + Bridge' +- bus: '00' + dev: '04' + fn: '0' + id: 14da + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy + Host Bridge' +- bus: '00' + dev: 08 + fn: '0' + id: 14da + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy + Host Bridge' +- bus: '00' + dev: 08 + fn: '1' + id: 14dd + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Internal + GPP Bridge to Bus [C:A]' +- bus: '00' + dev: 08 + fn: '3' + id: 14dd + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Internal + GPP Bridge to Bus [C:A]' +- bus: '00' + dev: '14' + fn: '0' + id: 790b + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 71)' +- bus: '00' + dev: '14' + fn: '3' + id: 790e + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 51)' +- bus: '00' + dev: '18' + fn: '0' + id: 14e0 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: 14e1 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: 14e2 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: 14e3 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: 14e4 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: 14e5 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 5' +- bus: '00' + dev: '18' + fn: '6' + id: 14e6 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 6' +- bus: '00' + dev: '18' + fn: '7' + id: 14e7 + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data + Fabric; Function 7' +- bus: '01' + dev: '00' + fn: '0' + id: f910 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries BCM78910 Switch ASIC + [Tomahawk6] (rev 01)' +- bus: '02' + dev: '00' + fn: '0' + id: 57b0 + name: 'Ethernet controller: Intel Corporation Ethernet Controller E610 10GBASE T' +- bus: '02' + dev: '00' + fn: '1' + id: 57b0 + name: 'Ethernet controller: Intel Corporation Ethernet Controller E610 10GBASE T' +- bus: '03' + dev: '00' + fn: '0' + id: '1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane + (rev 02)' +- bus: '03' + dev: '00' + fn: '1' + id: '1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane + (rev 02)' +- bus: '03' + dev: '00' + fn: '2' + id: '1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane + (rev 02)' +- bus: '03' + dev: '00' + fn: '3' + id: '1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane + (rev 02)' +- bus: '07' + dev: '00' + fn: '0' + id: 0280 + name: 'Non-Volatile memory controller: YEESTOR Microelectronics Co., Ltd PCIe NVMe + SSD (rev 01)' +- bus: 08 + dev: '00' + fn: '0' + id: '7011' + name: 'Memory controller: Xilinx Corporation 7-Series FPGA Hard PCIe block (AXI/debug)' +- bus: 09 + dev: '00' + fn: '0' + id: '7011' + name: 'Memory controller: Xilinx Corporation 7-Series FPGA Hard PCIe block (AXI/debug)' +- bus: 0a + dev: '00' + fn: '0' + id: '7011' + name: 'Memory controller: Xilinx Corporation 7-Series FPGA Hard PCIe block (AXI/debug)' +- bus: 0b + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: 0c + dev: '00' + fn: '0' + id: 14de + name: 'Non-Essential Instrumentation [1300]: Advanced Micro Devices, Inc. [AMD] + Raphael/Granite Ridge PCIe Dummy Function' +- bus: 0c + dev: '00' + fn: '2' + id: '1649' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Family 19h PSP/CCP' +- bus: 0c + dev: '00' + fn: '3' + id: 15b6 + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge + USB 3.1 xHCI' +- bus: 0c + dev: '00' + fn: '4' + id: 15b7 + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge + USB 3.1 xHCI' +- bus: 0c + dev: '00' + fn: '5' + id: 15e2 + name: 'Multimedia controller: Advanced Micro Devices, Inc. [AMD] Audio Coprocessor + (rev 62)' +- bus: 0c + dev: '00' + fn: '6' + id: 15e3 + name: 'Audio device: Advanced Micro Devices, Inc. [AMD] Family 17h/19h/1ah HD Audio + Controller' +- bus: 0d + dev: '00' + fn: '0' + id: 15b8 + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge + USB 2.0 xHCI' diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform.json new file mode 100644 index 0000000000..cd61e4747d --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform.json @@ -0,0 +1,3740 @@ +{ + "chassis": { + "name": "M2-W6950-O128", + "thermal_manager": false, + "status_led": { + "controllable": false, + "colors": ["green", "blinking_green", "amber", "blinking_amber"] + }, + "components": [], + "fans": [], + "fan_drawers": [], + "psus": [], + "thermals": [], + "modules": [], + "sfps": [] + }, + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1,1,1,1,1", + "lanes": "265,266,267,268,269,270,271,272", + "breakout_modes": { + "1x800G": [ + "etp1" + ], + "2x400G": [ + "etp1a", + "etp1b" + ], + "4x200G": [ + "etp1a", + "etp1b", + "etp1c", + "etp1d" + ], + "8x100G": [ + "etp1a", + "etp1b", + "etp1c", + "etp1d", + "etp1e", + "etp1f", + "etp1g", + "etp1h" + ] + } + }, + "Ethernet8": { + "index": "2,2,2,2,2,2,2,2", + "lanes": "297,298,299,300,301,302,303,304", + "breakout_modes": { + "1x800G": [ + "etp2" + ], + "2x400G": [ + "etp2a", + "etp2b" + ], + "4x200G": [ + "etp2a", + "etp2b", + "etp2c", + "etp2d" + ], + "8x100G": [ + "etp2a", + "etp2b", + "etp2c", + "etp2d", + "etp2e", + "etp2f", + "etp2g", + "etp2h" + ] + } + }, + "Ethernet16": { + "index": "3,3,3,3,3,3,3,3", + "lanes": "305,306,307,308,309,310,311,312", + "breakout_modes": { + "1x800G": [ + "etp3" + ], + "2x400G": [ + "etp3a", + "etp3b" + ], + "4x200G": [ + "etp3a", + "etp3b", + "etp3c", + "etp3d" + ], + "8x100G": [ + "etp3a", + "etp3b", + "etp3c", + "etp3d", + "etp3e", + "etp3f", + "etp3g", + "etp3h" + ] + } + }, + "Ethernet24": { + "index": "4,4,4,4,4,4,4,4", + "lanes": "313,314,315,316,317,318,319,320", + "breakout_modes": { + "1x800G": [ + "etp4" + ], + "2x400G": [ + "etp4a", + "etp4b" + ], + "4x200G": [ + "etp4a", + "etp4b", + "etp4c", + "etp4d" + ], + "8x100G": [ + "etp4a", + "etp4b", + "etp4c", + "etp4d", + "etp4e", + "etp4f", + "etp4g", + "etp4h" + ] + } + }, + "Ethernet32": { + "index": "5,5,5,5,5,5,5,5", + "lanes": "377,378,379,380,381,382,383,384", + "breakout_modes": { + "1x800G": [ + "etp5" + ], + "2x400G": [ + "etp5a", + "etp5b" + ], + "4x200G": [ + "etp5a", + "etp5b", + "etp5c", + "etp5d" + ], + "8x100G": [ + "etp5a", + "etp5b", + "etp5c", + "etp5d", + "etp5e", + "etp5f", + "etp5g", + "etp5h" + ] + } + }, + "Ethernet40": { + "index": "6,6,6,6,6,6,6,6", + "lanes": "369,370,371,372,373,374,375,376", + "breakout_modes": { + "1x800G": [ + "etp6" + ], + "2x400G": [ + "etp6a", + "etp6b" + ], + "4x200G": [ + "etp6a", + "etp6b", + "etp6c", + "etp6d" + ], + "8x100G": [ + "etp6a", + "etp6b", + "etp6c", + "etp6d", + "etp6e", + "etp6f", + "etp6g", + "etp6h" + ] + } + }, + "Ethernet48": { + "index": "7,7,7,7,7,7,7,7", + "lanes": "361,362,363,364,365,366,367,368", + "breakout_modes": { + "1x800G": [ + "etp7" + ], + "2x400G": [ + "etp7a", + "etp7b" + ], + "4x200G": [ + "etp7a", + "etp7b", + "etp7c", + "etp7d" + ], + "8x100G": [ + "etp7a", + "etp7b", + "etp7c", + "etp7d", + "etp7e", + "etp7f", + "etp7g", + "etp7h" + ] + } + }, + "Ethernet56": { + "index": "8,8,8,8,8,8,8,8", + "lanes": "329,330,331,332,333,334,335,336", + "breakout_modes": { + "1x800G": [ + "etp8" + ], + "2x400G": [ + "etp8a", + "etp8b" + ], + "4x200G": [ + "etp8a", + "etp8b", + "etp8c", + "etp8d" + ], + "8x100G": [ + "etp8a", + "etp8b", + "etp8c", + "etp8d", + "etp8e", + "etp8f", + "etp8g", + "etp8h" + ] + } + }, + "Ethernet64": { + "index": "9,9,9,9,9,9,9,9", + "lanes": "505,506,507,508,509,510,511,512", + "breakout_modes": { + "1x800G": [ + "etp9" + ], + "2x400G": [ + "etp9a", + "etp9b" + ], + "4x200G": [ + "etp9a", + "etp9b", + "etp9c", + "etp9d" + ], + "8x100G": [ + "etp9a", + "etp9b", + "etp9c", + "etp9d", + "etp9e", + "etp9f", + "etp9g", + "etp9h" + ] + } + }, + "Ethernet72": { + "index": "10,10,10,10,10,10,10,10", + "lanes": "497,498,499,500,501,502,503,504", + "breakout_modes": { + "1x800G": [ + "etp10" + ], + "2x400G": [ + "etp10a", + "etp10b" + ], + "4x200G": [ + "etp10a", + "etp10b", + "etp10c", + "etp10d" + ], + "8x100G": [ + "etp10a", + "etp10b", + "etp10c", + "etp10d", + "etp10e", + "etp10f", + "etp10g", + "etp10h" + ] + } + }, + "Ethernet80": { + "index": "11,11,11,11,11,11,11,11", + "lanes": "489,490,491,492,493,494,495,496", + "breakout_modes": { + "1x800G": [ + "etp11" + ], + "2x400G": [ + "etp11a", + "etp11b" + ], + "4x200G": [ + "etp11a", + "etp11b", + "etp11c", + "etp11d" + ], + "8x100G": [ + "etp11a", + "etp11b", + "etp11c", + "etp11d", + "etp11e", + "etp11f", + "etp11g", + "etp11h" + ] + } + }, + "Ethernet88": { + "index": "12,12,12,12,12,12,12,12", + "lanes": "457,458,459,460,461,462,463,464", + "breakout_modes": { + "1x800G": [ + "etp12" + ], + "2x400G": [ + "etp12a", + "etp12b" + ], + "4x200G": [ + "etp12a", + "etp12b", + "etp12c", + "etp12d" + ], + "8x100G": [ + "etp12a", + "etp12b", + "etp12c", + "etp12d", + "etp12e", + "etp12f", + "etp12g", + "etp12h" + ] + } + }, + "Ethernet96": { + "index": "13,13,13,13,13,13,13,13", + "lanes": "449,450,451,452,453,454,455,456", + "breakout_modes": { + "1x800G": [ + "etp13" + ], + "2x400G": [ + "etp13a", + "etp13b" + ], + "4x200G": [ + "etp13a", + "etp13b", + "etp13c", + "etp13d" + ], + "8x100G": [ + "etp13a", + "etp13b", + "etp13c", + "etp13d", + "etp13e", + "etp13f", + "etp13g", + "etp13h" + ] + } + }, + "Ethernet104": { + "index": "14,14,14,14,14,14,14,14", + "lanes": "465,466,467,468,469,470,471,472", + "breakout_modes": { + "1x800G": [ + "etp14" + ], + "2x400G": [ + "etp14a", + "etp14b" + ], + "4x200G": [ + "etp14a", + "etp14b", + "etp14c", + "etp14d" + ], + "8x100G": [ + "etp14a", + "etp14b", + "etp14c", + "etp14d", + "etp14e", + "etp14f", + "etp14g", + "etp14h" + ] + } + }, + "Ethernet112": { + "index": "15,15,15,15,15,15,15,15", + "lanes": "481,482,483,484,485,486,487,488", + "breakout_modes": { + "1x800G": [ + "etp15" + ], + "2x400G": [ + "etp15a", + "etp15b" + ], + "4x200G": [ + "etp15a", + "etp15b", + "etp15c", + "etp15d" + ], + "8x100G": [ + "etp15a", + "etp15b", + "etp15c", + "etp15d", + "etp15e", + "etp15f", + "etp15g", + "etp15h" + ] + } + }, + "Ethernet120": { + "index": "16,16,16,16,16,16,16,16", + "lanes": "473,474,475,476,477,478,479,480", + "breakout_modes": { + "1x800G": [ + "etp16" + ], + "2x400G": [ + "etp16a", + "etp16b" + ], + "4x200G": [ + "etp16a", + "etp16b", + "etp16c", + "etp16d" + ], + "8x100G": [ + "etp16a", + "etp16b", + "etp16c", + "etp16d", + "etp16e", + "etp16f", + "etp16g", + "etp16h" + ] + } + }, + "Ethernet128": { + "index": "17,17,17,17,17,17,17,17", + "lanes": "537,538,539,540,541,542,543,544", + "breakout_modes": { + "1x800G": [ + "etp17" + ], + "2x400G": [ + "etp17a", + "etp17b" + ], + "4x200G": [ + "etp17a", + "etp17b", + "etp17c", + "etp17d" + ], + "8x100G": [ + "etp17a", + "etp17b", + "etp17c", + "etp17d", + "etp17e", + "etp17f", + "etp17g", + "etp17h" + ] + } + }, + "Ethernet136": { + "index": "18,18,18,18,18,18,18,18", + "lanes": "545,546,547,548,549,550,551,552", + "breakout_modes": { + "1x800G": [ + "etp18" + ], + "2x400G": [ + "etp18a", + "etp18b" + ], + "4x200G": [ + "etp18a", + "etp18b", + "etp18c", + "etp18d" + ], + "8x100G": [ + "etp18a", + "etp18b", + "etp18c", + "etp18d", + "etp18e", + "etp18f", + "etp18g", + "etp18h" + ] + } + }, + "Ethernet144": { + "index": "19,19,19,19,19,19,19,19", + "lanes": "529,530,531,532,533,534,535,536", + "breakout_modes": { + "1x800G": [ + "etp19" + ], + "2x400G": [ + "etp19a", + "etp19b" + ], + "4x200G": [ + "etp19a", + "etp19b", + "etp19c", + "etp19d" + ], + "8x100G": [ + "etp19a", + "etp19b", + "etp19c", + "etp19d", + "etp19e", + "etp19f", + "etp19g", + "etp19h" + ] + } + }, + "Ethernet152": { + "index": "20,20,20,20,20,20,20,20", + "lanes": "513,514,515,516,517,518,519,520", + "breakout_modes": { + "1x800G": [ + "etp20" + ], + "2x400G": [ + "etp20a", + "etp20b" + ], + "4x200G": [ + "etp20a", + "etp20b", + "etp20c", + "etp20d" + ], + "8x100G": [ + "etp20a", + "etp20b", + "etp20c", + "etp20d", + "etp20e", + "etp20f", + "etp20g", + "etp20h" + ] + } + }, + "Ethernet160": { + "index": "21,21,21,21,21,21,21,21", + "lanes": "521,522,523,524,525,526,527,528", + "breakout_modes": { + "1x800G": [ + "etp21" + ], + "2x400G": [ + "etp21a", + "etp21b" + ], + "4x200G": [ + "etp21a", + "etp21b", + "etp21c", + "etp21d" + ], + "8x100G": [ + "etp21a", + "etp21b", + "etp21c", + "etp21d", + "etp21e", + "etp21f", + "etp21g", + "etp21h" + ] + } + }, + "Ethernet168": { + "index": "22,22,22,22,22,22,22,22", + "lanes": "553,554,555,556,557,558,559,560", + "breakout_modes": { + "1x800G": [ + "etp22" + ], + "2x400G": [ + "etp22a", + "etp22b" + ], + "4x200G": [ + "etp22a", + "etp22b", + "etp22c", + "etp22d" + ], + "8x100G": [ + "etp22a", + "etp22b", + "etp22c", + "etp22d", + "etp22e", + "etp22f", + "etp22g", + "etp22h" + ] + } + }, + "Ethernet176": { + "index": "23,23,23,23,23,23,23,23", + "lanes": "561,562,563,564,565,566,567,568", + "breakout_modes": { + "1x800G": [ + "etp23" + ], + "2x400G": [ + "etp23a", + "etp23b" + ], + "4x200G": [ + "etp23a", + "etp23b", + "etp23c", + "etp23d" + ], + "8x100G": [ + "etp23a", + "etp23b", + "etp23c", + "etp23d", + "etp23e", + "etp23f", + "etp23g", + "etp23h" + ] + } + }, + "Ethernet184": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "569,570,571,572,573,574,575,576", + "breakout_modes": { + "1x800G": [ + "etp24" + ], + "2x400G": [ + "etp24a", + "etp24b" + ], + "4x200G": [ + "etp24a", + "etp24b", + "etp24c", + "etp24d" + ], + "8x100G": [ + "etp24a", + "etp24b", + "etp24c", + "etp24d", + "etp24e", + "etp24f", + "etp24g", + "etp24h" + ] + } + }, + "Ethernet192": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "649,650,651,652,653,654,655,656", + "breakout_modes": { + "1x800G": [ + "etp25" + ], + "2x400G": [ + "etp25a", + "etp25b" + ], + "4x200G": [ + "etp25a", + "etp25b", + "etp25c", + "etp25d" + ], + "8x100G": [ + "etp25a", + "etp25b", + "etp25c", + "etp25d", + "etp25e", + "etp25f", + "etp25g", + "etp25h" + ] + } + }, + "Ethernet200": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "681,682,683,684,685,686,687,688", + "breakout_modes": { + "1x800G": [ + "etp26" + ], + "2x400G": [ + "etp26a", + "etp26b" + ], + "4x200G": [ + "etp26a", + "etp26b", + "etp26c", + "etp26d" + ], + "8x100G": [ + "etp26a", + "etp26b", + "etp26c", + "etp26d", + "etp26e", + "etp26f", + "etp26g", + "etp26h" + ] + } + }, + "Ethernet208": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "689,690,691,692,693,694,695,696", + "breakout_modes": { + "1x800G": [ + "etp27" + ], + "2x400G": [ + "etp27a", + "etp27b" + ], + "4x200G": [ + "etp27a", + "etp27b", + "etp27c", + "etp27d" + ], + "8x100G": [ + "etp27a", + "etp27b", + "etp27c", + "etp27d", + "etp27e", + "etp27f", + "etp27g", + "etp27h" + ] + } + }, + "Ethernet216": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "697,698,699,700,701,702,703,704", + "breakout_modes": { + "1x800G": [ + "etp28" + ], + "2x400G": [ + "etp28a", + "etp28b" + ], + "4x200G": [ + "etp28a", + "etp28b", + "etp28c", + "etp28d" + ], + "8x100G": [ + "etp28a", + "etp28b", + "etp28c", + "etp28d", + "etp28e", + "etp28f", + "etp28g", + "etp28h" + ] + } + }, + "Ethernet224": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "761,762,763,764,765,766,767,768", + "breakout_modes": { + "1x800G": [ + "etp29" + ], + "2x400G": [ + "etp29a", + "etp29b" + ], + "4x200G": [ + "etp29a", + "etp29b", + "etp29c", + "etp29d" + ], + "8x100G": [ + "etp29a", + "etp29b", + "etp29c", + "etp29d", + "etp29e", + "etp29f", + "etp29g", + "etp29h" + ] + } + }, + "Ethernet232": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "753,754,755,756,757,758,759,760", + "breakout_modes": { + "1x800G": [ + "etp30" + ], + "2x400G": [ + "etp30a", + "etp30b" + ], + "4x200G": [ + "etp30a", + "etp30b", + "etp30c", + "etp30d" + ], + "8x100G": [ + "etp30a", + "etp30b", + "etp30c", + "etp30d", + "etp30e", + "etp30f", + "etp30g", + "etp30h" + ] + } + }, + "Ethernet240": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "713,714,715,716,717,718,719,720", + "breakout_modes": { + "1x800G": [ + "etp31" + ], + "2x400G": [ + "etp31a", + "etp31b" + ], + "4x200G": [ + "etp31a", + "etp31b", + "etp31c", + "etp31d" + ], + "8x100G": [ + "etp31a", + "etp31b", + "etp31c", + "etp31d", + "etp31e", + "etp31f", + "etp31g", + "etp31h" + ] + } + }, + "Ethernet248": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "745,746,747,748,749,750,751,752", + "breakout_modes": { + "1x800G": [ + "etp32" + ], + "2x400G": [ + "etp32a", + "etp32b" + ], + "4x200G": [ + "etp32a", + "etp32b", + "etp32c", + "etp32d" + ], + "8x100G": [ + "etp32a", + "etp32b", + "etp32c", + "etp32d", + "etp32e", + "etp32f", + "etp32g", + "etp32h" + ] + } + }, + "Ethernet256": { + "index": "33,33,33,33,33,33,33,33", + "lanes": "33,34,35,36,37,38,39,40", + "breakout_modes": { + "1x800G": [ + "etp33" + ], + "2x400G": [ + "etp33a", + "etp33b" + ], + "4x200G": [ + "etp33a", + "etp33b", + "etp33c", + "etp33d" + ], + "8x100G": [ + "etp33a", + "etp33b", + "etp33c", + "etp33d", + "etp33e", + "etp33f", + "etp33g", + "etp33h" + ] + } + }, + "Ethernet264": { + "index": "34,34,34,34,34,34,34,34", + "lanes": "1,2,3,4,5,6,7,8", + "breakout_modes": { + "1x800G": [ + "etp34" + ], + "2x400G": [ + "etp34a", + "etp34b" + ], + "4x200G": [ + "etp34a", + "etp34b", + "etp34c", + "etp34d" + ], + "8x100G": [ + "etp34a", + "etp34b", + "etp34c", + "etp34d", + "etp34e", + "etp34f", + "etp34g", + "etp34h" + ] + } + }, + "Ethernet272": { + "index": "35,35,35,35,35,35,35,35", + "lanes": "41,42,43,44,45,46,47,48", + "breakout_modes": { + "1x800G": [ + "etp35" + ], + "2x400G": [ + "etp35a", + "etp35b" + ], + "4x200G": [ + "etp35a", + "etp35b", + "etp35c", + "etp35d" + ], + "8x100G": [ + "etp35a", + "etp35b", + "etp35c", + "etp35d", + "etp35e", + "etp35f", + "etp35g", + "etp35h" + ] + } + }, + "Ethernet280": { + "index": "36,36,36,36,36,36,36,36", + "lanes": "57,58,59,60,61,62,63,64", + "breakout_modes": { + "1x800G": [ + "etp36" + ], + "2x400G": [ + "etp36a", + "etp36b" + ], + "4x200G": [ + "etp36a", + "etp36b", + "etp36c", + "etp36d" + ], + "8x100G": [ + "etp36a", + "etp36b", + "etp36c", + "etp36d", + "etp36e", + "etp36f", + "etp36g", + "etp36h" + ] + } + }, + "Ethernet288": { + "index": "37,37,37,37,37,37,37,37", + "lanes": "121,122,123,124,125,126,127,128", + "breakout_modes": { + "1x800G": [ + "etp37" + ], + "2x400G": [ + "etp37a", + "etp37b" + ], + "4x200G": [ + "etp37a", + "etp37b", + "etp37c", + "etp37d" + ], + "8x100G": [ + "etp37a", + "etp37b", + "etp37c", + "etp37d", + "etp37e", + "etp37f", + "etp37g", + "etp37h" + ] + } + }, + "Ethernet296": { + "index": "38,38,38,38,38,38,38,38", + "lanes": "105,106,107,108,109,110,111,112", + "breakout_modes": { + "1x800G": [ + "etp38" + ], + "2x400G": [ + "etp38a", + "etp38b" + ], + "4x200G": [ + "etp38a", + "etp38b", + "etp38c", + "etp38d" + ], + "8x100G": [ + "etp38a", + "etp38b", + "etp38c", + "etp38d", + "etp38e", + "etp38f", + "etp38g", + "etp38h" + ] + } + }, + "Ethernet304": { + "index": "39,39,39,39,39,39,39,39", + "lanes": "65,66,67,68,69,70,71,72", + "breakout_modes": { + "1x800G": [ + "etp39" + ], + "2x400G": [ + "etp39a", + "etp39b" + ], + "4x200G": [ + "etp39a", + "etp39b", + "etp39c", + "etp39d" + ], + "8x100G": [ + "etp39a", + "etp39b", + "etp39c", + "etp39d", + "etp39e", + "etp39f", + "etp39g", + "etp39h" + ] + } + }, + "Ethernet312": { + "index": "40,40,40,40,40,40,40,40", + "lanes": "97,98,99,100,101,102,103,104", + "breakout_modes": { + "1x800G": [ + "etp40" + ], + "2x400G": [ + "etp40a", + "etp40b" + ], + "4x200G": [ + "etp40a", + "etp40b", + "etp40c", + "etp40d" + ], + "8x100G": [ + "etp40a", + "etp40b", + "etp40c", + "etp40d", + "etp40e", + "etp40f", + "etp40g", + "etp40h" + ] + } + }, + "Ethernet320": { + "index": "41,41,41,41,41,41,41,41", + "lanes": "153,154,155,156,157,158,159,160", + "breakout_modes": { + "1x800G": [ + "etp41" + ], + "2x400G": [ + "etp41a", + "etp41b" + ], + "4x200G": [ + "etp41a", + "etp41b", + "etp41c", + "etp41d" + ], + "8x100G": [ + "etp41a", + "etp41b", + "etp41c", + "etp41d", + "etp41e", + "etp41f", + "etp41g", + "etp41h" + ] + } + }, + "Ethernet328": { + "index": "42,42,42,42,42,42,42,42", + "lanes": "145,146,147,148,149,150,151,152", + "breakout_modes": { + "1x800G": [ + "etp42" + ], + "2x400G": [ + "etp42a", + "etp42b" + ], + "4x200G": [ + "etp42a", + "etp42b", + "etp42c", + "etp42d" + ], + "8x100G": [ + "etp42a", + "etp42b", + "etp42c", + "etp42d", + "etp42e", + "etp42f", + "etp42g", + "etp42h" + ] + } + }, + "Ethernet336": { + "index": "43,43,43,43,43,43,43,43", + "lanes": "321,322,323,324,325,326,327,328", + "breakout_modes": { + "1x800G": [ + "etp43" + ], + "2x400G": [ + "etp43a", + "etp43b" + ], + "4x200G": [ + "etp43a", + "etp43b", + "etp43c", + "etp43d" + ], + "8x100G": [ + "etp43a", + "etp43b", + "etp43c", + "etp43d", + "etp43e", + "etp43f", + "etp43g", + "etp43h" + ] + } + }, + "Ethernet344": { + "index": "44,44,44,44,44,44,44,44", + "lanes": "353,354,355,356,357,358,359,360", + "breakout_modes": { + "1x800G": [ + "etp44" + ], + "2x400G": [ + "etp44a", + "etp44b" + ], + "4x200G": [ + "etp44a", + "etp44b", + "etp44c", + "etp44d" + ], + "8x100G": [ + "etp44a", + "etp44b", + "etp44c", + "etp44d", + "etp44e", + "etp44f", + "etp44g", + "etp44h" + ] + } + }, + "Ethernet352": { + "index": "45,45,45,45,45,45,45,45", + "lanes": "409,410,411,412,413,414,415,416", + "breakout_modes": { + "1x800G": [ + "etp45" + ], + "2x400G": [ + "etp45a", + "etp45b" + ], + "4x200G": [ + "etp45a", + "etp45b", + "etp45c", + "etp45d" + ], + "8x100G": [ + "etp45a", + "etp45b", + "etp45c", + "etp45d", + "etp45e", + "etp45f", + "etp45g", + "etp45h" + ] + } + }, + "Ethernet360": { + "index": "46,46,46,46,46,46,46,46", + "lanes": "401,402,403,404,405,406,407,408", + "breakout_modes": { + "1x800G": [ + "etp46" + ], + "2x400G": [ + "etp46a", + "etp46b" + ], + "4x200G": [ + "etp46a", + "etp46b", + "etp46c", + "etp46d" + ], + "8x100G": [ + "etp46a", + "etp46b", + "etp46c", + "etp46d", + "etp46e", + "etp46f", + "etp46g", + "etp46h" + ] + } + }, + "Ethernet368": { + "index": "47,47,47,47,47,47,47,47", + "lanes": "393,394,395,396,397,398,399,400", + "breakout_modes": { + "1x800G": [ + "etp47" + ], + "2x400G": [ + "etp47a", + "etp47b" + ], + "4x200G": [ + "etp47a", + "etp47b", + "etp47c", + "etp47d" + ], + "8x100G": [ + "etp47a", + "etp47b", + "etp47c", + "etp47d", + "etp47e", + "etp47f", + "etp47g", + "etp47h" + ] + } + }, + "Ethernet376": { + "index": "48,48,48,48,48,48,48,48", + "lanes": "433,434,435,436,437,438,439,440", + "breakout_modes": { + "1x800G": [ + "etp48" + ], + "2x400G": [ + "etp48a", + "etp48b" + ], + "4x200G": [ + "etp48a", + "etp48b", + "etp48c", + "etp48d" + ], + "8x100G": [ + "etp48a", + "etp48b", + "etp48c", + "etp48d", + "etp48e", + "etp48f", + "etp48g", + "etp48h" + ] + } + }, + "Ethernet384": { + "index": "49,49,49,49,49,49,49,49", + "lanes": "585,586,587,588,589,590,591,592", + "breakout_modes": { + "1x800G": [ + "etp49" + ], + "2x400G": [ + "etp49a", + "etp49b" + ], + "4x200G": [ + "etp49a", + "etp49b", + "etp49c", + "etp49d" + ], + "8x100G": [ + "etp49a", + "etp49b", + "etp49c", + "etp49d", + "etp49e", + "etp49f", + "etp49g", + "etp49h" + ] + } + }, + "Ethernet392": { + "index": "50,50,50,50,50,50,50,50", + "lanes": "625,626,627,628,629,630,631,632", + "breakout_modes": { + "1x800G": [ + "etp50" + ], + "2x400G": [ + "etp50a", + "etp50b" + ], + "4x200G": [ + "etp50a", + "etp50b", + "etp50c", + "etp50d" + ], + "8x100G": [ + "etp50a", + "etp50b", + "etp50c", + "etp50d", + "etp50e", + "etp50f", + "etp50g", + "etp50h" + ] + } + }, + "Ethernet400": { + "index": "51,51,51,51,51,51,51,51", + "lanes": "601,602,603,604,605,606,607,608", + "breakout_modes": { + "1x800G": [ + "etp51" + ], + "2x400G": [ + "etp51a", + "etp51b" + ], + "4x200G": [ + "etp51a", + "etp51b", + "etp51c", + "etp51d" + ], + "8x100G": [ + "etp51a", + "etp51b", + "etp51c", + "etp51d", + "etp51e", + "etp51f", + "etp51g", + "etp51h" + ] + } + }, + "Ethernet408": { + "index": "52,52,52,52,52,52,52,52", + "lanes": "593,594,595,596,597,598,599,600", + "breakout_modes": { + "1x800G": [ + "etp52" + ], + "2x400G": [ + "etp52a", + "etp52b" + ], + "4x200G": [ + "etp52a", + "etp52b", + "etp52c", + "etp52d" + ], + "8x100G": [ + "etp52a", + "etp52b", + "etp52c", + "etp52d", + "etp52e", + "etp52f", + "etp52g", + "etp52h" + ] + } + }, + "Ethernet416": { + "index": "53,53,53,53,53,53,53,53", + "lanes": "641,642,643,644,645,646,647,648", + "breakout_modes": { + "1x800G": [ + "etp53" + ], + "2x400G": [ + "etp53a", + "etp53b" + ], + "4x200G": [ + "etp53a", + "etp53b", + "etp53c", + "etp53d" + ], + "8x100G": [ + "etp53a", + "etp53b", + "etp53c", + "etp53d", + "etp53e", + "etp53f", + "etp53g", + "etp53h" + ] + } + }, + "Ethernet424": { + "index": "54,54,54,54,54,54,54,54", + "lanes": "673,674,675,676,677,678,679,680", + "breakout_modes": { + "1x800G": [ + "etp54" + ], + "2x400G": [ + "etp54a", + "etp54b" + ], + "4x200G": [ + "etp54a", + "etp54b", + "etp54c", + "etp54d" + ], + "8x100G": [ + "etp54a", + "etp54b", + "etp54c", + "etp54d", + "etp54e", + "etp54f", + "etp54g", + "etp54h" + ] + } + }, + "Ethernet432": { + "index": "55,55,55,55,55,55,55,55", + "lanes": "857,858,859,860,861,862,863,864", + "breakout_modes": { + "1x800G": [ + "etp55" + ], + "2x400G": [ + "etp55a", + "etp55b" + ], + "4x200G": [ + "etp55a", + "etp55b", + "etp55c", + "etp55d" + ], + "8x100G": [ + "etp55a", + "etp55b", + "etp55c", + "etp55d", + "etp55e", + "etp55f", + "etp55g", + "etp55h" + ] + } + }, + "Ethernet440": { + "index": "56,56,56,56,56,56,56,56", + "lanes": "849,850,851,852,853,854,855,856", + "breakout_modes": { + "1x800G": [ + "etp56" + ], + "2x400G": [ + "etp56a", + "etp56b" + ], + "4x200G": [ + "etp56a", + "etp56b", + "etp56c", + "etp56d" + ], + "8x100G": [ + "etp56a", + "etp56b", + "etp56c", + "etp56d", + "etp56e", + "etp56f", + "etp56g", + "etp56h" + ] + } + }, + "Ethernet448": { + "index": "57,57,57,57,57,57,57,57", + "lanes": "897,898,899,900,901,902,903,904", + "breakout_modes": { + "1x800G": [ + "etp57" + ], + "2x400G": [ + "etp57a", + "etp57b" + ], + "4x200G": [ + "etp57a", + "etp57b", + "etp57c", + "etp57d" + ], + "8x100G": [ + "etp57a", + "etp57b", + "etp57c", + "etp57d", + "etp57e", + "etp57f", + "etp57g", + "etp57h" + ] + } + }, + "Ethernet456": { + "index": "58,58,58,58,58,58,58,58", + "lanes": "929,930,931,932,933,934,935,936", + "breakout_modes": { + "1x800G": [ + "etp58" + ], + "2x400G": [ + "etp58a", + "etp58b" + ], + "4x200G": [ + "etp58a", + "etp58b", + "etp58c", + "etp58d" + ], + "8x100G": [ + "etp58a", + "etp58b", + "etp58c", + "etp58d", + "etp58e", + "etp58f", + "etp58g", + "etp58h" + ] + } + }, + "Ethernet464": { + "index": "59,59,59,59,59,59,59,59", + "lanes": "953,954,955,956,957,958,959,960", + "breakout_modes": { + "1x800G": [ + "etp59" + ], + "2x400G": [ + "etp59a", + "etp59b" + ], + "4x200G": [ + "etp59a", + "etp59b", + "etp59c", + "etp59d" + ], + "8x100G": [ + "etp59a", + "etp59b", + "etp59c", + "etp59d", + "etp59e", + "etp59f", + "etp59g", + "etp59h" + ] + } + }, + "Ethernet472": { + "index": "60,60,60,60,60,60,60,60", + "lanes": "937,938,939,940,941,942,943,944", + "breakout_modes": { + "1x800G": [ + "etp60" + ], + "2x400G": [ + "etp60a", + "etp60b" + ], + "4x200G": [ + "etp60a", + "etp60b", + "etp60c", + "etp60d" + ], + "8x100G": [ + "etp60a", + "etp60b", + "etp60c", + "etp60d", + "etp60e", + "etp60f", + "etp60g", + "etp60h" + ] + } + }, + "Ethernet480": { + "index": "61,61,61,61,61,61,61,61", + "lanes": "1001,1002,1003,1004,1005,1006,1007,1008", + "breakout_modes": { + "1x800G": [ + "etp61" + ], + "2x400G": [ + "etp61a", + "etp61b" + ], + "4x200G": [ + "etp61a", + "etp61b", + "etp61c", + "etp61d" + ], + "8x100G": [ + "etp61a", + "etp61b", + "etp61c", + "etp61d", + "etp61e", + "etp61f", + "etp61g", + "etp61h" + ] + } + }, + "Ethernet488": { + "index": "62,62,62,62,62,62,62,62", + "lanes": "1017,1018,1019,1020,1021,1022,1023,1024", + "breakout_modes": { + "1x800G": [ + "etp62" + ], + "2x400G": [ + "etp62a", + "etp62b" + ], + "4x200G": [ + "etp62a", + "etp62b", + "etp62c", + "etp62d" + ], + "8x100G": [ + "etp62a", + "etp62b", + "etp62c", + "etp62d", + "etp62e", + "etp62f", + "etp62g", + "etp62h" + ] + } + }, + "Ethernet496": { + "index": "63,63,63,63,63,63,63,63", + "lanes": "993,994,995,996,997,998,999,1000", + "breakout_modes": { + "1x800G": [ + "etp63" + ], + "2x400G": [ + "etp63a", + "etp63b" + ], + "4x200G": [ + "etp63a", + "etp63b", + "etp63c", + "etp63d" + ], + "8x100G": [ + "etp63a", + "etp63b", + "etp63c", + "etp63d", + "etp63e", + "etp63f", + "etp63g", + "etp63h" + ] + } + }, + "Ethernet504": { + "index": "64,64,64,64,64,64,64,64", + "lanes": "961,962,963,964,965,966,967,968", + "breakout_modes": { + "1x800G": [ + "etp64" + ], + "2x400G": [ + "etp64a", + "etp64b" + ], + "4x200G": [ + "etp64a", + "etp64b", + "etp64c", + "etp64d" + ], + "8x100G": [ + "etp64a", + "etp64b", + "etp64c", + "etp64d", + "etp64e", + "etp64f", + "etp64g", + "etp64h" + ] + } + }, + "Ethernet512": { + "index": "65,65,65,65,65,65,65,65", + "lanes": "17,18,19,20,21,22,23,24", + "breakout_modes": { + "1x800G": [ + "etp65" + ], + "2x400G": [ + "etp65a", + "etp65b" + ], + "4x200G": [ + "etp65a", + "etp65b", + "etp65c", + "etp65d" + ], + "8x100G": [ + "etp65a", + "etp65b", + "etp65c", + "etp65d", + "etp65e", + "etp65f", + "etp65g", + "etp65h" + ] + } + }, + "Ethernet520": { + "index": "66,66,66,66,66,66,66,66", + "lanes": "25,26,27,28,29,30,31,32", + "breakout_modes": { + "1x800G": [ + "etp66" + ], + "2x400G": [ + "etp66a", + "etp66b" + ], + "4x200G": [ + "etp66a", + "etp66b", + "etp66c", + "etp66d" + ], + "8x100G": [ + "etp66a", + "etp66b", + "etp66c", + "etp66d", + "etp66e", + "etp66f", + "etp66g", + "etp66h" + ] + } + }, + "Ethernet528": { + "index": "67,67,67,67,67,67,67,67", + "lanes": "49,50,51,52,53,54,55,56", + "breakout_modes": { + "1x800G": [ + "etp67" + ], + "2x400G": [ + "etp67a", + "etp67b" + ], + "4x200G": [ + "etp67a", + "etp67b", + "etp67c", + "etp67d" + ], + "8x100G": [ + "etp67a", + "etp67b", + "etp67c", + "etp67d", + "etp67e", + "etp67f", + "etp67g", + "etp67h" + ] + } + }, + "Ethernet536": { + "index": "68,68,68,68,68,68,68,68", + "lanes": "9,10,11,12,13,14,15,16", + "breakout_modes": { + "1x800G": [ + "etp68" + ], + "2x400G": [ + "etp68a", + "etp68b" + ], + "4x200G": [ + "etp68a", + "etp68b", + "etp68c", + "etp68d" + ], + "8x100G": [ + "etp68a", + "etp68b", + "etp68c", + "etp68d", + "etp68e", + "etp68f", + "etp68g", + "etp68h" + ] + } + }, + "Ethernet544": { + "index": "69,69,69,69,69,69,69,69", + "lanes": "73,74,75,76,77,78,79,80", + "breakout_modes": { + "1x800G": [ + "etp69" + ], + "2x400G": [ + "etp69a", + "etp69b" + ], + "4x200G": [ + "etp69a", + "etp69b", + "etp69c", + "etp69d" + ], + "8x100G": [ + "etp69a", + "etp69b", + "etp69c", + "etp69d", + "etp69e", + "etp69f", + "etp69g", + "etp69h" + ] + } + }, + "Ethernet552": { + "index": "70,70,70,70,70,70,70,70", + "lanes": "113,114,115,116,117,118,119,120", + "breakout_modes": { + "1x800G": [ + "etp70" + ], + "2x400G": [ + "etp70a", + "etp70b" + ], + "4x200G": [ + "etp70a", + "etp70b", + "etp70c", + "etp70d" + ], + "8x100G": [ + "etp70a", + "etp70b", + "etp70c", + "etp70d", + "etp70e", + "etp70f", + "etp70g", + "etp70h" + ] + } + }, + "Ethernet560": { + "index": "71,71,71,71,71,71,71,71", + "lanes": "89,90,91,92,93,94,95,96", + "breakout_modes": { + "1x800G": [ + "etp71" + ], + "2x400G": [ + "etp71a", + "etp71b" + ], + "4x200G": [ + "etp71a", + "etp71b", + "etp71c", + "etp71d" + ], + "8x100G": [ + "etp71a", + "etp71b", + "etp71c", + "etp71d", + "etp71e", + "etp71f", + "etp71g", + "etp71h" + ] + } + }, + "Ethernet568": { + "index": "72,72,72,72,72,72,72,72", + "lanes": "81,82,83,84,85,86,87,88", + "breakout_modes": { + "1x800G": [ + "etp72" + ], + "2x400G": [ + "etp72a", + "etp72b" + ], + "4x200G": [ + "etp72a", + "etp72b", + "etp72c", + "etp72d" + ], + "8x100G": [ + "etp72a", + "etp72b", + "etp72c", + "etp72d", + "etp72e", + "etp72f", + "etp72g", + "etp72h" + ] + } + }, + "Ethernet576": { + "index": "73,73,73,73,73,73,73,73", + "lanes": "129,130,131,132,133,134,135,136", + "breakout_modes": { + "1x800G": [ + "etp73" + ], + "2x400G": [ + "etp73a", + "etp73b" + ], + "4x200G": [ + "etp73a", + "etp73b", + "etp73c", + "etp73d" + ], + "8x100G": [ + "etp73a", + "etp73b", + "etp73c", + "etp73d", + "etp73e", + "etp73f", + "etp73g", + "etp73h" + ] + } + }, + "Ethernet584": { + "index": "74,74,74,74,74,74,74,74", + "lanes": "161,162,163,164,165,166,167,168", + "breakout_modes": { + "1x800G": [ + "etp74" + ], + "2x400G": [ + "etp74a", + "etp74b" + ], + "4x200G": [ + "etp74a", + "etp74b", + "etp74c", + "etp74d" + ], + "8x100G": [ + "etp74a", + "etp74b", + "etp74c", + "etp74d", + "etp74e", + "etp74f", + "etp74g", + "etp74h" + ] + } + }, + "Ethernet592": { + "index": "75,75,75,75,75,75,75,75", + "lanes": "345,346,347,348,349,350,351,352", + "breakout_modes": { + "1x800G": [ + "etp75" + ], + "2x400G": [ + "etp75a", + "etp75b" + ], + "4x200G": [ + "etp75a", + "etp75b", + "etp75c", + "etp75d" + ], + "8x100G": [ + "etp75a", + "etp75b", + "etp75c", + "etp75d", + "etp75e", + "etp75f", + "etp75g", + "etp75h" + ] + } + }, + "Ethernet600": { + "index": "76,76,76,76,76,76,76,76", + "lanes": "337,338,339,340,341,342,343,344", + "breakout_modes": { + "1x800G": [ + "etp76" + ], + "2x400G": [ + "etp76a", + "etp76b" + ], + "4x200G": [ + "etp76a", + "etp76b", + "etp76c", + "etp76d" + ], + "8x100G": [ + "etp76a", + "etp76b", + "etp76c", + "etp76d", + "etp76e", + "etp76f", + "etp76g", + "etp76h" + ] + } + }, + "Ethernet608": { + "index": "77,77,77,77,77,77,77,77", + "lanes": "385,386,387,388,389,390,391,392", + "breakout_modes": { + "1x800G": [ + "etp77" + ], + "2x400G": [ + "etp77a", + "etp77b" + ], + "4x200G": [ + "etp77a", + "etp77b", + "etp77c", + "etp77d" + ], + "8x100G": [ + "etp77a", + "etp77b", + "etp77c", + "etp77d", + "etp77e", + "etp77f", + "etp77g", + "etp77h" + ] + } + }, + "Ethernet616": { + "index": "78,78,78,78,78,78,78,78", + "lanes": "417,418,419,420,421,422,423,424", + "breakout_modes": { + "1x800G": [ + "etp78" + ], + "2x400G": [ + "etp78a", + "etp78b" + ], + "4x200G": [ + "etp78a", + "etp78b", + "etp78c", + "etp78d" + ], + "8x100G": [ + "etp78a", + "etp78b", + "etp78c", + "etp78d", + "etp78e", + "etp78f", + "etp78g", + "etp78h" + ] + } + }, + "Ethernet624": { + "index": "79,79,79,79,79,79,79,79", + "lanes": "441,442,443,444,445,446,447,448", + "breakout_modes": { + "1x800G": [ + "etp79" + ], + "2x400G": [ + "etp79a", + "etp79b" + ], + "4x200G": [ + "etp79a", + "etp79b", + "etp79c", + "etp79d" + ], + "8x100G": [ + "etp79a", + "etp79b", + "etp79c", + "etp79d", + "etp79e", + "etp79f", + "etp79g", + "etp79h" + ] + } + }, + "Ethernet632": { + "index": "80,80,80,80,80,80,80,80", + "lanes": "425,426,427,428,429,430,431,432", + "breakout_modes": { + "1x800G": [ + "etp80" + ], + "2x400G": [ + "etp80a", + "etp80b" + ], + "4x200G": [ + "etp80a", + "etp80b", + "etp80c", + "etp80d" + ], + "8x100G": [ + "etp80a", + "etp80b", + "etp80c", + "etp80d", + "etp80e", + "etp80f", + "etp80g", + "etp80h" + ] + } + }, + "Ethernet640": { + "index": "81,81,81,81,81,81,81,81", + "lanes": "633,634,635,636,637,638,639,640", + "breakout_modes": { + "1x800G": [ + "etp81" + ], + "2x400G": [ + "etp81a", + "etp81b" + ], + "4x200G": [ + "etp81a", + "etp81b", + "etp81c", + "etp81d" + ], + "8x100G": [ + "etp81a", + "etp81b", + "etp81c", + "etp81d", + "etp81e", + "etp81f", + "etp81g", + "etp81h" + ] + } + }, + "Ethernet648": { + "index": "82,82,82,82,82,82,82,82", + "lanes": "617,618,619,620,621,622,623,624", + "breakout_modes": { + "1x800G": [ + "etp82" + ], + "2x400G": [ + "etp82a", + "etp82b" + ], + "4x200G": [ + "etp82a", + "etp82b", + "etp82c", + "etp82d" + ], + "8x100G": [ + "etp82a", + "etp82b", + "etp82c", + "etp82d", + "etp82e", + "etp82f", + "etp82g", + "etp82h" + ] + } + }, + "Ethernet656": { + "index": "83,83,83,83,83,83,83,83", + "lanes": "577,578,579,580,581,582,583,584", + "breakout_modes": { + "1x800G": [ + "etp83" + ], + "2x400G": [ + "etp83a", + "etp83b" + ], + "4x200G": [ + "etp83a", + "etp83b", + "etp83c", + "etp83d" + ], + "8x100G": [ + "etp83a", + "etp83b", + "etp83c", + "etp83d", + "etp83e", + "etp83f", + "etp83g", + "etp83h" + ] + } + }, + "Ethernet664": { + "index": "84,84,84,84,84,84,84,84", + "lanes": "609,610,611,612,613,614,615,616", + "breakout_modes": { + "1x800G": [ + "etp84" + ], + "2x400G": [ + "etp84a", + "etp84b" + ], + "4x200G": [ + "etp84a", + "etp84b", + "etp84c", + "etp84d" + ], + "8x100G": [ + "etp84a", + "etp84b", + "etp84c", + "etp84d", + "etp84e", + "etp84f", + "etp84g", + "etp84h" + ] + } + }, + "Ethernet672": { + "index": "85,85,85,85,85,85,85,85", + "lanes": "665,666,667,668,669,670,671,672", + "breakout_modes": { + "1x800G": [ + "etp85" + ], + "2x400G": [ + "etp85a", + "etp85b" + ], + "4x200G": [ + "etp85a", + "etp85b", + "etp85c", + "etp85d" + ], + "8x100G": [ + "etp85a", + "etp85b", + "etp85c", + "etp85d", + "etp85e", + "etp85f", + "etp85g", + "etp85h" + ] + } + }, + "Ethernet680": { + "index": "86,86,86,86,86,86,86,86", + "lanes": "657,658,659,660,661,662,663,664", + "breakout_modes": { + "1x800G": [ + "etp86" + ], + "2x400G": [ + "etp86a", + "etp86b" + ], + "4x200G": [ + "etp86a", + "etp86b", + "etp86c", + "etp86d" + ], + "8x100G": [ + "etp86a", + "etp86b", + "etp86c", + "etp86d", + "etp86e", + "etp86f", + "etp86g", + "etp86h" + ] + } + }, + "Ethernet688": { + "index": "87,87,87,87,87,87,87,87", + "lanes": "833,834,835,836,837,838,839,840", + "breakout_modes": { + "1x800G": [ + "etp87" + ], + "2x400G": [ + "etp87a", + "etp87b" + ], + "4x200G": [ + "etp87a", + "etp87b", + "etp87c", + "etp87d" + ], + "8x100G": [ + "etp87a", + "etp87b", + "etp87c", + "etp87d", + "etp87e", + "etp87f", + "etp87g", + "etp87h" + ] + } + }, + "Ethernet696": { + "index": "88,88,88,88,88,88,88,88", + "lanes": "865,866,867,868,869,870,871,872", + "breakout_modes": { + "1x800G": [ + "etp88" + ], + "2x400G": [ + "etp88a", + "etp88b" + ], + "4x200G": [ + "etp88a", + "etp88b", + "etp88c", + "etp88d" + ], + "8x100G": [ + "etp88a", + "etp88b", + "etp88c", + "etp88d", + "etp88e", + "etp88f", + "etp88g", + "etp88h" + ] + } + }, + "Ethernet704": { + "index": "89,89,89,89,89,89,89,89", + "lanes": "921,922,923,924,925,926,927,928", + "breakout_modes": { + "1x800G": [ + "etp89" + ], + "2x400G": [ + "etp89a", + "etp89b" + ], + "4x200G": [ + "etp89a", + "etp89b", + "etp89c", + "etp89d" + ], + "8x100G": [ + "etp89a", + "etp89b", + "etp89c", + "etp89d", + "etp89e", + "etp89f", + "etp89g", + "etp89h" + ] + } + }, + "Ethernet712": { + "index": "90,90,90,90,90,90,90,90", + "lanes": "913,914,915,916,917,918,919,920", + "breakout_modes": { + "1x800G": [ + "etp90" + ], + "2x400G": [ + "etp90a", + "etp90b" + ], + "4x200G": [ + "etp90a", + "etp90b", + "etp90c", + "etp90d" + ], + "8x100G": [ + "etp90a", + "etp90b", + "etp90c", + "etp90d", + "etp90e", + "etp90f", + "etp90g", + "etp90h" + ] + } + }, + "Ethernet720": { + "index": "91,91,91,91,91,91,91,91", + "lanes": "905,906,907,908,909,910,911,912", + "breakout_modes": { + "1x800G": [ + "etp91" + ], + "2x400G": [ + "etp91a", + "etp91b" + ], + "4x200G": [ + "etp91a", + "etp91b", + "etp91c", + "etp91d" + ], + "8x100G": [ + "etp91a", + "etp91b", + "etp91c", + "etp91d", + "etp91e", + "etp91f", + "etp91g", + "etp91h" + ] + } + }, + "Ethernet728": { + "index": "92,92,92,92,92,92,92,92", + "lanes": "945,946,947,948,949,950,951,952", + "breakout_modes": { + "1x800G": [ + "etp92" + ], + "2x400G": [ + "etp92a", + "etp92b" + ], + "4x200G": [ + "etp92a", + "etp92b", + "etp92c", + "etp92d" + ], + "8x100G": [ + "etp92a", + "etp92b", + "etp92c", + "etp92d", + "etp92e", + "etp92f", + "etp92g", + "etp92h" + ] + } + }, + "Ethernet736": { + "index": "93,93,93,93,93,93,93,93", + "lanes": "1009,1010,1011,1012,1013,1014,1015,1016", + "breakout_modes": { + "1x800G": [ + "etp93" + ], + "2x400G": [ + "etp93a", + "etp93b" + ], + "4x200G": [ + "etp93a", + "etp93b", + "etp93c", + "etp93d" + ], + "8x100G": [ + "etp93a", + "etp93b", + "etp93c", + "etp93d", + "etp93e", + "etp93f", + "etp93g", + "etp93h" + ] + } + }, + "Ethernet744": { + "index": "94,94,94,94,94,94,94,94", + "lanes": "969,970,971,972,973,974,975,976", + "breakout_modes": { + "1x800G": [ + "etp94" + ], + "2x400G": [ + "etp94a", + "etp94b" + ], + "4x200G": [ + "etp94a", + "etp94b", + "etp94c", + "etp94d" + ], + "8x100G": [ + "etp94a", + "etp94b", + "etp94c", + "etp94d", + "etp94e", + "etp94f", + "etp94g", + "etp94h" + ] + } + }, + "Ethernet752": { + "index": "95,95,95,95,95,95,95,95", + "lanes": "977,978,979,980,981,982,983,984", + "breakout_modes": { + "1x800G": [ + "etp95" + ], + "2x400G": [ + "etp95a", + "etp95b" + ], + "4x200G": [ + "etp95a", + "etp95b", + "etp95c", + "etp95d" + ], + "8x100G": [ + "etp95a", + "etp95b", + "etp95c", + "etp95d", + "etp95e", + "etp95f", + "etp95g", + "etp95h" + ] + } + }, + "Ethernet760": { + "index": "96,96,96,96,96,96,96,96", + "lanes": "985,986,987,988,989,990,991,992", + "breakout_modes": { + "1x800G": [ + "etp96" + ], + "2x400G": [ + "etp96a", + "etp96b" + ], + "4x200G": [ + "etp96a", + "etp96b", + "etp96c", + "etp96d" + ], + "8x100G": [ + "etp96a", + "etp96b", + "etp96c", + "etp96d", + "etp96e", + "etp96f", + "etp96g", + "etp96h" + ] + } + }, + "Ethernet768": { + "index": "97,97,97,97,97,97,97,97", + "lanes": "209,210,211,212,213,214,215,216", + "breakout_modes": { + "1x800G": [ + "etp97" + ], + "2x400G": [ + "etp97a", + "etp97b" + ], + "4x200G": [ + "etp97a", + "etp97b", + "etp97c", + "etp97d" + ], + "8x100G": [ + "etp97a", + "etp97b", + "etp97c", + "etp97d", + "etp97e", + "etp97f", + "etp97g", + "etp97h" + ] + } + }, + "Ethernet776": { + "index": "98,98,98,98,98,98,98,98", + "lanes": "193,194,195,196,197,198,199,200", + "breakout_modes": { + "1x800G": [ + "etp98" + ], + "2x400G": [ + "etp98a", + "etp98b" + ], + "4x200G": [ + "etp98a", + "etp98b", + "etp98c", + "etp98d" + ], + "8x100G": [ + "etp98a", + "etp98b", + "etp98c", + "etp98d", + "etp98e", + "etp98f", + "etp98g", + "etp98h" + ] + } + }, + "Ethernet784": { + "index": "99,99,99,99,99,99,99,99", + "lanes": "225,226,227,228,229,230,231,232", + "breakout_modes": { + "1x800G": [ + "etp99" + ], + "2x400G": [ + "etp99a", + "etp99b" + ], + "4x200G": [ + "etp99a", + "etp99b", + "etp99c", + "etp99d" + ], + "8x100G": [ + "etp99a", + "etp99b", + "etp99c", + "etp99d", + "etp99e", + "etp99f", + "etp99g", + "etp99h" + ] + } + }, + "Ethernet792": { + "index": "100,100,100,100,100,100,100,100", + "lanes": "217,218,219,220,221,222,223,224", + "breakout_modes": { + "1x800G": [ + "etp100" + ], + "2x400G": [ + "etp100a", + "etp100b" + ], + "4x200G": [ + "etp100a", + "etp100b", + "etp100c", + "etp100d" + ], + "8x100G": [ + "etp100a", + "etp100b", + "etp100c", + "etp100d", + "etp100e", + "etp100f", + "etp100g", + "etp100h" + ] + } + }, + "Ethernet800": { + "index": "101,101,101,101,101,101,101,101", + "lanes": "281,282,283,284,285,286,287,288", + "breakout_modes": { + "1x800G": [ + "etp101" + ], + "2x400G": [ + "etp101a", + "etp101b" + ], + "4x200G": [ + "etp101a", + "etp101b", + "etp101c", + "etp101d" + ], + "8x100G": [ + "etp101a", + "etp101b", + "etp101c", + "etp101d", + "etp101e", + "etp101f", + "etp101g", + "etp101h" + ] + } + }, + "Ethernet808": { + "index": "102,102,102,102,102,102,102,102", + "lanes": "289,290,291,292,293,294,295,296", + "breakout_modes": { + "1x800G": [ + "etp102" + ], + "2x400G": [ + "etp102a", + "etp102b" + ], + "4x200G": [ + "etp102a", + "etp102b", + "etp102c", + "etp102d" + ], + "8x100G": [ + "etp102a", + "etp102b", + "etp102c", + "etp102d", + "etp102e", + "etp102f", + "etp102g", + "etp102h" + ] + } + }, + "Ethernet816": { + "index": "103,103,103,103,103,103,103,103", + "lanes": "257,258,259,260,261,262,263,264", + "breakout_modes": { + "1x800G": [ + "etp103" + ], + "2x400G": [ + "etp103a", + "etp103b" + ], + "4x200G": [ + "etp103a", + "etp103b", + "etp103c", + "etp103d" + ], + "8x100G": [ + "etp103a", + "etp103b", + "etp103c", + "etp103d", + "etp103e", + "etp103f", + "etp103g", + "etp103h" + ] + } + }, + "Ethernet824": { + "index": "104,104,104,104,104,104,104,104", + "lanes": "273,274,275,276,277,278,279,280", + "breakout_modes": { + "1x800G": [ + "etp104" + ], + "2x400G": [ + "etp104a", + "etp104b" + ], + "4x200G": [ + "etp104a", + "etp104b", + "etp104c", + "etp104d" + ], + "8x100G": [ + "etp104a", + "etp104b", + "etp104c", + "etp104d", + "etp104e", + "etp104f", + "etp104g", + "etp104h" + ] + } + }, + "Ethernet832": { + "index": "105,105,105,105,105,105,105,105", + "lanes": "201,202,203,204,205,206,207,208", + "breakout_modes": { + "1x800G": [ + "etp105" + ], + "2x400G": [ + "etp105a", + "etp105b" + ], + "4x200G": [ + "etp105a", + "etp105b", + "etp105c", + "etp105d" + ], + "8x100G": [ + "etp105a", + "etp105b", + "etp105c", + "etp105d", + "etp105e", + "etp105f", + "etp105g", + "etp105h" + ] + } + }, + "Ethernet840": { + "index": "106,106,106,106,106,106,106,106", + "lanes": "233,234,235,236,237,238,239,240", + "breakout_modes": { + "1x800G": [ + "etp106" + ], + "2x400G": [ + "etp106a", + "etp106b" + ], + "4x200G": [ + "etp106a", + "etp106b", + "etp106c", + "etp106d" + ], + "8x100G": [ + "etp106a", + "etp106b", + "etp106c", + "etp106d", + "etp106e", + "etp106f", + "etp106g", + "etp106h" + ] + } + }, + "Ethernet848": { + "index": "107,107,107,107,107,107,107,107", + "lanes": "241,242,243,244,245,246,247,248", + "breakout_modes": { + "1x800G": [ + "etp107" + ], + "2x400G": [ + "etp107a", + "etp107b" + ], + "4x200G": [ + "etp107a", + "etp107b", + "etp107c", + "etp107d" + ], + "8x100G": [ + "etp107a", + "etp107b", + "etp107c", + "etp107d", + "etp107e", + "etp107f", + "etp107g", + "etp107h" + ] + } + }, + "Ethernet856": { + "index": "108,108,108,108,108,108,108,108", + "lanes": "249,250,251,252,253,254,255,256", + "breakout_modes": { + "1x800G": [ + "etp108" + ], + "2x400G": [ + "etp108a", + "etp108b" + ], + "4x200G": [ + "etp108a", + "etp108b", + "etp108c", + "etp108d" + ], + "8x100G": [ + "etp108a", + "etp108b", + "etp108c", + "etp108d", + "etp108e", + "etp108f", + "etp108g", + "etp108h" + ] + } + }, + "Ethernet864": { + "index": "109,109,109,109,109,109,109,109", + "lanes": "185,186,187,188,189,190,191,192", + "breakout_modes": { + "1x800G": [ + "etp109" + ], + "2x400G": [ + "etp109a", + "etp109b" + ], + "4x200G": [ + "etp109a", + "etp109b", + "etp109c", + "etp109d" + ], + "8x100G": [ + "etp109a", + "etp109b", + "etp109c", + "etp109d", + "etp109e", + "etp109f", + "etp109g", + "etp109h" + ] + } + }, + "Ethernet872": { + "index": "110,110,110,110,110,110,110,110", + "lanes": "177,178,179,180,181,182,183,184", + "breakout_modes": { + "1x800G": [ + "etp110" + ], + "2x400G": [ + "etp110a", + "etp110b" + ], + "4x200G": [ + "etp110a", + "etp110b", + "etp110c", + "etp110d" + ], + "8x100G": [ + "etp110a", + "etp110b", + "etp110c", + "etp110d", + "etp110e", + "etp110f", + "etp110g", + "etp110h" + ] + } + }, + "Ethernet880": { + "index": "111,111,111,111,111,111,111,111", + "lanes": "169,170,171,172,173,174,175,176", + "breakout_modes": { + "1x800G": [ + "etp111" + ], + "2x400G": [ + "etp111a", + "etp111b" + ], + "4x200G": [ + "etp111a", + "etp111b", + "etp111c", + "etp111d" + ], + "8x100G": [ + "etp111a", + "etp111b", + "etp111c", + "etp111d", + "etp111e", + "etp111f", + "etp111g", + "etp111h" + ] + } + }, + "Ethernet888": { + "index": "112,112,112,112,112,112,112,112", + "lanes": "137,138,139,140,141,142,143,144", + "breakout_modes": { + "1x800G": [ + "etp112" + ], + "2x400G": [ + "etp112a", + "etp112b" + ], + "4x200G": [ + "etp112a", + "etp112b", + "etp112c", + "etp112d" + ], + "8x100G": [ + "etp112a", + "etp112b", + "etp112c", + "etp112d", + "etp112e", + "etp112f", + "etp112g", + "etp112h" + ] + } + }, + "Ethernet896": { + "index": "113,113,113,113,113,113,113,113", + "lanes": "841,842,843,844,845,846,847,848", + "breakout_modes": { + "1x800G": [ + "etp113" + ], + "2x400G": [ + "etp113a", + "etp113b" + ], + "4x200G": [ + "etp113a", + "etp113b", + "etp113c", + "etp113d" + ], + "8x100G": [ + "etp113a", + "etp113b", + "etp113c", + "etp113d", + "etp113e", + "etp113f", + "etp113g", + "etp113h" + ] + } + }, + "Ethernet904": { + "index": "114,114,114,114,114,114,114,114", + "lanes": "873,874,875,876,877,878,879,880", + "breakout_modes": { + "1x800G": [ + "etp114" + ], + "2x400G": [ + "etp114a", + "etp114b" + ], + "4x200G": [ + "etp114a", + "etp114b", + "etp114c", + "etp114d" + ], + "8x100G": [ + "etp114a", + "etp114b", + "etp114c", + "etp114d", + "etp114e", + "etp114f", + "etp114g", + "etp114h" + ] + } + }, + "Ethernet912": { + "index": "115,115,115,115,115,115,115,115", + "lanes": "881,882,883,884,885,886,887,888", + "breakout_modes": { + "1x800G": [ + "etp115" + ], + "2x400G": [ + "etp115a", + "etp115b" + ], + "4x200G": [ + "etp115a", + "etp115b", + "etp115c", + "etp115d" + ], + "8x100G": [ + "etp115a", + "etp115b", + "etp115c", + "etp115d", + "etp115e", + "etp115f", + "etp115g", + "etp115h" + ] + } + }, + "Ethernet920": { + "index": "116,116,116,116,116,116,116,116", + "lanes": "889,890,891,892,893,894,895,896", + "breakout_modes": { + "1x800G": [ + "etp116" + ], + "2x400G": [ + "etp116a", + "etp116b" + ], + "4x200G": [ + "etp116a", + "etp116b", + "etp116c", + "etp116d" + ], + "8x100G": [ + "etp116a", + "etp116b", + "etp116c", + "etp116d", + "etp116e", + "etp116f", + "etp116g", + "etp116h" + ] + } + }, + "Ethernet928": { + "index": "117,117,117,117,117,117,117,117", + "lanes": "825,826,827,828,829,830,831,832", + "breakout_modes": { + "1x800G": [ + "etp117" + ], + "2x400G": [ + "etp117a", + "etp117b" + ], + "4x200G": [ + "etp117a", + "etp117b", + "etp117c", + "etp117d" + ], + "8x100G": [ + "etp117a", + "etp117b", + "etp117c", + "etp117d", + "etp117e", + "etp117f", + "etp117g", + "etp117h" + ] + } + }, + "Ethernet936": { + "index": "118,118,118,118,118,118,118,118", + "lanes": "817,818,819,820,821,822,823,824", + "breakout_modes": { + "1x800G": [ + "etp118" + ], + "2x400G": [ + "etp118a", + "etp118b" + ], + "4x200G": [ + "etp118a", + "etp118b", + "etp118c", + "etp118d" + ], + "8x100G": [ + "etp118a", + "etp118b", + "etp118c", + "etp118d", + "etp118e", + "etp118f", + "etp118g", + "etp118h" + ] + } + }, + "Ethernet944": { + "index": "119,119,119,119,119,119,119,119", + "lanes": "809,810,811,812,813,814,815,816", + "breakout_modes": { + "1x800G": [ + "etp119" + ], + "2x400G": [ + "etp119a", + "etp119b" + ], + "4x200G": [ + "etp119a", + "etp119b", + "etp119c", + "etp119d" + ], + "8x100G": [ + "etp119a", + "etp119b", + "etp119c", + "etp119d", + "etp119e", + "etp119f", + "etp119g", + "etp119h" + ] + } + }, + "Ethernet952": { + "index": "120,120,120,120,120,120,120,120", + "lanes": "777,778,779,780,781,782,783,784", + "breakout_modes": { + "1x800G": [ + "etp120" + ], + "2x400G": [ + "etp120a", + "etp120b" + ], + "4x200G": [ + "etp120a", + "etp120b", + "etp120c", + "etp120d" + ], + "8x100G": [ + "etp120a", + "etp120b", + "etp120c", + "etp120d", + "etp120e", + "etp120f", + "etp120g", + "etp120h" + ] + } + }, + "Ethernet960": { + "index": "121,121,121,121,121,121,121,121", + "lanes": "721,722,723,724,725,726,727,728", + "breakout_modes": { + "1x800G": [ + "etp121" + ], + "2x400G": [ + "etp121a", + "etp121b" + ], + "4x200G": [ + "etp121a", + "etp121b", + "etp121c", + "etp121d" + ], + "8x100G": [ + "etp121a", + "etp121b", + "etp121c", + "etp121d", + "etp121e", + "etp121f", + "etp121g", + "etp121h" + ] + } + }, + "Ethernet968": { + "index": "122,122,122,122,122,122,122,122", + "lanes": "705,706,707,708,709,710,711,712", + "breakout_modes": { + "1x800G": [ + "etp122" + ], + "2x400G": [ + "etp122a", + "etp122b" + ], + "4x200G": [ + "etp122a", + "etp122b", + "etp122c", + "etp122d" + ], + "8x100G": [ + "etp122a", + "etp122b", + "etp122c", + "etp122d", + "etp122e", + "etp122f", + "etp122g", + "etp122h" + ] + } + }, + "Ethernet976": { + "index": "123,123,123,123,123,123,123,123", + "lanes": "737,738,739,740,741,742,743,744", + "breakout_modes": { + "1x800G": [ + "etp123" + ], + "2x400G": [ + "etp123a", + "etp123b" + ], + "4x200G": [ + "etp123a", + "etp123b", + "etp123c", + "etp123d" + ], + "8x100G": [ + "etp123a", + "etp123b", + "etp123c", + "etp123d", + "etp123e", + "etp123f", + "etp123g", + "etp123h" + ] + } + }, + "Ethernet984": { + "index": "124,124,124,124,124,124,124,124", + "lanes": "729,730,731,732,733,734,735,736", + "breakout_modes": { + "1x800G": [ + "etp124" + ], + "2x400G": [ + "etp124a", + "etp124b" + ], + "4x200G": [ + "etp124a", + "etp124b", + "etp124c", + "etp124d" + ], + "8x100G": [ + "etp124a", + "etp124b", + "etp124c", + "etp124d", + "etp124e", + "etp124f", + "etp124g", + "etp124h" + ] + } + }, + "Ethernet992": { + "index": "125,125,125,125,125,125,125,125", + "lanes": "793,794,795,796,797,798,799,800", + "breakout_modes": { + "1x800G": [ + "etp125" + ], + "2x400G": [ + "etp125a", + "etp125b" + ], + "4x200G": [ + "etp125a", + "etp125b", + "etp125c", + "etp125d" + ], + "8x100G": [ + "etp125a", + "etp125b", + "etp125c", + "etp125d", + "etp125e", + "etp125f", + "etp125g", + "etp125h" + ] + } + }, + "Ethernet1000": { + "index": "126,126,126,126,126,126,126,126", + "lanes": "801,802,803,804,805,806,807,808", + "breakout_modes": { + "1x800G": [ + "etp126" + ], + "2x400G": [ + "etp126a", + "etp126b" + ], + "4x200G": [ + "etp126a", + "etp126b", + "etp126c", + "etp126d" + ], + "8x100G": [ + "etp126a", + "etp126b", + "etp126c", + "etp126d", + "etp126e", + "etp126f", + "etp126g", + "etp126h" + ] + } + }, + "Ethernet1008": { + "index": "127,127,127,127,127,127,127,127", + "lanes": "785,786,787,788,789,790,791,792", + "breakout_modes": { + "1x800G": [ + "etp127" + ], + "2x400G": [ + "etp127a", + "etp127b" + ], + "4x200G": [ + "etp127a", + "etp127b", + "etp127c", + "etp127d" + ], + "8x100G": [ + "etp127a", + "etp127b", + "etp127c", + "etp127d", + "etp127e", + "etp127f", + "etp127g", + "etp127h" + ] + } + }, + "Ethernet1016": { + "index": "128,128,128,128,128,128,128,128", + "lanes": "769,770,771,772,773,774,775,776", + "breakout_modes": { + "1x800G": [ + "etp128" + ], + "2x400G": [ + "etp128a", + "etp128b" + ], + "4x200G": [ + "etp128a", + "etp128b", + "etp128c", + "etp128d" + ], + "8x100G": [ + "etp128a", + "etp128b", + "etp128c", + "etp128d", + "etp128e", + "etp128f", + "etp128g", + "etp128h" + ] + } + }, + "Ethernet1024": { + "index": "129,129,129,129", + "lanes": "1026,1027,1028,1029", + "breakout_modes": { + "1x100G": [ + "etp129" + ] + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_asic b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_asic new file mode 100644 index 0000000000..9604676527 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_components.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_components.json new file mode 100644 index 0000000000..029922ab31 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_components.json @@ -0,0 +1,19 @@ +{ + "chassis": { + "M2-W6950-O128": { + "component": { + "CPU_CPLD": { }, + "MGMT_CPLD": { }, + "MAC_CPLD_A": { }, + "MAC_CPLD_B": { }, + "MAC_CPLD_C": { }, + "UPORT_CPLD": { }, + "DPORT_CPLD": { }, + "UFAN_CPLD": { }, + "DFAN_CPLD": { }, + "MAC_CPLD_D": { }, + "BIOS": { } + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env.conf b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env.conf new file mode 100644 index 0000000000..75bc013788 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env.conf @@ -0,0 +1,3 @@ +is_ltsw_chip=1 +SYNCD_SHM_SIZE=1g +switch_host=1 \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env_fac.conf b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env_fac.conf new file mode 100644 index 0000000000..3a14dd8bd5 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/platform_env_fac.conf @@ -0,0 +1 @@ +sdkmsg=1 diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/eeprom.py b/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/eeprom.py new file mode 100644 index 0000000000..697bd2332b --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/eeprom.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +try: + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/sfputil.py b/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/sfputil.py new file mode 100644 index 0000000000..b38a1befe2 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/sfputil.py @@ -0,0 +1,379 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + import traceback + import subprocess + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 129 + PORTS_IN_BLOCK = 129 + + EEPROM_OFFSET = 201 + SFP_DEVICE_TYPE = "optoe2" + QSFP_DEVICE_TYPE = "optoe1" + QSFP_DD_DEVICE_TYPE = "optoe3" + I2C_MAX_ATTEMPT = 3 + + OPTOE_TYPE1 = 1 + OPTOE_TYPE2 = 2 + OPTOE_TYPE3 = 3 + + SFP_STATUS_INSERTED = '1' + SFP_STATUS_REMOVED = '0' + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping ={} + port_dict = {} + + qsfp_ports_list = [] + qsfp_dd_ports_list = [] + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return self.qsfp_ports_list + + @property + def qsfp_dd_ports(self): + return self.qsfp_dd_ports_list + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + for x in range(self.PORT_START, self.PORTS_IN_BLOCK-2): + self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + self.port_to_i2cbus_mapping[128] = 329 + self.port_to_i2cbus_mapping[129] = 330 + self.update_ports_list() + + SfpUtilBase.__init__(self) + + def _sfp_read_file_path(self, file_path, offset, num_bytes): + attempts = 0 + while attempts < self.I2C_MAX_ATTEMPT: + try: + file_path.seek(offset) + read_buf = file_path.read(num_bytes) + except: + attempts += 1 + time.sleep(0.05) + else: + return True, read_buf + return False, None + + def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): + """Tries to read the eeprom file to determine if the + device/sfp is present or not. If sfp present, the read returns + valid bytes. If not, read returns error 'Connection timed out""" + + if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): + return False + else: + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv + + def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): + try: + sysfs_nd_path = "%s/device/new_device" % sysfs_sfp_i2c_adapter_path + + # Write device address to new_device file + nd_file = open(sysfs_nd_path, "w") + nd_str = "%s %s" % (devtype, hex(devaddr)) + nd_file.write(nd_str) + nd_file.close() + + except Exception as err: + print("Error writing to new device file: %s" % str(err)) + return 1 + else: + return 0 + + def _get_port_eeprom_path(self, port_num, devid): + return "/sys/s3ip/transceiver/eth%d/eeprom" % (port_num + 1) + + # def _get_port_eeprom_path(self, port_num, devid): + # sysfs_i2c_adapter_base_path = "/sys/class/i2c-dev" + + # if port_num in self.port_to_eeprom_mapping.keys(): + # sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] + # else: + # sysfs_i2c_adapter_base_path = "/sys/class/i2c-dev" + + # i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + # if i2c_adapter_id is None: + # print("Error getting i2c bus num") + # return None + + # # Get i2c virtual bus path for the sfp + # sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + # str(i2c_adapter_id)) + + # # If i2c bus for port does not exist + # if not os.path.exists(sysfs_sfp_i2c_adapter_path): + # print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + # return None + + # sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + # str(i2c_adapter_id), + # hex(devid)[-2:]) + + # # If sfp device is not present on bus, Add it + # if not os.path.exists(sysfs_sfp_i2c_client_path): + # if port_num in self.qsfp_dd_ports: + # ret = self._add_new_sfp_device( + # sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DD_DEVICE_TYPE) + # elif port_num in self.qsfp_ports: + # ret = self._add_new_sfp_device( + # sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE) + # else: + # ret = self._add_new_sfp_device( + # sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE) + # if ret != 0: + # print("Error adding sfp device") + # return None + + # sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + # return sysfs_sfp_i2c_client_eeprom_path + + def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) + if rv == False: + return None + + try: + if len(raw) == 0: + return None + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except: + return None + + return eeprom_raw + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.qsfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + cmd = "cat /sys/s3ip/transceiver/eth{}/present".format(str(port_num + 1)) + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + return False + if output == "1": + return True + return False + + def check_is_qsfpdd(self, port_num): + try: + if self.get_presence(port_num) == False: + return False + + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, 0, 1) + if eeprom_raw is None: + return False + # according to sff-8024 A0h Byte 0 is '1e','18' or '19' means the transceiver is qsfpdd, + if (eeprom_raw[0] == '1e' or eeprom_raw[0] == '18' or eeprom_raw[0] == '19'): + return True + except Exception as e: + print(traceback.format_exc()) + + return False + + def check_optoe_type(self, port_num, optoe_type): + if self.get_presence(port_num) == False: + return True + try: + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + dev_class_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/dev_class' + i2c_path = dev_class_path.format(str(self.port_to_i2cbus_mapping[port_num])) + cmd = "cat " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + if int(output) != optoe_type: + cmd = "echo " + str(optoe_type) + " > " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + return True + + except Exception as e: + print(traceback.format_exc()) + return False + + def update_ports_list(self): + self.qsfp_ports_list = [] + self.qsfp_dd_ports_list = [] + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + if (self.check_is_qsfpdd(x)): + self.qsfp_dd_ports_list.append(x) + else: + self.qsfp_ports_list.append(x) + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return True + + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + current_port_dict = {} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print ("get_transceiver_change_event:Invalid timeout value", timeout) + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print ('get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout) + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + # Check for OIR events and return updated port_dict + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(x): + current_port_dict[x] = self.SFP_STATUS_INSERTED + else: + current_port_dict[x] = self.SFP_STATUS_REMOVED + if (current_port_dict == self.port_dict): + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + self.update_ports_list() + return True, {} + else: + # Update reg value + self.update_ports_list() + self.port_dict = current_port_dict + return True, self.port_dict + print ("get_transceiver_change_event: Should not reach here.") + return False, {} + + def _twos_comp(self, num, bits): + try: + if ((num & (1 << (bits - 1))) != 0): + num = num - (1 << bits) + return num + except: + return 0 + + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 + + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False + + for port in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(port) == False: + continue + + presence_flag = True + + if port in self.qsfp_dd_ports: + offset = 14 + elif port in self.qsfp_ports: + offset = 22 + else: + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + if len(eeprom_raw) != 0: + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self._twos_comp(result, 16) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + if hightest_temperature < result: + hightest_temperature = result + except Exception as e: + pass + + # all port not presence + if presence_flag == False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag == False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag == True and temperature_valid_flag == False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/ssd_util.py b/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/ssd_util.py new file mode 100644 index 0000000000..d7f62b2dc6 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/plugins/ssd_util.py @@ -0,0 +1,318 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_storage.storage_base import StorageBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(StorageBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : r"\n190\s+(.+?)\n", "remainingLife" : r"\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : r"\n194\s+(.+?)\n", "remainingLife" : r"\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : r"\n194\s+(.+?)\n", "remainingLife" : r"\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : r"\n194\s+(.+?)\n", "remainingLife" : r"\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : r"\n190\s+(.+?)\n", "remainingLife" : r"\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : r"\n194\s+(.+?)\n", "remainingLife" : r"\n231\s+(.+?)\n" }, + "MTFDDAV240TCB-1AR1ZABAA" : { "temperature" : r"\n194\s+(.+?)\n", "remainingLife" : r"\n202\s+(.+?)\n" }, + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = r"[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re(r'Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re(r'Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re(r'Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re(r'Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re(r'\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re(r'SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re(r'Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re(r'Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re(r'Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re(r'Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re(r'Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re(r'NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re(r'Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + # Invalid avg_erase_count or nand_endurance. + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + if self.health == 'N/A': + return "NA" + else: + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + if self.temperature == 'N/A': + return 'NA' + else: + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re(r'{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/pmon_daemon_control.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..6716a121a9 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6950-128oc-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "include_sensormond": true +} diff --git a/device/micas/x86_64-micas_m2-w6950-128oc-r0/system_health_monitoring_config.json b/device/micas/x86_64-micas_m2-w6950-128oc-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/hwsku.json b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/hwsku.json new file mode 100644 index 0000000000..c4428af812 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/hwsku.json @@ -0,0 +1,333 @@ +{ + "interfaces": { + "Ethernet1": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet9": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet17": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet25": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet33": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet41": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet49": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet57": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet65": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet73": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet81": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet89": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet97": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet105": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet113": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet121": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet129": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet137": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet145": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet153": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet161": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet169": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet177": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet185": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet193": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet201": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet209": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet217": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet225": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet233": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet241": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet249": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet257": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet265": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet273": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet281": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet289": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet297": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet305": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet313": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet321": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet329": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet337": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet345": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet353": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet361": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet369": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet377": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet385": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet393": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet401": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet409": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet417": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet425": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet433": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet441": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet449": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet457": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet465": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet473": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet481": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet489": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet497": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet505": { + "default_brkout_mode": "1x1600G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet513": { + "default_brkout_mode": "1x25G", + "fec": "none" + }, + "Ethernet514": { + "default_brkout_mode": "1x25G", + "fec": "none" + } + } +} + diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/port_config.ini b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/port_config.ini new file mode 100644 index 0000000000..7b240d8e81 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/port_config.ini @@ -0,0 +1,67 @@ +# name lanes alias index speed +Ethernet1 121,122,123,124,125,126,127,128 sixteenhundredGigE0/1 0 1600000 +Ethernet9 65,66,67,68,69,70,71,72 sixteenhundredGigE0/2 1 1600000 +Ethernet17 129,130,131,132,133,134,135,136 sixteenhundredGigE0/3 2 1600000 +Ethernet25 137,138,139,140,141,142,143,144 sixteenhundredGigE0/4 3 1600000 +Ethernet33 113,114,115,116,117,118,119,120 sixteenhundredGigE0/5 4 1600000 +Ethernet41 73,74,75,76,77,78,79,80 sixteenhundredGigE0/6 5 1600000 +Ethernet49 145,146,147,148,149,150,151,152 sixteenhundredGigE0/7 6 1600000 +Ethernet57 153,154,155,156,157,158,159,160 sixteenhundredGigE0/8 7 1600000 +Ethernet65 105,106,107,108,109,110,111,112 sixteenhundredGigE0/9 8 1600000 +Ethernet73 81,82,83,84,85,86,87,88 sixteenhundredGigE0/10 9 1600000 +Ethernet81 185,186,187,188,189,190,191,192 sixteenhundredGigE0/11 10 1600000 +Ethernet89 177,178,179,180,181,182,183,184 sixteenhundredGigE0/12 11 1600000 +Ethernet97 97,98,99,100,101,102,103,104 sixteenhundredGigE0/13 12 1600000 +Ethernet105 89,90,91,92,93,94,95,96 sixteenhundredGigE0/14 13 1600000 +Ethernet113 169,170,171,172,173,174,175,176 sixteenhundredGigE0/15 14 1600000 +Ethernet121 161,162,163,164,165,166,167,168 sixteenhundredGigE0/16 15 1600000 +Ethernet129 25,26,27,28,29,30,31,32 sixteenhundredGigE0/17 16 1600000 +Ethernet137 33,34,35,36,37,38,39,40 sixteenhundredGigE0/18 17 1600000 +Ethernet145 193,194,195,196,197,198,199,200 sixteenhundredGigE0/19 18 1600000 +Ethernet153 201,202,203,204,205,206,207,208 sixteenhundredGigE0/20 19 1600000 +Ethernet161 17,18,19,20,21,22,23,24 sixteenhundredGigE0/21 20 1600000 +Ethernet169 41,42,43,44,45,46,47,48 sixteenhundredGigE0/22 21 1600000 +Ethernet177 209,210,211,212,213,214,215,216 sixteenhundredGigE0/23 22 1600000 +Ethernet185 217,218,219,220,221,222,223,224 sixteenhundredGigE0/24 23 1600000 +Ethernet193 9,10,11,12,13,14,15,16 sixteenhundredGigE0/25 24 1600000 +Ethernet201 49,50,51,52,53,54,55,56 sixteenhundredGigE0/26 25 1600000 +Ethernet209 249,250,251,252,253,254,255,256 sixteenhundredGigE0/27 26 1600000 +Ethernet217 241,242,243,244,245,246,247,248 sixteenhundredGigE0/28 27 1600000 +Ethernet225 1,2,3,4,5,6,7,8 sixteenhundredGigE0/29 28 1600000 +Ethernet233 57,58,59,60,61,62,63,64 sixteenhundredGigE0/30 29 1600000 +Ethernet241 233,234,235,236,237,238,239,240 sixteenhundredGigE0/31 30 1600000 +Ethernet249 225,226,227,228,229,230,231,232 sixteenhundredGigE0/32 31 1600000 +Ethernet257 481,482,483,484,485,486,487,488 sixteenhundredGigE0/33 32 1600000 +Ethernet265 473,474,475,476,477,478,479,480 sixteenhundredGigE0/34 33 1600000 +Ethernet273 257,258,259,260,261,262,263,264 sixteenhundredGigE0/35 34 1600000 +Ethernet281 265,266,267,268,269,270,271,272 sixteenhundredGigE0/36 35 1600000 +Ethernet289 489,490,491,492,493,494,495,496 sixteenhundredGigE0/37 36 1600000 +Ethernet297 465,466,467,468,469,470,471,472 sixteenhundredGigE0/38 37 1600000 +Ethernet305 273,274,275,276,277,278,279,280 sixteenhundredGigE0/39 38 1600000 +Ethernet313 281,282,283,284,285,286,287,288 sixteenhundredGigE0/40 39 1600000 +Ethernet321 497,498,499,500,501,502,503,504 sixteenhundredGigE0/41 40 1600000 +Ethernet329 457,458,459,460,461,462,463,464 sixteenhundredGigE0/42 41 1600000 +Ethernet337 313,314,315,316,317,318,319,320 sixteenhundredGigE0/43 42 1600000 +Ethernet345 305,306,307,308,309,310,311,312 sixteenhundredGigE0/44 43 1600000 +Ethernet353 505,506,507,508,509,510,511,512 sixteenhundredGigE0/45 44 1600000 +Ethernet361 449,450,451,452,453,454,455,456 sixteenhundredGigE0/46 45 1600000 +Ethernet369 297,298,299,300,301,302,303,304 sixteenhundredGigE0/47 46 1600000 +Ethernet377 289,290,291,292,293,294,295,296 sixteenhundredGigE0/48 47 1600000 +Ethernet385 385,386,387,388,389,390,391,392 sixteenhundredGigE0/49 48 1600000 +Ethernet393 441,442,443,444,445,446,447,448 sixteenhundredGigE0/50 49 1600000 +Ethernet401 321,322,323,324,325,326,327,328 sixteenhundredGigE0/51 50 1600000 +Ethernet409 329,330,331,332,333,334,335,336 sixteenhundredGigE0/52 51 1600000 +Ethernet417 393,394,395,396,397,398,399,400 sixteenhundredGigE0/53 52 1600000 +Ethernet425 433,434,435,436,437,438,439,440 sixteenhundredGigE0/54 53 1600000 +Ethernet433 337,338,339,340,341,342,343,344 sixteenhundredGigE0/55 54 1600000 +Ethernet441 345,346,347,348,349,350,351,352 sixteenhundredGigE0/56 55 1600000 +Ethernet449 401,402,403,404,405,406,407,408 sixteenhundredGigE0/57 56 1600000 +Ethernet457 425,426,427,428,429,430,431,432 sixteenhundredGigE0/58 57 1600000 +Ethernet465 377,378,379,380,381,382,383,384 sixteenhundredGigE0/59 58 1600000 +Ethernet473 369,370,371,372,373,374,375,376 sixteenhundredGigE0/60 59 1600000 +Ethernet481 409,410,411,412,413,414,415,416 sixteenhundredGigE0/61 60 1600000 +Ethernet489 417,418,419,420,421,422,423,424 sixteenhundredGigE0/62 61 1600000 +Ethernet497 361,362,363,364,365,366,367,368 sixteenhundredGigE0/63 62 1600000 +Ethernet505 353,354,355,356,357,358,359,360 sixteenhundredGigE0/64 63 1600000 +Ethernet513 514 twentyfiveGigE0/65 64 25000 +Ethernet514 517 twentyfiveGigE0/66 65 25000 diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/sai.profile b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/sai.profile new file mode 100644 index 0000000000..9bde461edc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th6-m2-w6951-64hc-cp-64x1600G.config.yml \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/th6-m2-w6951-64hc-cp-64x1600G.config.yml b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/th6-m2-w6951-64hc-cp-64x1600G.config.yml new file mode 100644 index 0000000000..91a7752b0c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/M2-W6951-64HC-CP/th6-m2-w6951-64hc-cp-64x1600G.config.yml @@ -0,0 +1,1169 @@ +--- +device: + 0: + DEVICE_CONFIG: + AUTOLOAD_BOARD_SETTINGS: 0 +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46572031 + RX_LANE_MAP: 0x20317654 + TX_POLARITY_FLIP: 0x35 + RX_POLARITY_FLIP: 0xc7 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64750213 + RX_LANE_MAP: 0x02136745 + TX_POLARITY_FLIP: 0x3a + RX_POLARITY_FLIP: 0xcb + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64750213 + RX_LANE_MAP: 0x02136745 + TX_POLARITY_FLIP: 0x3a + RX_POLARITY_FLIP: 0xcb + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64750213 + RX_LANE_MAP: 0x02136745 + TX_POLARITY_FLIP: 0x38 + RX_POLARITY_FLIP: 0xcb + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03125647 + RX_LANE_MAP: 0x74653021 + TX_POLARITY_FLIP: 0xcc + RX_POLARITY_FLIP: 0x2b + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106574 + RX_LANE_MAP: 0x65741032 + TX_POLARITY_FLIP: 0xbc + RX_POLARITY_FLIP: 0x43 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106574 + RX_LANE_MAP: 0x65741032 + TX_POLARITY_FLIP: 0xbc + RX_POLARITY_FLIP: 0x43 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32015647 + RX_LANE_MAP: 0x56470123 + TX_POLARITY_FLIP: 0x7c + RX_POLARITY_FLIP: 0x83 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30216574 + RX_LANE_MAP: 0x47560312 + TX_POLARITY_FLIP: 0x33 + RX_POLARITY_FLIP: 0xac + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x75640213 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x75640213 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x75640213 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0xb3 + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651023 + RX_LANE_MAP: 0x32107465 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0xc1 + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651023 + RX_LANE_MAP: 0x32107465 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0xc1 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651023 + RX_LANE_MAP: 0x32107465 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0xc1 + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560132 + RX_LANE_MAP: 0x23014756 + TX_POLARITY_FLIP: 0x39 + RX_POLARITY_FLIP: 0xc2 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651032 + RX_LANE_MAP: 0x25130476 + TX_POLARITY_FLIP: 0x3a + RX_POLARITY_FLIP: 0xc8 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x70516243 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0x9b + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651032 + RX_LANE_MAP: 0x25130476 + TX_POLARITY_FLIP: 0x3a + RX_POLARITY_FLIP: 0xc8 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x70516243 + TX_POLARITY_FLIP: 0x53 + RX_POLARITY_FLIP: 0x9b + ? + PC_PM_ID: 21 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30216574 + RX_LANE_MAP: 0x40715362 + TX_POLARITY_FLIP: 0x33 + RX_POLARITY_FLIP: 0xe8 + ? + PC_PM_ID: 22 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560132 + RX_LANE_MAP: 0x16230754 + TX_POLARITY_FLIP: 0x39 + RX_POLARITY_FLIP: 0x32 + ? + PC_PM_ID: 23 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32015647 + RX_LANE_MAP: 0x50624173 + TX_POLARITY_FLIP: 0x93 + RX_POLARITY_FLIP: 0x6e + ? + PC_PM_ID: 24 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560132 + RX_LANE_MAP: 0x16230754 + TX_POLARITY_FLIP: 0x39 + RX_POLARITY_FLIP: 0x32 + ? + PC_PM_ID: 25 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47561203 + RX_LANE_MAP: 0x04213576 + TX_POLARITY_FLIP: 0x33 + RX_POLARITY_FLIP: 0x33 + ? + PC_PM_ID: 26 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x70516243 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x9b + ? + PC_PM_ID: 27 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651032 + RX_LANE_MAP: 0x25130476 + TX_POLARITY_FLIP: 0x32 + RX_POLARITY_FLIP: 0xc8 + ? + PC_PM_ID: 28 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x70516243 + TX_POLARITY_FLIP: 0x73 + RX_POLARITY_FLIP: 0x9b + ? + PC_PM_ID: 29 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x31205746 + RX_LANE_MAP: 0x53427160 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 30 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46572031 + RX_LANE_MAP: 0x14203657 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 31 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x31205746 + RX_LANE_MAP: 0x53427160 + TX_POLARITY_FLIP: 0xa0 + RX_POLARITY_FLIP: 0x19 + ? + PC_PM_ID: 32 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46572031 + RX_LANE_MAP: 0x14203657 + TX_POLARITY_FLIP: 0xf4 + RX_POLARITY_FLIP: 0xce + ? + PC_PM_ID: 33 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64750213 + RX_LANE_MAP: 0x35021746 + TX_POLARITY_FLIP: 0x05 + RX_POLARITY_FLIP: 0x34 + ? + PC_PM_ID: 34 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027564 + RX_LANE_MAP: 0x41506372 + TX_POLARITY_FLIP: 0xaf + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 35 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64750213 + RX_LANE_MAP: 0x35021746 + TX_POLARITY_FLIP: 0x05 + RX_POLARITY_FLIP: 0x34 + ? + PC_PM_ID: 36 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x13027564 + RX_LANE_MAP: 0x41506372 + TX_POLARITY_FLIP: 0x2f + RX_POLARITY_FLIP: 0xec + ? + PC_PM_ID: 37 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30216574 + RX_LANE_MAP: 0x40715362 + TX_POLARITY_FLIP: 0xcc + RX_POLARITY_FLIP: 0x33 + ? + PC_PM_ID: 38 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560123 + RX_LANE_MAP: 0x07312654 + TX_POLARITY_FLIP: 0xce + RX_POLARITY_FLIP: 0x75 + ? + PC_PM_ID: 39 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015647 + RX_LANE_MAP: 0x52734061 + TX_POLARITY_FLIP: 0x4c + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 40 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560123 + RX_LANE_MAP: 0x07312654 + TX_POLARITY_FLIP: 0xce + RX_POLARITY_FLIP: 0x75 + ? + PC_PM_ID: 41 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47561203 + RX_LANE_MAP: 0x04213576 + TX_POLARITY_FLIP: 0xcc + RX_POLARITY_FLIP: 0xc6 + ? + PC_PM_ID: 42 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106574 + RX_LANE_MAP: 0x61537042 + TX_POLARITY_FLIP: 0x9c + RX_POLARITY_FLIP: 0x31 + ? + PC_PM_ID: 43 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651023 + RX_LANE_MAP: 0x05321467 + TX_POLARITY_FLIP: 0xc9 + RX_POLARITY_FLIP: 0x8f + ? + PC_PM_ID: 44 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23106574 + RX_LANE_MAP: 0x61537042 + TX_POLARITY_FLIP: 0x9c + RX_POLARITY_FLIP: 0x31 + ? + PC_PM_ID: 45 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015647 + RX_LANE_MAP: 0x52734061 + TX_POLARITY_FLIP: 0x5c + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 46 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560123 + RX_LANE_MAP: 0x07312654 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x75 + ? + PC_PM_ID: 47 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015647 + RX_LANE_MAP: 0x52734061 + TX_POLARITY_FLIP: 0x5c + RX_POLARITY_FLIP: 0xc4 + ? + PC_PM_ID: 48 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560123 + RX_LANE_MAP: 0x07312654 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x75 + ? + PC_PM_ID: 49 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74651023 + RX_LANE_MAP: 0x32107465 + TX_POLARITY_FLIP: 0xc9 + RX_POLARITY_FLIP: 0x3e + ? + PC_PM_ID: 50 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560132 + RX_LANE_MAP: 0x23014756 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0x3d + ? + PC_PM_ID: 51 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560132 + RX_LANE_MAP: 0x23014756 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0x3d + ? + PC_PM_ID: 52 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x47560132 + RX_LANE_MAP: 0x23014756 + TX_POLARITY_FLIP: 0xc6 + RX_POLARITY_FLIP: 0x3d + ? + PC_PM_ID: 53 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x30216574 + RX_LANE_MAP: 0x47560312 + TX_POLARITY_FLIP: 0xcc + RX_POLARITY_FLIP: 0x53 + ? + PC_PM_ID: 54 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015647 + RX_LANE_MAP: 0x57462031 + TX_POLARITY_FLIP: 0x5c + RX_POLARITY_FLIP: 0x8c + ? + PC_PM_ID: 55 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015647 + RX_LANE_MAP: 0x57462031 + TX_POLARITY_FLIP: 0x5c + RX_POLARITY_FLIP: 0x8c + ? + PC_PM_ID: 56 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32106574 + RX_LANE_MAP: 0x75640213 + TX_POLARITY_FLIP: 0xac + RX_POLARITY_FLIP: 0x4c + ? + PC_PM_ID: 57 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03125647 + RX_LANE_MAP: 0x74653021 + TX_POLARITY_FLIP: 0x33 + RX_POLARITY_FLIP: 0xd4 + ? + PC_PM_ID: 58 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32015647 + RX_LANE_MAP: 0x56470123 + TX_POLARITY_FLIP: 0x83 + RX_POLARITY_FLIP: 0x7c + ? + PC_PM_ID: 59 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32015647 + RX_LANE_MAP: 0x56470123 + TX_POLARITY_FLIP: 0x83 + RX_POLARITY_FLIP: 0x7c + ? + PC_PM_ID: 60 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32015647 + RX_LANE_MAP: 0x56470123 + TX_POLARITY_FLIP: 0x83 + RX_POLARITY_FLIP: 0x7c + ? + PC_PM_ID: 61 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46572031 + RX_LANE_MAP: 0x20317654 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 62 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46572031 + RX_LANE_MAP: 0x20317654 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 63 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x46572031 + RX_LANE_MAP: 0x20317654 + TX_POLARITY_FLIP: 0xca + RX_POLARITY_FLIP: 0x38 + ? + PC_PM_ID: 64 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x64750213 + RX_LANE_MAP: 0x02136745 + TX_POLARITY_FLIP: 0xc7 + RX_POLARITY_FLIP: 0x34 + ? + PC_PM_ID: 65 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x3012 + RX_LANE_MAP: 0x2103 + TX_POLARITY_FLIP: 0x00 + RX_POLARITY_FLIP: 0x01 +... + + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 16 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 33 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 51 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 69 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 86 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 87 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 104 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 105 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 122 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 123 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 140 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 141 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 158 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 159 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 176 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 177 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 194 + : + PC_PHYS_PORT_ID: 161 + ? + PORT_ID: 195 + : + PC_PHYS_PORT_ID: 169 + ? + PORT_ID: 212 + : + PC_PHYS_PORT_ID: 177 + ? + PORT_ID: 213 + : + PC_PHYS_PORT_ID: 185 + ? + PORT_ID: 230 + : + PC_PHYS_PORT_ID: 193 + ? + PORT_ID: 231 + : + PC_PHYS_PORT_ID: 201 + ? + PORT_ID: 248 + : + PC_PHYS_PORT_ID: 209 + ? + PORT_ID: 249 + : + PC_PHYS_PORT_ID: 217 + ? + PORT_ID: 266 + : + PC_PHYS_PORT_ID: 225 + ? + PORT_ID: 267 + : + PC_PHYS_PORT_ID: 233 + ? + PORT_ID: 284 + : + PC_PHYS_PORT_ID: 241 + ? + PORT_ID: 285 + : + PC_PHYS_PORT_ID: 249 + ? + PORT_ID: 302 + : + PC_PHYS_PORT_ID: 257 + ? + PORT_ID: 303 + : + PC_PHYS_PORT_ID: 265 + ? + PORT_ID: 320 + : + PC_PHYS_PORT_ID: 273 + ? + PORT_ID: 321 + : + PC_PHYS_PORT_ID: 281 + ? + PORT_ID: 338 + : + PC_PHYS_PORT_ID: 289 + ? + PORT_ID: 339 + : + PC_PHYS_PORT_ID: 297 + ? + PORT_ID: 356 + : + PC_PHYS_PORT_ID: 305 + ? + PORT_ID: 357 + : + PC_PHYS_PORT_ID: 313 + ? + PORT_ID: 374 + : + PC_PHYS_PORT_ID: 321 + ? + PORT_ID: 375 + : + PC_PHYS_PORT_ID: 329 + ? + PORT_ID: 392 + : + PC_PHYS_PORT_ID: 337 + ? + PORT_ID: 393 + : + PC_PHYS_PORT_ID: 345 + ? + PORT_ID: 410 + : + PC_PHYS_PORT_ID: 353 + ? + PORT_ID: 411 + : + PC_PHYS_PORT_ID: 361 + ? + PORT_ID: 428 + : + PC_PHYS_PORT_ID: 369 + ? + PORT_ID: 429 + : + PC_PHYS_PORT_ID: 377 + ? + PORT_ID: 446 + : + PC_PHYS_PORT_ID: 385 + ? + PORT_ID: 447 + : + PC_PHYS_PORT_ID: 393 + ? + PORT_ID: 464 + : + PC_PHYS_PORT_ID: 401 + ? + PORT_ID: 465 + : + PC_PHYS_PORT_ID: 409 + ? + PORT_ID: 482 + : + PC_PHYS_PORT_ID: 417 + ? + PORT_ID: 483 + : + PC_PHYS_PORT_ID: 425 + ? + PORT_ID: 500 + : + PC_PHYS_PORT_ID: 433 + ? + PORT_ID: 501 + : + PC_PHYS_PORT_ID: 441 + ? + PORT_ID: 518 + : + PC_PHYS_PORT_ID: 449 + ? + PORT_ID: 519 + : + PC_PHYS_PORT_ID: 457 + ? + PORT_ID: 536 + : + PC_PHYS_PORT_ID: 465 + ? + PORT_ID: 537 + : + PC_PHYS_PORT_ID: 473 + ? + PORT_ID: 554 + : + PC_PHYS_PORT_ID: 481 + ? + PORT_ID: 555 + : + PC_PHYS_PORT_ID: 489 + ? + PORT_ID: 572 + : + PC_PHYS_PORT_ID: 497 + ? + PORT_ID: 573 + : + PC_PHYS_PORT_ID: 505 + ? + #mgmt ports + PORT_ID: 268 + : + PC_PHYS_PORT_ID: 514 + ? + PORT_ID: 556 + : + PC_PHYS_PORT_ID: 517 +... + +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [15, 16, 32, 33, 50, 51, 68, 69, 86, 87, 104, 105, 122, 123, 140, 141, 158, 159, 176, 177, 194, 195, 212, 213, 230, 231, 248, 249, 266, 267, 284, 285, 302, 303, 320, 321, 338, 339, 356, 357, 374, 375, 392, 393, 410, 411, 428, 429, 446, 447, 464, 465, 482, 483, 500, 501, 518, 519, 536, 537, 554, 555, 572, 573] + : + ENABLE: 1 + SPEED: 1600000 + NUM_LANES: 8 + FEC_MODE: PC_FEC_RS544_2XN_IEEE + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [268, 556] + : + ENABLE: 1 + SPEED: 25000 + NUM_LANES: 1 + FEC_MODE: PC_FEC_RS528 + MAX_FRAME_SIZE: 9416 +... + +--- +device: + 0: + PC_PMD_FIRMWARE: + ? + PORT_ID: [15, 16, 32, 33, 50, 51, 68, 69, 86, 87, 104, 105, 122, 123, 140, 141, 158, 159, 176, 177, 194, 195, 212, 213, 230, 231, 248, 249, 266, 267, 284, 285, 302, 303, 320, 321, 338, 339, 356, 357, 374, 375, 392, 393, 410, 411, 428, 429, 446, 447, 464, 465, 482, 483, 500, 501, 518, 519, 536, 537, 554, 555, 572, 573] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE + ? + PORT_ID: [268, 556] + : + MEDIUM_TYPE_AUTO: 0 + MEDIUM_TYPE: PC_PHY_MEDIUM_BACKPLANE +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +device: + 0: + # Per pipe flex counter configuration + CTR_EFLEX_CONFIG: + CTR_ING_EFLEX_OPERMODE_PIPEUNIQUE: 1 + CTR_ING_EFLEX_OPERMODE_PIPE_INSTANCE_UNIQUE: 1 + CTR_EGR_EFLEX_OPERMODE_PIPEUNIQUE: 1 + CTR_EGR_EFLEX_OPERMODE_PIPE_INSTANCE_UNIQUE: 1 + FP_CONFIG: + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE + #CTR COS_ENABLE + CTR_ING_COS_Q_CONFIG: + COS_ENABLE: 0 +... + +--- +bcm_device: + 0: + global: + sai_port_phy_time_sync_en: 1 + skip_protocol_default_entries: 1 + sai_field_group_auto_prioritize: 1 + sai_trap_group_ver: 1 + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + pktio_mode: 1 + stat_custom_receive0_management_mode: 1 + global_flexctr_ing_action_num_reserved: 20 + global_flexctr_ing_pool_num_reserved: 8 + global_flexctr_ing_op_profile_num_reserved: 20 + global_flexctr_ing_group_num_reserved: 2 + global_flexctr_egr_action_num_reserved: 8 + global_flexctr_egr_pool_num_reserved: 5 + global_flexctr_egr_op_profile_num_reserved: 10 + global_flexctr_egr_group_num_reserved: 1 + flowtracker_flexctr_alloc_enable: 1 + sai_pfc_dlr_init_capability: 2 + sai_stats_support_mask: 0x804 + sai_postinit_cmd_file: /usr/share/sonic/platform/postinit_cmd_file.soc + +... diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/custom_led.bin b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..5b14a1385f9ec69aadbd6ebe937870fadd04ad02 GIT binary patch literal 898 zcmajcKWq|F90&04?+$ttS}bjifMVtFPvANT#>BRXdEDtskfaL4m_pS83mv>fl(@;m|lVM8%1?m^!+NXJvJG-E}@2r^#GlTGGeim03qA}GP@Gv2aki(d4K(QHi|4>)(BP1FVx)jhgdsr)2HuNOv zLYOKOK1;10*HyINcB$bl(QLIP7An|EJ1UnCJ;n9R$eoO*SsJbT%FcSTysz%NHCAul za@7ys9!+=n?B{UbL(E?F9<~^9p0PPLuJH&%&}ImF%$9L?S|j>39%f1Rhn7|UG=m@Q=~@}V^r*x>DRsl%NXDNaLBCJZP) z`g`#$NueJ*2cGS|dCgmVlRx0QZ@04=cjWRso-5_Lz3rScKc6qVpv83 rSuDT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/fru.py b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/fru.py new file mode 100644 index 0000000000..f95164e036 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/installer.conf b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/installer.conf new file mode 100644 index 0000000000..832f836f2f --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/installer.conf @@ -0,0 +1,41 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="modprobe.blacklist=ixgbe,wb_ixgbe,ice,i2c_designware_platform,wb_i2c_designware_platform,i2c_piix4,i2c_asf,spi_amd,cdc_subset" +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 + +create_eth_fix_rules(){ + [ -n "$demo_mnt" ] || return + + [ "$install_env" = "onie" -a -n "$demo_dev" ] && { + mkdir -p $demo_mnt + ${onie_bin} mount -t ext4 -o defaults,rw $demo_dev $demo_mnt || { + echo "Error: Unable to mount $demo_dev on $demo_mnt,link creating failed." + } + } + [ -n "$demo_mnt" -a -n "$image_dir" -a -d "$demo_mnt/$image_dir" ] && { + mkdir -p $demo_mnt/$image_dir/rw/etc/systemd/network/ + + # Fix Intel E610/E810 Ethernet interface names by PCI path + # 02:00.0 -> eth1, 02:00.1 -> eth2 (E610 10GBASE-T) + # 03:00.0..3 -> eth3..eth6 (E810-C backplane) + for entry in \ + "1:0000:02:00.0" \ + "2:0000:02:00.1" \ + "3:0000:03:00.0" \ + "4:0000:03:00.1" \ + "5:0000:03:00.2" \ + "6:0000:03:00.3"; do + idx=${entry%%:*} + bdf=${entry#*:} + cat > $demo_mnt/$image_dir/rw/etc/systemd/network/20-eth${idx}.link < 0: + os.close(fd) + return True, val_list + + +def getPMCreg(location): + retval = 'ERR' + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) + try: + with open(location, 'r') as fd: + retval = fd.read() + except Exception as error: + return "ERR %s" % str(error) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +# Get a mailbox register +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = reg_name + filepath = glob.glob(mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) + mb_reg_file = filepath[0] + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) + try: + with open(mb_reg_file, 'rb') as fd: + retval = fd.read() + retval = typeTostr(retval) + except Exception as error: + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +class checktype(): + def __init__(self, test1): + self.test1 = test1 + + @staticmethod + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) + return value_t + except Exception as e: + value_t = "ERR %s" % str(e) + return value_t + + # fanFRU + @staticmethod + def decodeBinByValue(retval): + fru = ipmifru() + fru.decodeBin(retval) + return fru + + @staticmethod + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name.strip() == psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) + + +class status(): + def __init__(self, productname): + self.productname = productname + + @staticmethod + def getETroot(filename): + tree = ET.parse(filename) + root = tree.getroot() + return root + + @staticmethod + def getDecodValue(collection, decode): + decodes = collection.find('decode') + testdecode = decodes.find(decode) + test = {} + if testdecode is None: + return test + for neighbor in testdecode.iter('code'): + test[neighbor.attrib["key"]] = neighbor.attrib["value"] + return test + + @staticmethod + def getfileValue(location): + return checktype.getValue(location, " ", " ") + + @staticmethod + def getETValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + prob_t = {} + prob_t.update(neighbor.attrib) + prob_t['errcode'] = 0 + prob_t['errmsg'] = '' + for pros in neighbor.iter("property"): + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) + if ret.get('e2type') == 'fru' and ret.get("name") == "fru": + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" + else: + val = ret["type"] + if 'bit' not in ret.keys(): + bit = "0" + else: + bit = ret["bit"] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] + if str(s) != ret["default"]: + prob_t['errcode'] = -1 + break + else: + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) + else: + s = rt[str(s).replace("\x00", "").rstrip()] + name = ret["name"] + prob_t[name] = str(s) + a.append(prob_t) + + @staticmethod + def getCPUValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + location = neighbor.attrib["location"] + L = [] + for dirpath, dirnames, filenames in os.walk(location): + for file in filenames: + if file.endswith("input"): + L.append(os.path.join(dirpath, file)) + L = sorted(L, reverse=False) + for i in range(len(L)): + prob_t = {} + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 + a.append(prob_t) + + @staticmethod + def getFileName(): + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + + @staticmethod + def checkFan(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "fan" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getTemp(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "temp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getPsu(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "psu" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getcputemp(ret): + _filename = status.getFileName() + _tagname = "cpus" + status.getCPUValue(ret, _filename, _tagname) + + @staticmethod + def getDcdc(ret): + _filename = status.getFileName() + _tagname = "dcdc" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pcie.yaml b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pcie.yaml new file mode 100644 index 0000000000..b0688f08b9 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pcie.yaml @@ -0,0 +1,240 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1022:14d8' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Root Complex' +- bus: '00' + dev: '00' + fn: '2' + id: '1022:14d9' + name: 'IOMMU: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge IOMMU' +- bus: '00' + dev: '01' + fn: '0' + id: '1022:14da' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy Host Bridge' +- bus: '00' + dev: '01' + fn: '1' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '01' + fn: '2' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '01' + fn: '3' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '01' + fn: '4' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '01' + fn: '5' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '02' + fn: '0' + id: '1022:14da' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy Host Bridge' +- bus: '00' + dev: '02' + fn: '1' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '02' + fn: '2' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '03' + fn: '0' + id: '1022:14da' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy Host Bridge' +- bus: '00' + dev: '03' + fn: '1' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '03' + fn: '2' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '03' + fn: '3' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '03' + fn: '4' + id: '1022:14db' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge GPP Bridge' +- bus: '00' + dev: '04' + fn: '0' + id: '1022:14da' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy Host Bridge' +- bus: '00' + dev: '08' + fn: '0' + id: '1022:14da' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Dummy Host Bridge' +- bus: '00' + dev: '08' + fn: '1' + id: '1022:14dd' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Internal GPP Bridge to Bus [C:A]' +- bus: '00' + dev: '08' + fn: '3' + id: '1022:14dd' + name: 'PCI bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Internal GPP Bridge to Bus [C:A]' +- bus: '00' + dev: '14' + fn: '0' + id: '1022:790b' + name: 'SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 71)' +- bus: '00' + dev: '14' + fn: '3' + id: '1022:790e' + name: 'ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 51)' +- bus: '00' + dev: '18' + fn: '0' + id: '1022:14e0' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 0' +- bus: '00' + dev: '18' + fn: '1' + id: '1022:14e1' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 1' +- bus: '00' + dev: '18' + fn: '2' + id: '1022:14e2' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 2' +- bus: '00' + dev: '18' + fn: '3' + id: '1022:14e3' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 3' +- bus: '00' + dev: '18' + fn: '4' + id: '1022:14e4' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 4' +- bus: '00' + dev: '18' + fn: '5' + id: '1022:14e5' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 5' +- bus: '00' + dev: '18' + fn: '6' + id: '1022:14e6' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 6' +- bus: '00' + dev: '18' + fn: '7' + id: '1022:14e7' + name: 'Host bridge: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge Data Fabric; Function 7' +- bus: '01' + dev: '00' + fn: '0' + id: '14e4:f914' + name: 'Ethernet controller: Broadcom Inc. and subsidiaries BCM78914 Switch ASIC [Tomahawk6] (rev 11)' +- bus: '02' + dev: '00' + fn: '0' + id: '8086:57b0' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E610 10GBASE T' +- bus: '02' + dev: '00' + fn: '1' + id: '8086:57b0' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E610 10GBASE T' +- bus: '03' + dev: '00' + fn: '0' + id: '8086:1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane (rev 02)' +- bus: '03' + dev: '00' + fn: '1' + id: '8086:1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane (rev 02)' +- bus: '03' + dev: '00' + fn: '2' + id: '8086:1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane (rev 02)' +- bus: '03' + dev: '00' + fn: '3' + id: '8086:1591' + name: 'Ethernet controller: Intel Corporation Ethernet Controller E810-C for backplane (rev 02)' +- bus: '05' + dev: '00' + fn: '0' + id: '1d89:0280' + name: 'Non-Volatile memory controller: YEESTOR Microelectronics Co., Ltd PCIe NVMe SSD (rev 01)' +- bus: '08' + dev: '00' + fn: '0' + id: '10ee:7011' + name: 'Memory controller: Xilinx Corporation 7-Series FPGA Hard PCIe block (AXI/debug)' +- bus: '0a' + dev: '00' + fn: '0' + id: '8086:1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)' +- bus: '0b' + dev: '00' + fn: '0' + id: '10ee:7011' + name: 'Memory controller: Xilinx Corporation 7-Series FPGA Hard PCIe block (AXI/debug)' +- bus: '0c' + dev: '00' + fn: '0' + id: '1022:14de' + name: 'Non-Essential Instrumentation [1300]: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge PCIe Dummy Function' +- bus: '0c' + dev: '00' + fn: '2' + id: '1022:1649' + name: 'Encryption controller: Advanced Micro Devices, Inc. [AMD] Family 19h PSP/CCP' +- bus: '0c' + dev: '00' + fn: '3' + id: '1022:15b6' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge USB 3.1 xHCI' +- bus: '0c' + dev: '00' + fn: '4' + id: '1022:15b7' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge USB 3.1 xHCI' +- bus: '0c' + dev: '00' + fn: '5' + id: '1022:15e2' + name: 'Multimedia controller: Advanced Micro Devices, Inc. [AMD] Audio Coprocessor (rev 62)' +- bus: '0c' + dev: '00' + fn: '6' + id: '1022:15e3' + name: 'Audio device: Advanced Micro Devices, Inc. [AMD] Family 17h/19h/1ah HD Audio Controller' +- bus: '0d' + dev: '00' + fn: '0' + id: '1022:15b8' + name: 'USB controller: Advanced Micro Devices, Inc. [AMD] Raphael/Granite Ridge USB 2.0 xHCI' \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform.json b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform.json new file mode 100644 index 0000000000..aa55a93315 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform.json @@ -0,0 +1,4402 @@ +{ + "chassis": { + "name": "M2-W6951-64HC-CP", + "thermal_manager": false, + "status_led": { + "controllable": false, + "colors": [ + "green", + "blinking_green", + "amber", + "blinking_amber" + ] + }, + "components": [ + { + "name": "CPU_CPLD" + }, + { + "name": "CONNECT_CPLD" + }, + { + "name": "MAC_CPLDA" + }, + { + "name": "MAC_CPLDB" + }, + { + "name": "MAC_CPLDC" + }, + { + "name": "FAN_CPLD" + }, + { + "name": "MGMT_CPLD" + }, + { + "name": "MAC_FPGA" + }, + { + "name": "BIOS" + } + ], + "fans": [ + { + "name": "Fantray1_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray1_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray2_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray2_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray3_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray3_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray4_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray4_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + } + ], + "fan_drawers": [ + { + "name": "Fantray1", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray1_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray1_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray2", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray2_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray2_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray3", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray3_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray3_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray4", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray4_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray4_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + } + ], + "psus": [ + { + "name": "Psu1", + "voltage": true, + "current": true, + "power": true, + "max_power": false, + "voltage_high_threshold": true, + "voltage_low_threshold": true, + "temperature": true, + "fans_target_speed": true, + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU1_FAN1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Psu2", + "voltage": true, + "current": true, + "power": true, + "max_power": false, + "voltage_high_threshold": true, + "voltage_low_threshold": true, + "temperature": true, + "fans_target_speed": true, + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU2_FAN1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + } + ], + "thermals": [ + { + "name": "BOARD_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "CPU_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "INLET_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "OUTLET_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "ASIC_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU1_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU2_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU3_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU4_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + } + ], + "modules": [], + "sfps": [] + }, + "interfaces": { + "Ethernet1": { + "index": "0,0,0,0,0,0,0,0", + "lanes": "121,122,123,124,125,126,127,128", + "breakout_modes": { + "1x1600G": [ + "Eth1" + ], + "2x800G": [ + "Eth1/1", + "Eth1/2" + ], + "4x400G": [ + "Eth1/1", + "Eth1/2", + "Eth1/3", + "Eth1/4" + ], + "8x200G": [ + "Eth1/1", + "Eth1/2", + "Eth1/3", + "Eth1/4", + "Eth1/5", + "Eth1/6", + "Eth1/7", + "Eth1/8" + ], + "2x400G": [ + "Eth1/1", + "Eth1/2" + ], + "4x200G": [ + "Eth1/1", + "Eth1/2", + "Eth1/3", + "Eth1/4" + ], + "8x100G": [ + "Eth1/1", + "Eth1/2", + "Eth1/3", + "Eth1/4", + "Eth1/5", + "Eth1/6", + "Eth1/7", + "Eth1/8" + ], + "1x400G(4)": [ + "Eth1/1" + ], + "1x200G(2)": [ + "Eth1/1" + ], + "1x100G(1)": [ + "Eth1/1" + ], + "1x200G(1)": [ + "Eth1/1" + ] + } + }, + "Ethernet9": { + "index": "1,1,1,1,1,1,1,1", + "lanes": "65,66,67,68,69,70,71,72", + "breakout_modes": { + "1x1600G": [ + "Eth2" + ], + "2x800G": [ + "Eth2/1", + "Eth2/2" + ], + "4x400G": [ + "Eth2/1", + "Eth2/2", + "Eth2/3", + "Eth2/4" + ], + "8x200G": [ + "Eth2/1", + "Eth2/2", + "Eth2/3", + "Eth2/4", + "Eth2/5", + "Eth2/6", + "Eth2/7", + "Eth2/8" + ], + "2x400G": [ + "Eth2/1", + "Eth2/2" + ], + "4x200G": [ + "Eth2/1", + "Eth2/2", + "Eth2/3", + "Eth2/4" + ], + "8x100G": [ + "Eth2/1", + "Eth2/2", + "Eth2/3", + "Eth2/4", + "Eth2/5", + "Eth2/6", + "Eth2/7", + "Eth2/8" + ], + "1x400G(4)": [ + "Eth2/1" + ], + "1x200G(2)": [ + "Eth2/1" + ], + "1x100G(1)": [ + "Eth2/1" + ], + "1x200G(1)": [ + "Eth2/1" + ] + } + }, + "Ethernet17": { + "index": "2,2,2,2,2,2,2,2", + "lanes": "129,130,131,132,133,134,135,136", + "breakout_modes": { + "1x1600G": [ + "Eth3" + ], + "2x800G": [ + "Eth3/1", + "Eth3/2" + ], + "4x400G": [ + "Eth3/1", + "Eth3/2", + "Eth3/3", + "Eth3/4" + ], + "8x200G": [ + "Eth3/1", + "Eth3/2", + "Eth3/3", + "Eth3/4", + "Eth3/5", + "Eth3/6", + "Eth3/7", + "Eth3/8" + ], + "2x400G": [ + "Eth3/1", + "Eth3/2" + ], + "4x200G": [ + "Eth3/1", + "Eth3/2", + "Eth3/3", + "Eth3/4" + ], + "8x100G": [ + "Eth3/1", + "Eth3/2", + "Eth3/3", + "Eth3/4", + "Eth3/5", + "Eth3/6", + "Eth3/7", + "Eth3/8" + ], + "1x400G(4)": [ + "Eth3/1" + ], + "1x200G(2)": [ + "Eth3/1" + ], + "1x100G(1)": [ + "Eth3/1" + ], + "1x200G(1)": [ + "Eth3/1" + ] + } + }, + "Ethernet25": { + "index": "3,3,3,3,3,3,3,3", + "lanes": "137,138,139,140,141,142,143,144", + "breakout_modes": { + "1x1600G": [ + "Eth4" + ], + "2x800G": [ + "Eth4/1", + "Eth4/2" + ], + "4x400G": [ + "Eth4/1", + "Eth4/2", + "Eth4/3", + "Eth4/4" + ], + "8x200G": [ + "Eth4/1", + "Eth4/2", + "Eth4/3", + "Eth4/4", + "Eth4/5", + "Eth4/6", + "Eth4/7", + "Eth4/8" + ], + "2x400G": [ + "Eth4/1", + "Eth4/2" + ], + "4x200G": [ + "Eth4/1", + "Eth4/2", + "Eth4/3", + "Eth4/4" + ], + "8x100G": [ + "Eth4/1", + "Eth4/2", + "Eth4/3", + "Eth4/4", + "Eth4/5", + "Eth4/6", + "Eth4/7", + "Eth4/8" + ], + "1x400G(4)": [ + "Eth4/1" + ], + "1x200G(2)": [ + "Eth4/1" + ], + "1x100G(1)": [ + "Eth4/1" + ], + "1x200G(1)": [ + "Eth4/1" + ] + } + }, + "Ethernet33": { + "index": "4,4,4,4,4,4,4,4", + "lanes": "113,114,115,116,117,118,119,120", + "breakout_modes": { + "1x1600G": [ + "Eth5" + ], + "2x800G": [ + "Eth5/1", + "Eth5/2" + ], + "4x400G": [ + "Eth5/1", + "Eth5/2", + "Eth5/3", + "Eth5/4" + ], + "8x200G": [ + "Eth5/1", + "Eth5/2", + "Eth5/3", + "Eth5/4", + "Eth5/5", + "Eth5/6", + "Eth5/7", + "Eth5/8" + ], + "2x400G": [ + "Eth5/1", + "Eth5/2" + ], + "4x200G": [ + "Eth5/1", + "Eth5/2", + "Eth5/3", + "Eth5/4" + ], + "8x100G": [ + "Eth5/1", + "Eth5/2", + "Eth5/3", + "Eth5/4", + "Eth5/5", + "Eth5/6", + "Eth5/7", + "Eth5/8" + ], + "1x400G(4)": [ + "Eth5/1" + ], + "1x200G(2)": [ + "Eth5/1" + ], + "1x100G(1)": [ + "Eth5/1" + ], + "1x200G(1)": [ + "Eth5/1" + ] + } + }, + "Ethernet41": { + "index": "5,5,5,5,5,5,5,5", + "lanes": "73,74,75,76,77,78,79,80", + "breakout_modes": { + "1x1600G": [ + "Eth6" + ], + "2x800G": [ + "Eth6/1", + "Eth6/2" + ], + "4x400G": [ + "Eth6/1", + "Eth6/2", + "Eth6/3", + "Eth6/4" + ], + "8x200G": [ + "Eth6/1", + "Eth6/2", + "Eth6/3", + "Eth6/4", + "Eth6/5", + "Eth6/6", + "Eth6/7", + "Eth6/8" + ], + "2x400G": [ + "Eth6/1", + "Eth6/2" + ], + "4x200G": [ + "Eth6/1", + "Eth6/2", + "Eth6/3", + "Eth6/4" + ], + "8x100G": [ + "Eth6/1", + "Eth6/2", + "Eth6/3", + "Eth6/4", + "Eth6/5", + "Eth6/6", + "Eth6/7", + "Eth6/8" + ], + "1x400G(4)": [ + "Eth6/1" + ], + "1x200G(2)": [ + "Eth6/1" + ], + "1x100G(1)": [ + "Eth6/1" + ], + "1x200G(1)": [ + "Eth6/1" + ] + } + }, + "Ethernet49": { + "index": "6,6,6,6,6,6,6,6", + "lanes": "145,146,147,148,149,150,151,152", + "breakout_modes": { + "1x1600G": [ + "Eth7" + ], + "2x800G": [ + "Eth7/1", + "Eth7/2" + ], + "4x400G": [ + "Eth7/1", + "Eth7/2", + "Eth7/3", + "Eth7/4" + ], + "8x200G": [ + "Eth7/1", + "Eth7/2", + "Eth7/3", + "Eth7/4", + "Eth7/5", + "Eth7/6", + "Eth7/7", + "Eth7/8" + ], + "2x400G": [ + "Eth7/1", + "Eth7/2" + ], + "4x200G": [ + "Eth7/1", + "Eth7/2", + "Eth7/3", + "Eth7/4" + ], + "8x100G": [ + "Eth7/1", + "Eth7/2", + "Eth7/3", + "Eth7/4", + "Eth7/5", + "Eth7/6", + "Eth7/7", + "Eth7/8" + ], + "1x400G(4)": [ + "Eth7/1" + ], + "1x200G(2)": [ + "Eth7/1" + ], + "1x100G(1)": [ + "Eth7/1" + ], + "1x200G(1)": [ + "Eth7/1" + ] + } + }, + "Ethernet57": { + "index": "7,7,7,7,7,7,7,7", + "lanes": "153,154,155,156,157,158,159,160", + "breakout_modes": { + "1x1600G": [ + "Eth8" + ], + "2x800G": [ + "Eth8/1", + "Eth8/2" + ], + "4x400G": [ + "Eth8/1", + "Eth8/2", + "Eth8/3", + "Eth8/4" + ], + "8x200G": [ + "Eth8/1", + "Eth8/2", + "Eth8/3", + "Eth8/4", + "Eth8/5", + "Eth8/6", + "Eth8/7", + "Eth8/8" + ], + "2x400G": [ + "Eth8/1", + "Eth8/2" + ], + "4x200G": [ + "Eth8/1", + "Eth8/2", + "Eth8/3", + "Eth8/4" + ], + "8x100G": [ + "Eth8/1", + "Eth8/2", + "Eth8/3", + "Eth8/4", + "Eth8/5", + "Eth8/6", + "Eth8/7", + "Eth8/8" + ], + "1x400G(4)": [ + "Eth8/1" + ], + "1x200G(2)": [ + "Eth8/1" + ], + "1x100G(1)": [ + "Eth8/1" + ], + "1x200G(1)": [ + "Eth8/1" + ] + } + }, + "Ethernet65": { + "index": "8,8,8,8,8,8,8,8", + "lanes": "105,106,107,108,109,110,111,112", + "breakout_modes": { + "1x1600G": [ + "Eth9" + ], + "2x800G": [ + "Eth9/1", + "Eth9/2" + ], + "4x400G": [ + "Eth9/1", + "Eth9/2", + "Eth9/3", + "Eth9/4" + ], + "8x200G": [ + "Eth9/1", + "Eth9/2", + "Eth9/3", + "Eth9/4", + "Eth9/5", + "Eth9/6", + "Eth9/7", + "Eth9/8" + ], + "2x400G": [ + "Eth9/1", + "Eth9/2" + ], + "4x200G": [ + "Eth9/1", + "Eth9/2", + "Eth9/3", + "Eth9/4" + ], + "8x100G": [ + "Eth9/1", + "Eth9/2", + "Eth9/3", + "Eth9/4", + "Eth9/5", + "Eth9/6", + "Eth9/7", + "Eth9/8" + ], + "1x400G(4)": [ + "Eth9/1" + ], + "1x200G(2)": [ + "Eth9/1" + ], + "1x100G(1)": [ + "Eth9/1" + ], + "1x200G(1)": [ + "Eth9/1" + ] + } + }, + "Ethernet73": { + "index": "9,9,9,9,9,9,9,9", + "lanes": "81,82,83,84,85,86,87,88", + "breakout_modes": { + "1x1600G": [ + "Eth10" + ], + "2x800G": [ + "Eth10/1", + "Eth10/2" + ], + "4x400G": [ + "Eth10/1", + "Eth10/2", + "Eth10/3", + "Eth10/4" + ], + "8x200G": [ + "Eth10/1", + "Eth10/2", + "Eth10/3", + "Eth10/4", + "Eth10/5", + "Eth10/6", + "Eth10/7", + "Eth10/8" + ], + "2x400G": [ + "Eth10/1", + "Eth10/2" + ], + "4x200G": [ + "Eth10/1", + "Eth10/2", + "Eth10/3", + "Eth10/4" + ], + "8x100G": [ + "Eth10/1", + "Eth10/2", + "Eth10/3", + "Eth10/4", + "Eth10/5", + "Eth10/6", + "Eth10/7", + "Eth10/8" + ], + "1x400G(4)": [ + "Eth10/1" + ], + "1x200G(2)": [ + "Eth10/1" + ], + "1x100G(1)": [ + "Eth10/1" + ], + "1x200G(1)": [ + "Eth10/1" + ] + } + }, + "Ethernet81": { + "index": "10,10,10,10,10,10,10,10", + "lanes": "185,186,187,188,189,190,191,192", + "breakout_modes": { + "1x1600G": [ + "Eth11" + ], + "2x800G": [ + "Eth11/1", + "Eth11/2" + ], + "4x400G": [ + "Eth11/1", + "Eth11/2", + "Eth11/3", + "Eth11/4" + ], + "8x200G": [ + "Eth11/1", + "Eth11/2", + "Eth11/3", + "Eth11/4", + "Eth11/5", + "Eth11/6", + "Eth11/7", + "Eth11/8" + ], + "2x400G": [ + "Eth11/1", + "Eth11/2" + ], + "4x200G": [ + "Eth11/1", + "Eth11/2", + "Eth11/3", + "Eth11/4" + ], + "8x100G": [ + "Eth11/1", + "Eth11/2", + "Eth11/3", + "Eth11/4", + "Eth11/5", + "Eth11/6", + "Eth11/7", + "Eth11/8" + ], + "1x400G(4)": [ + "Eth11/1" + ], + "1x200G(2)": [ + "Eth11/1" + ], + "1x100G(1)": [ + "Eth11/1" + ], + "1x200G(1)": [ + "Eth11/1" + ] + } + }, + "Ethernet89": { + "index": "11,11,11,11,11,11,11,11", + "lanes": "177,178,179,180,181,182,183,184", + "breakout_modes": { + "1x1600G": [ + "Eth12" + ], + "2x800G": [ + "Eth12/1", + "Eth12/2" + ], + "4x400G": [ + "Eth12/1", + "Eth12/2", + "Eth12/3", + "Eth12/4" + ], + "8x200G": [ + "Eth12/1", + "Eth12/2", + "Eth12/3", + "Eth12/4", + "Eth12/5", + "Eth12/6", + "Eth12/7", + "Eth12/8" + ], + "2x400G": [ + "Eth12/1", + "Eth12/2" + ], + "4x200G": [ + "Eth12/1", + "Eth12/2", + "Eth12/3", + "Eth12/4" + ], + "8x100G": [ + "Eth12/1", + "Eth12/2", + "Eth12/3", + "Eth12/4", + "Eth12/5", + "Eth12/6", + "Eth12/7", + "Eth12/8" + ], + "1x400G(4)": [ + "Eth12/1" + ], + "1x200G(2)": [ + "Eth12/1" + ], + "1x100G(1)": [ + "Eth12/1" + ], + "1x200G(1)": [ + "Eth12/1" + ] + } + }, + "Ethernet97": { + "index": "12,12,12,12,12,12,12,12", + "lanes": "97,98,99,100,101,102,103,104", + "breakout_modes": { + "1x1600G": [ + "Eth13" + ], + "2x800G": [ + "Eth13/1", + "Eth13/2" + ], + "4x400G": [ + "Eth13/1", + "Eth13/2", + "Eth13/3", + "Eth13/4" + ], + "8x200G": [ + "Eth13/1", + "Eth13/2", + "Eth13/3", + "Eth13/4", + "Eth13/5", + "Eth13/6", + "Eth13/7", + "Eth13/8" + ], + "2x400G": [ + "Eth13/1", + "Eth13/2" + ], + "4x200G": [ + "Eth13/1", + "Eth13/2", + "Eth13/3", + "Eth13/4" + ], + "8x100G": [ + "Eth13/1", + "Eth13/2", + "Eth13/3", + "Eth13/4", + "Eth13/5", + "Eth13/6", + "Eth13/7", + "Eth13/8" + ], + "1x400G(4)": [ + "Eth13/1" + ], + "1x200G(2)": [ + "Eth13/1" + ], + "1x100G(1)": [ + "Eth13/1" + ], + "1x200G(1)": [ + "Eth13/1" + ] + } + }, + "Ethernet105": { + "index": "13,13,13,13,13,13,13,13", + "lanes": "89,90,91,92,93,94,95,96", + "breakout_modes": { + "1x1600G": [ + "Eth14" + ], + "2x800G": [ + "Eth14/1", + "Eth14/2" + ], + "4x400G": [ + "Eth14/1", + "Eth14/2", + "Eth14/3", + "Eth14/4" + ], + "8x200G": [ + "Eth14/1", + "Eth14/2", + "Eth14/3", + "Eth14/4", + "Eth14/5", + "Eth14/6", + "Eth14/7", + "Eth14/8" + ], + "2x400G": [ + "Eth14/1", + "Eth14/2" + ], + "4x200G": [ + "Eth14/1", + "Eth14/2", + "Eth14/3", + "Eth14/4" + ], + "8x100G": [ + "Eth14/1", + "Eth14/2", + "Eth14/3", + "Eth14/4", + "Eth14/5", + "Eth14/6", + "Eth14/7", + "Eth14/8" + ], + "1x400G(4)": [ + "Eth14/1" + ], + "1x200G(2)": [ + "Eth14/1" + ], + "1x100G(1)": [ + "Eth14/1" + ], + "1x200G(1)": [ + "Eth14/1" + ] + } + }, + "Ethernet113": { + "index": "14,14,14,14,14,14,14,14", + "lanes": "169,170,171,172,173,174,175,176", + "breakout_modes": { + "1x1600G": [ + "Eth15" + ], + "2x800G": [ + "Eth15/1", + "Eth15/2" + ], + "4x400G": [ + "Eth15/1", + "Eth15/2", + "Eth15/3", + "Eth15/4" + ], + "8x200G": [ + "Eth15/1", + "Eth15/2", + "Eth15/3", + "Eth15/4", + "Eth15/5", + "Eth15/6", + "Eth15/7", + "Eth15/8" + ], + "2x400G": [ + "Eth15/1", + "Eth15/2" + ], + "4x200G": [ + "Eth15/1", + "Eth15/2", + "Eth15/3", + "Eth15/4" + ], + "8x100G": [ + "Eth15/1", + "Eth15/2", + "Eth15/3", + "Eth15/4", + "Eth15/5", + "Eth15/6", + "Eth15/7", + "Eth15/8" + ], + "1x400G(4)": [ + "Eth15/1" + ], + "1x200G(2)": [ + "Eth15/1" + ], + "1x100G(1)": [ + "Eth15/1" + ], + "1x200G(1)": [ + "Eth15/1" + ] + } + }, + "Ethernet121": { + "index": "15,15,15,15,15,15,15,15", + "lanes": "161,162,163,164,165,166,167,168", + "breakout_modes": { + "1x1600G": [ + "Eth16" + ], + "2x800G": [ + "Eth16/1", + "Eth16/2" + ], + "4x400G": [ + "Eth16/1", + "Eth16/2", + "Eth16/3", + "Eth16/4" + ], + "8x200G": [ + "Eth16/1", + "Eth16/2", + "Eth16/3", + "Eth16/4", + "Eth16/5", + "Eth16/6", + "Eth16/7", + "Eth16/8" + ], + "2x400G": [ + "Eth16/1", + "Eth16/2" + ], + "4x200G": [ + "Eth16/1", + "Eth16/2", + "Eth16/3", + "Eth16/4" + ], + "8x100G": [ + "Eth16/1", + "Eth16/2", + "Eth16/3", + "Eth16/4", + "Eth16/5", + "Eth16/6", + "Eth16/7", + "Eth16/8" + ], + "1x400G(4)": [ + "Eth16/1" + ], + "1x200G(2)": [ + "Eth16/1" + ], + "1x100G(1)": [ + "Eth16/1" + ], + "1x200G(1)": [ + "Eth16/1" + ] + } + }, + "Ethernet129": { + "index": "16,16,16,16,16,16,16,16", + "lanes": "25,26,27,28,29,30,31,32", + "breakout_modes": { + "1x1600G": [ + "Eth17" + ], + "2x800G": [ + "Eth17/1", + "Eth17/2" + ], + "4x400G": [ + "Eth17/1", + "Eth17/2", + "Eth17/3", + "Eth17/4" + ], + "8x200G": [ + "Eth17/1", + "Eth17/2", + "Eth17/3", + "Eth17/4", + "Eth17/5", + "Eth17/6", + "Eth17/7", + "Eth17/8" + ], + "2x400G": [ + "Eth17/1", + "Eth17/2" + ], + "4x200G": [ + "Eth17/1", + "Eth17/2", + "Eth17/3", + "Eth17/4" + ], + "8x100G": [ + "Eth17/1", + "Eth17/2", + "Eth17/3", + "Eth17/4", + "Eth17/5", + "Eth17/6", + "Eth17/7", + "Eth17/8" + ], + "1x400G(4)": [ + "Eth17/1" + ], + "1x200G(2)": [ + "Eth17/1" + ], + "1x100G(1)": [ + "Eth17/1" + ], + "1x200G(1)": [ + "Eth17/1" + ] + } + }, + "Ethernet137": { + "index": "17,17,17,17,17,17,17,17", + "lanes": "33,34,35,36,37,38,39,40", + "breakout_modes": { + "1x1600G": [ + "Eth18" + ], + "2x800G": [ + "Eth18/1", + "Eth18/2" + ], + "4x400G": [ + "Eth18/1", + "Eth18/2", + "Eth18/3", + "Eth18/4" + ], + "8x200G": [ + "Eth18/1", + "Eth18/2", + "Eth18/3", + "Eth18/4", + "Eth18/5", + "Eth18/6", + "Eth18/7", + "Eth18/8" + ], + "2x400G": [ + "Eth18/1", + "Eth18/2" + ], + "4x200G": [ + "Eth18/1", + "Eth18/2", + "Eth18/3", + "Eth18/4" + ], + "8x100G": [ + "Eth18/1", + "Eth18/2", + "Eth18/3", + "Eth18/4", + "Eth18/5", + "Eth18/6", + "Eth18/7", + "Eth18/8" + ], + "1x400G(4)": [ + "Eth18/1" + ], + "1x200G(2)": [ + "Eth18/1" + ], + "1x100G(1)": [ + "Eth18/1" + ], + "1x200G(1)": [ + "Eth18/1" + ] + } + }, + "Ethernet145": { + "index": "18,18,18,18,18,18,18,18", + "lanes": "193,194,195,196,197,198,199,200", + "breakout_modes": { + "1x1600G": [ + "Eth19" + ], + "2x800G": [ + "Eth19/1", + "Eth19/2" + ], + "4x400G": [ + "Eth19/1", + "Eth19/2", + "Eth19/3", + "Eth19/4" + ], + "8x200G": [ + "Eth19/1", + "Eth19/2", + "Eth19/3", + "Eth19/4", + "Eth19/5", + "Eth19/6", + "Eth19/7", + "Eth19/8" + ], + "2x400G": [ + "Eth19/1", + "Eth19/2" + ], + "4x200G": [ + "Eth19/1", + "Eth19/2", + "Eth19/3", + "Eth19/4" + ], + "8x100G": [ + "Eth19/1", + "Eth19/2", + "Eth19/3", + "Eth19/4", + "Eth19/5", + "Eth19/6", + "Eth19/7", + "Eth19/8" + ], + "1x400G(4)": [ + "Eth19/1" + ], + "1x200G(2)": [ + "Eth19/1" + ], + "1x100G(1)": [ + "Eth19/1" + ], + "1x200G(1)": [ + "Eth19/1" + ] + } + }, + "Ethernet153": { + "index": "19,19,19,19,19,19,19,19", + "lanes": "201,202,203,204,205,206,207,208", + "breakout_modes": { + "1x1600G": [ + "Eth20" + ], + "2x800G": [ + "Eth20/1", + "Eth20/2" + ], + "4x400G": [ + "Eth20/1", + "Eth20/2", + "Eth20/3", + "Eth20/4" + ], + "8x200G": [ + "Eth20/1", + "Eth20/2", + "Eth20/3", + "Eth20/4", + "Eth20/5", + "Eth20/6", + "Eth20/7", + "Eth20/8" + ], + "2x400G": [ + "Eth20/1", + "Eth20/2" + ], + "4x200G": [ + "Eth20/1", + "Eth20/2", + "Eth20/3", + "Eth20/4" + ], + "8x100G": [ + "Eth20/1", + "Eth20/2", + "Eth20/3", + "Eth20/4", + "Eth20/5", + "Eth20/6", + "Eth20/7", + "Eth20/8" + ], + "1x400G(4)": [ + "Eth20/1" + ], + "1x200G(2)": [ + "Eth20/1" + ], + "1x100G(1)": [ + "Eth20/1" + ], + "1x200G(1)": [ + "Eth20/1" + ] + } + }, + "Ethernet161": { + "index": "20,20,20,20,20,20,20,20", + "lanes": "17,18,19,20,21,22,23,24", + "breakout_modes": { + "1x1600G": [ + "Eth21" + ], + "2x800G": [ + "Eth21/1", + "Eth21/2" + ], + "4x400G": [ + "Eth21/1", + "Eth21/2", + "Eth21/3", + "Eth21/4" + ], + "8x200G": [ + "Eth21/1", + "Eth21/2", + "Eth21/3", + "Eth21/4", + "Eth21/5", + "Eth21/6", + "Eth21/7", + "Eth21/8" + ], + "2x400G": [ + "Eth21/1", + "Eth21/2" + ], + "4x200G": [ + "Eth21/1", + "Eth21/2", + "Eth21/3", + "Eth21/4" + ], + "8x100G": [ + "Eth21/1", + "Eth21/2", + "Eth21/3", + "Eth21/4", + "Eth21/5", + "Eth21/6", + "Eth21/7", + "Eth21/8" + ], + "1x400G(4)": [ + "Eth21/1" + ], + "1x200G(2)": [ + "Eth21/1" + ], + "1x100G(1)": [ + "Eth21/1" + ], + "1x200G(1)": [ + "Eth21/1" + ] + } + }, + "Ethernet169": { + "index": "21,21,21,21,21,21,21,21", + "lanes": "41,42,43,44,45,46,47,48", + "breakout_modes": { + "1x1600G": [ + "Eth22" + ], + "2x800G": [ + "Eth22/1", + "Eth22/2" + ], + "4x400G": [ + "Eth22/1", + "Eth22/2", + "Eth22/3", + "Eth22/4" + ], + "8x200G": [ + "Eth22/1", + "Eth22/2", + "Eth22/3", + "Eth22/4", + "Eth22/5", + "Eth22/6", + "Eth22/7", + "Eth22/8" + ], + "2x400G": [ + "Eth22/1", + "Eth22/2" + ], + "4x200G": [ + "Eth22/1", + "Eth22/2", + "Eth22/3", + "Eth22/4" + ], + "8x100G": [ + "Eth22/1", + "Eth22/2", + "Eth22/3", + "Eth22/4", + "Eth22/5", + "Eth22/6", + "Eth22/7", + "Eth22/8" + ], + "1x400G(4)": [ + "Eth22/1" + ], + "1x200G(2)": [ + "Eth22/1" + ], + "1x100G(1)": [ + "Eth22/1" + ], + "1x200G(1)": [ + "Eth22/1" + ] + } + }, + "Ethernet177": { + "index": "22,22,22,22,22,22,22,22", + "lanes": "209,210,211,212,213,214,215,216", + "breakout_modes": { + "1x1600G": [ + "Eth23" + ], + "2x800G": [ + "Eth23/1", + "Eth23/2" + ], + "4x400G": [ + "Eth23/1", + "Eth23/2", + "Eth23/3", + "Eth23/4" + ], + "8x200G": [ + "Eth23/1", + "Eth23/2", + "Eth23/3", + "Eth23/4", + "Eth23/5", + "Eth23/6", + "Eth23/7", + "Eth23/8" + ], + "2x400G": [ + "Eth23/1", + "Eth23/2" + ], + "4x200G": [ + "Eth23/1", + "Eth23/2", + "Eth23/3", + "Eth23/4" + ], + "8x100G": [ + "Eth23/1", + "Eth23/2", + "Eth23/3", + "Eth23/4", + "Eth23/5", + "Eth23/6", + "Eth23/7", + "Eth23/8" + ], + "1x400G(4)": [ + "Eth23/1" + ], + "1x200G(2)": [ + "Eth23/1" + ], + "1x100G(1)": [ + "Eth23/1" + ], + "1x200G(1)": [ + "Eth23/1" + ] + } + }, + "Ethernet185": { + "index": "23,23,23,23,23,23,23,23", + "lanes": "217,218,219,220,221,222,223,224", + "breakout_modes": { + "1x1600G": [ + "Eth24" + ], + "2x800G": [ + "Eth24/1", + "Eth24/2" + ], + "4x400G": [ + "Eth24/1", + "Eth24/2", + "Eth24/3", + "Eth24/4" + ], + "8x200G": [ + "Eth24/1", + "Eth24/2", + "Eth24/3", + "Eth24/4", + "Eth24/5", + "Eth24/6", + "Eth24/7", + "Eth24/8" + ], + "2x400G": [ + "Eth24/1", + "Eth24/2" + ], + "4x200G": [ + "Eth24/1", + "Eth24/2", + "Eth24/3", + "Eth24/4" + ], + "8x100G": [ + "Eth24/1", + "Eth24/2", + "Eth24/3", + "Eth24/4", + "Eth24/5", + "Eth24/6", + "Eth24/7", + "Eth24/8" + ], + "1x400G(4)": [ + "Eth24/1" + ], + "1x200G(2)": [ + "Eth24/1" + ], + "1x100G(1)": [ + "Eth24/1" + ], + "1x200G(1)": [ + "Eth24/1" + ] + } + }, + "Ethernet193": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "9,10,11,12,13,14,15,16", + "breakout_modes": { + "1x1600G": [ + "Eth25" + ], + "2x800G": [ + "Eth25/1", + "Eth25/2" + ], + "4x400G": [ + "Eth25/1", + "Eth25/2", + "Eth25/3", + "Eth25/4" + ], + "8x200G": [ + "Eth25/1", + "Eth25/2", + "Eth25/3", + "Eth25/4", + "Eth25/5", + "Eth25/6", + "Eth25/7", + "Eth25/8" + ], + "2x400G": [ + "Eth25/1", + "Eth25/2" + ], + "4x200G": [ + "Eth25/1", + "Eth25/2", + "Eth25/3", + "Eth25/4" + ], + "8x100G": [ + "Eth25/1", + "Eth25/2", + "Eth25/3", + "Eth25/4", + "Eth25/5", + "Eth25/6", + "Eth25/7", + "Eth25/8" + ], + "1x400G(4)": [ + "Eth25/1" + ], + "1x200G(2)": [ + "Eth25/1" + ], + "1x100G(1)": [ + "Eth25/1" + ], + "1x200G(1)": [ + "Eth25/1" + ] + } + }, + "Ethernet201": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "49,50,51,52,53,54,55,56", + "breakout_modes": { + "1x1600G": [ + "Eth26" + ], + "2x800G": [ + "Eth26/1", + "Eth26/2" + ], + "4x400G": [ + "Eth26/1", + "Eth26/2", + "Eth26/3", + "Eth26/4" + ], + "8x200G": [ + "Eth26/1", + "Eth26/2", + "Eth26/3", + "Eth26/4", + "Eth26/5", + "Eth26/6", + "Eth26/7", + "Eth26/8" + ], + "2x400G": [ + "Eth26/1", + "Eth26/2" + ], + "4x200G": [ + "Eth26/1", + "Eth26/2", + "Eth26/3", + "Eth26/4" + ], + "8x100G": [ + "Eth26/1", + "Eth26/2", + "Eth26/3", + "Eth26/4", + "Eth26/5", + "Eth26/6", + "Eth26/7", + "Eth26/8" + ], + "1x400G(4)": [ + "Eth26/1" + ], + "1x200G(2)": [ + "Eth26/1" + ], + "1x100G(1)": [ + "Eth26/1" + ], + "1x200G(1)": [ + "Eth26/1" + ] + } + }, + "Ethernet209": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "249,250,251,252,253,254,255,256", + "breakout_modes": { + "1x1600G": [ + "Eth27" + ], + "2x800G": [ + "Eth27/1", + "Eth27/2" + ], + "4x400G": [ + "Eth27/1", + "Eth27/2", + "Eth27/3", + "Eth27/4" + ], + "8x200G": [ + "Eth27/1", + "Eth27/2", + "Eth27/3", + "Eth27/4", + "Eth27/5", + "Eth27/6", + "Eth27/7", + "Eth27/8" + ], + "2x400G": [ + "Eth27/1", + "Eth27/2" + ], + "4x200G": [ + "Eth27/1", + "Eth27/2", + "Eth27/3", + "Eth27/4" + ], + "8x100G": [ + "Eth27/1", + "Eth27/2", + "Eth27/3", + "Eth27/4", + "Eth27/5", + "Eth27/6", + "Eth27/7", + "Eth27/8" + ], + "1x400G(4)": [ + "Eth27/1" + ], + "1x200G(2)": [ + "Eth27/1" + ], + "1x100G(1)": [ + "Eth27/1" + ], + "1x200G(1)": [ + "Eth27/1" + ] + } + }, + "Ethernet217": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "241,242,243,244,245,246,247,248", + "breakout_modes": { + "1x1600G": [ + "Eth28" + ], + "2x800G": [ + "Eth28/1", + "Eth28/2" + ], + "4x400G": [ + "Eth28/1", + "Eth28/2", + "Eth28/3", + "Eth28/4" + ], + "8x200G": [ + "Eth28/1", + "Eth28/2", + "Eth28/3", + "Eth28/4", + "Eth28/5", + "Eth28/6", + "Eth28/7", + "Eth28/8" + ], + "2x400G": [ + "Eth28/1", + "Eth28/2" + ], + "4x200G": [ + "Eth28/1", + "Eth28/2", + "Eth28/3", + "Eth28/4" + ], + "8x100G": [ + "Eth28/1", + "Eth28/2", + "Eth28/3", + "Eth28/4", + "Eth28/5", + "Eth28/6", + "Eth28/7", + "Eth28/8" + ], + "1x400G(4)": [ + "Eth28/1" + ], + "1x200G(2)": [ + "Eth28/1" + ], + "1x100G(1)": [ + "Eth28/1" + ], + "1x200G(1)": [ + "Eth28/1" + ] + } + }, + "Ethernet225": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "1,2,3,4,5,6,7,8", + "breakout_modes": { + "1x1600G": [ + "Eth29" + ], + "2x800G": [ + "Eth29/1", + "Eth29/2" + ], + "4x400G": [ + "Eth29/1", + "Eth29/2", + "Eth29/3", + "Eth29/4" + ], + "8x200G": [ + "Eth29/1", + "Eth29/2", + "Eth29/3", + "Eth29/4", + "Eth29/5", + "Eth29/6", + "Eth29/7", + "Eth29/8" + ], + "2x400G": [ + "Eth29/1", + "Eth29/2" + ], + "4x200G": [ + "Eth29/1", + "Eth29/2", + "Eth29/3", + "Eth29/4" + ], + "8x100G": [ + "Eth29/1", + "Eth29/2", + "Eth29/3", + "Eth29/4", + "Eth29/5", + "Eth29/6", + "Eth29/7", + "Eth29/8" + ], + "1x400G(4)": [ + "Eth29/1" + ], + "1x200G(2)": [ + "Eth29/1" + ], + "1x100G(1)": [ + "Eth29/1" + ], + "1x200G(1)": [ + "Eth29/1" + ] + } + }, + "Ethernet233": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "57,58,59,60,61,62,63,64", + "breakout_modes": { + "1x1600G": [ + "Eth30" + ], + "2x800G": [ + "Eth30/1", + "Eth30/2" + ], + "4x400G": [ + "Eth30/1", + "Eth30/2", + "Eth30/3", + "Eth30/4" + ], + "8x200G": [ + "Eth30/1", + "Eth30/2", + "Eth30/3", + "Eth30/4", + "Eth30/5", + "Eth30/6", + "Eth30/7", + "Eth30/8" + ], + "2x400G": [ + "Eth30/1", + "Eth30/2" + ], + "4x200G": [ + "Eth30/1", + "Eth30/2", + "Eth30/3", + "Eth30/4" + ], + "8x100G": [ + "Eth30/1", + "Eth30/2", + "Eth30/3", + "Eth30/4", + "Eth30/5", + "Eth30/6", + "Eth30/7", + "Eth30/8" + ], + "1x400G(4)": [ + "Eth30/1" + ], + "1x200G(2)": [ + "Eth30/1" + ], + "1x100G(1)": [ + "Eth30/1" + ], + "1x200G(1)": [ + "Eth30/1" + ] + } + }, + "Ethernet241": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "233,234,235,236,237,238,239,240", + "breakout_modes": { + "1x1600G": [ + "Eth31" + ], + "2x800G": [ + "Eth31/1", + "Eth31/2" + ], + "4x400G": [ + "Eth31/1", + "Eth31/2", + "Eth31/3", + "Eth31/4" + ], + "8x200G": [ + "Eth31/1", + "Eth31/2", + "Eth31/3", + "Eth31/4", + "Eth31/5", + "Eth31/6", + "Eth31/7", + "Eth31/8" + ], + "2x400G": [ + "Eth31/1", + "Eth31/2" + ], + "4x200G": [ + "Eth31/1", + "Eth31/2", + "Eth31/3", + "Eth31/4" + ], + "8x100G": [ + "Eth31/1", + "Eth31/2", + "Eth31/3", + "Eth31/4", + "Eth31/5", + "Eth31/6", + "Eth31/7", + "Eth31/8" + ], + "1x400G(4)": [ + "Eth31/1" + ], + "1x200G(2)": [ + "Eth31/1" + ], + "1x100G(1)": [ + "Eth31/1" + ], + "1x200G(1)": [ + "Eth31/1" + ] + } + }, + "Ethernet249": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "225,226,227,228,229,230,231,232", + "breakout_modes": { + "1x1600G": [ + "Eth32" + ], + "2x800G": [ + "Eth32/1", + "Eth32/2" + ], + "4x400G": [ + "Eth32/1", + "Eth32/2", + "Eth32/3", + "Eth32/4" + ], + "8x200G": [ + "Eth32/1", + "Eth32/2", + "Eth32/3", + "Eth32/4", + "Eth32/5", + "Eth32/6", + "Eth32/7", + "Eth32/8" + ], + "2x400G": [ + "Eth32/1", + "Eth32/2" + ], + "4x200G": [ + "Eth32/1", + "Eth32/2", + "Eth32/3", + "Eth32/4" + ], + "8x100G": [ + "Eth32/1", + "Eth32/2", + "Eth32/3", + "Eth32/4", + "Eth32/5", + "Eth32/6", + "Eth32/7", + "Eth32/8" + ], + "1x400G(4)": [ + "Eth32/1" + ], + "1x200G(2)": [ + "Eth32/1" + ], + "1x100G(1)": [ + "Eth32/1" + ], + "1x200G(1)": [ + "Eth32/1" + ] + } + }, + "Ethernet257": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "481,482,483,484,485,486,487,488", + "breakout_modes": { + "1x1600G": [ + "Eth33" + ], + "2x800G": [ + "Eth33/1", + "Eth33/2" + ], + "4x400G": [ + "Eth33/1", + "Eth33/2", + "Eth33/3", + "Eth33/4" + ], + "8x200G": [ + "Eth33/1", + "Eth33/2", + "Eth33/3", + "Eth33/4", + "Eth33/5", + "Eth33/6", + "Eth33/7", + "Eth33/8" + ], + "2x400G": [ + "Eth33/1", + "Eth33/2" + ], + "4x200G": [ + "Eth33/1", + "Eth33/2", + "Eth33/3", + "Eth33/4" + ], + "8x100G": [ + "Eth33/1", + "Eth33/2", + "Eth33/3", + "Eth33/4", + "Eth33/5", + "Eth33/6", + "Eth33/7", + "Eth33/8" + ], + "1x400G(4)": [ + "Eth33/1" + ], + "1x200G(2)": [ + "Eth33/1" + ], + "1x100G(1)": [ + "Eth33/1" + ], + "1x200G(1)": [ + "Eth33/1" + ] + } + }, + "Ethernet265": { + "index": "33,33,33,33,33,33,33,33", + "lanes": "473,474,475,476,477,478,479,480", + "breakout_modes": { + "1x1600G": [ + "Eth34" + ], + "2x800G": [ + "Eth34/1", + "Eth34/2" + ], + "4x400G": [ + "Eth34/1", + "Eth34/2", + "Eth34/3", + "Eth34/4" + ], + "8x200G": [ + "Eth34/1", + "Eth34/2", + "Eth34/3", + "Eth34/4", + "Eth34/5", + "Eth34/6", + "Eth34/7", + "Eth34/8" + ], + "2x400G": [ + "Eth34/1", + "Eth34/2" + ], + "4x200G": [ + "Eth34/1", + "Eth34/2", + "Eth34/3", + "Eth34/4" + ], + "8x100G": [ + "Eth34/1", + "Eth34/2", + "Eth34/3", + "Eth34/4", + "Eth34/5", + "Eth34/6", + "Eth34/7", + "Eth34/8" + ], + "1x400G(4)": [ + "Eth34/1" + ], + "1x200G(2)": [ + "Eth34/1" + ], + "1x100G(1)": [ + "Eth34/1" + ], + "1x200G(1)": [ + "Eth34/1" + ] + } + }, + "Ethernet273": { + "index": "34,34,34,34,34,34,34,34", + "lanes": "257,258,259,260,261,262,263,264", + "breakout_modes": { + "1x1600G": [ + "Eth35" + ], + "2x800G": [ + "Eth35/1", + "Eth35/2" + ], + "4x400G": [ + "Eth35/1", + "Eth35/2", + "Eth35/3", + "Eth35/4" + ], + "8x200G": [ + "Eth35/1", + "Eth35/2", + "Eth35/3", + "Eth35/4", + "Eth35/5", + "Eth35/6", + "Eth35/7", + "Eth35/8" + ], + "2x400G": [ + "Eth35/1", + "Eth35/2" + ], + "4x200G": [ + "Eth35/1", + "Eth35/2", + "Eth35/3", + "Eth35/4" + ], + "8x100G": [ + "Eth35/1", + "Eth35/2", + "Eth35/3", + "Eth35/4", + "Eth35/5", + "Eth35/6", + "Eth35/7", + "Eth35/8" + ], + "1x400G(4)": [ + "Eth35/1" + ], + "1x200G(2)": [ + "Eth35/1" + ], + "1x100G(1)": [ + "Eth35/1" + ], + "1x200G(1)": [ + "Eth35/1" + ] + } + }, + "Ethernet281": { + "index": "35,35,35,35,35,35,35,35", + "lanes": "265,266,267,268,269,270,271,272", + "breakout_modes": { + "1x1600G": [ + "Eth36" + ], + "2x800G": [ + "Eth36/1", + "Eth36/2" + ], + "4x400G": [ + "Eth36/1", + "Eth36/2", + "Eth36/3", + "Eth36/4" + ], + "8x200G": [ + "Eth36/1", + "Eth36/2", + "Eth36/3", + "Eth36/4", + "Eth36/5", + "Eth36/6", + "Eth36/7", + "Eth36/8" + ], + "2x400G": [ + "Eth36/1", + "Eth36/2" + ], + "4x200G": [ + "Eth36/1", + "Eth36/2", + "Eth36/3", + "Eth36/4" + ], + "8x100G": [ + "Eth36/1", + "Eth36/2", + "Eth36/3", + "Eth36/4", + "Eth36/5", + "Eth36/6", + "Eth36/7", + "Eth36/8" + ], + "1x400G(4)": [ + "Eth36/1" + ], + "1x200G(2)": [ + "Eth36/1" + ], + "1x100G(1)": [ + "Eth36/1" + ], + "1x200G(1)": [ + "Eth36/1" + ] + } + }, + "Ethernet289": { + "index": "36,36,36,36,36,36,36,36", + "lanes": "489,490,491,492,493,494,495,496", + "breakout_modes": { + "1x1600G": [ + "Eth37" + ], + "2x800G": [ + "Eth37/1", + "Eth37/2" + ], + "4x400G": [ + "Eth37/1", + "Eth37/2", + "Eth37/3", + "Eth37/4" + ], + "8x200G": [ + "Eth37/1", + "Eth37/2", + "Eth37/3", + "Eth37/4", + "Eth37/5", + "Eth37/6", + "Eth37/7", + "Eth37/8" + ], + "2x400G": [ + "Eth37/1", + "Eth37/2" + ], + "4x200G": [ + "Eth37/1", + "Eth37/2", + "Eth37/3", + "Eth37/4" + ], + "8x100G": [ + "Eth37/1", + "Eth37/2", + "Eth37/3", + "Eth37/4", + "Eth37/5", + "Eth37/6", + "Eth37/7", + "Eth37/8" + ], + "1x400G(4)": [ + "Eth37/1" + ], + "1x200G(2)": [ + "Eth37/1" + ], + "1x100G(1)": [ + "Eth37/1" + ], + "1x200G(1)": [ + "Eth37/1" + ] + } + }, + "Ethernet297": { + "index": "37,37,37,37,37,37,37,37", + "lanes": "465,466,467,468,469,470,471,472", + "breakout_modes": { + "1x1600G": [ + "Eth38" + ], + "2x800G": [ + "Eth38/1", + "Eth38/2" + ], + "4x400G": [ + "Eth38/1", + "Eth38/2", + "Eth38/3", + "Eth38/4" + ], + "8x200G": [ + "Eth38/1", + "Eth38/2", + "Eth38/3", + "Eth38/4", + "Eth38/5", + "Eth38/6", + "Eth38/7", + "Eth38/8" + ], + "2x400G": [ + "Eth38/1", + "Eth38/2" + ], + "4x200G": [ + "Eth38/1", + "Eth38/2", + "Eth38/3", + "Eth38/4" + ], + "8x100G": [ + "Eth38/1", + "Eth38/2", + "Eth38/3", + "Eth38/4", + "Eth38/5", + "Eth38/6", + "Eth38/7", + "Eth38/8" + ], + "1x400G(4)": [ + "Eth38/1" + ], + "1x200G(2)": [ + "Eth38/1" + ], + "1x100G(1)": [ + "Eth38/1" + ], + "1x200G(1)": [ + "Eth38/1" + ] + } + }, + "Ethernet305": { + "index": "38,38,38,38,38,38,38,38", + "lanes": "273,274,275,276,277,278,279,280", + "breakout_modes": { + "1x1600G": [ + "Eth39" + ], + "2x800G": [ + "Eth39/1", + "Eth39/2" + ], + "4x400G": [ + "Eth39/1", + "Eth39/2", + "Eth39/3", + "Eth39/4" + ], + "8x200G": [ + "Eth39/1", + "Eth39/2", + "Eth39/3", + "Eth39/4", + "Eth39/5", + "Eth39/6", + "Eth39/7", + "Eth39/8" + ], + "2x400G": [ + "Eth39/1", + "Eth39/2" + ], + "4x200G": [ + "Eth39/1", + "Eth39/2", + "Eth39/3", + "Eth39/4" + ], + "8x100G": [ + "Eth39/1", + "Eth39/2", + "Eth39/3", + "Eth39/4", + "Eth39/5", + "Eth39/6", + "Eth39/7", + "Eth39/8" + ], + "1x400G(4)": [ + "Eth39/1" + ], + "1x200G(2)": [ + "Eth39/1" + ], + "1x100G(1)": [ + "Eth39/1" + ], + "1x200G(1)": [ + "Eth39/1" + ] + } + }, + "Ethernet313": { + "index": "39,39,39,39,39,39,39,39", + "lanes": "281,282,283,284,285,286,287,288", + "breakout_modes": { + "1x1600G": [ + "Eth40" + ], + "2x800G": [ + "Eth40/1", + "Eth40/2" + ], + "4x400G": [ + "Eth40/1", + "Eth40/2", + "Eth40/3", + "Eth40/4" + ], + "8x200G": [ + "Eth40/1", + "Eth40/2", + "Eth40/3", + "Eth40/4", + "Eth40/5", + "Eth40/6", + "Eth40/7", + "Eth40/8" + ], + "2x400G": [ + "Eth40/1", + "Eth40/2" + ], + "4x200G": [ + "Eth40/1", + "Eth40/2", + "Eth40/3", + "Eth40/4" + ], + "8x100G": [ + "Eth40/1", + "Eth40/2", + "Eth40/3", + "Eth40/4", + "Eth40/5", + "Eth40/6", + "Eth40/7", + "Eth40/8" + ], + "1x400G(4)": [ + "Eth40/1" + ], + "1x200G(2)": [ + "Eth40/1" + ], + "1x100G(1)": [ + "Eth40/1" + ], + "1x200G(1)": [ + "Eth40/1" + ] + } + }, + "Ethernet321": { + "index": "40,40,40,40,40,40,40,40", + "lanes": "497,498,499,500,501,502,503,504", + "breakout_modes": { + "1x1600G": [ + "Eth41" + ], + "2x800G": [ + "Eth41/1", + "Eth41/2" + ], + "4x400G": [ + "Eth41/1", + "Eth41/2", + "Eth41/3", + "Eth41/4" + ], + "8x200G": [ + "Eth41/1", + "Eth41/2", + "Eth41/3", + "Eth41/4", + "Eth41/5", + "Eth41/6", + "Eth41/7", + "Eth41/8" + ], + "2x400G": [ + "Eth41/1", + "Eth41/2" + ], + "4x200G": [ + "Eth41/1", + "Eth41/2", + "Eth41/3", + "Eth41/4" + ], + "8x100G": [ + "Eth41/1", + "Eth41/2", + "Eth41/3", + "Eth41/4", + "Eth41/5", + "Eth41/6", + "Eth41/7", + "Eth41/8" + ], + "1x400G(4)": [ + "Eth41/1" + ], + "1x200G(2)": [ + "Eth41/1" + ], + "1x100G(1)": [ + "Eth41/1" + ], + "1x200G(1)": [ + "Eth41/1" + ] + } + }, + "Ethernet329": { + "index": "41,41,41,41,41,41,41,41", + "lanes": "457,458,459,460,461,462,463,464", + "breakout_modes": { + "1x1600G": [ + "Eth42" + ], + "2x800G": [ + "Eth42/1", + "Eth42/2" + ], + "4x400G": [ + "Eth42/1", + "Eth42/2", + "Eth42/3", + "Eth42/4" + ], + "8x200G": [ + "Eth42/1", + "Eth42/2", + "Eth42/3", + "Eth42/4", + "Eth42/5", + "Eth42/6", + "Eth42/7", + "Eth42/8" + ], + "2x400G": [ + "Eth42/1", + "Eth42/2" + ], + "4x200G": [ + "Eth42/1", + "Eth42/2", + "Eth42/3", + "Eth42/4" + ], + "8x100G": [ + "Eth42/1", + "Eth42/2", + "Eth42/3", + "Eth42/4", + "Eth42/5", + "Eth42/6", + "Eth42/7", + "Eth42/8" + ], + "1x400G(4)": [ + "Eth42/1" + ], + "1x200G(2)": [ + "Eth42/1" + ], + "1x100G(1)": [ + "Eth42/1" + ], + "1x200G(1)": [ + "Eth42/1" + ] + } + }, + "Ethernet337": { + "index": "42,42,42,42,42,42,42,42", + "lanes": "313,314,315,316,317,318,319,320", + "breakout_modes": { + "1x1600G": [ + "Eth43" + ], + "2x800G": [ + "Eth43/1", + "Eth43/2" + ], + "4x400G": [ + "Eth43/1", + "Eth43/2", + "Eth43/3", + "Eth43/4" + ], + "8x200G": [ + "Eth43/1", + "Eth43/2", + "Eth43/3", + "Eth43/4", + "Eth43/5", + "Eth43/6", + "Eth43/7", + "Eth43/8" + ], + "2x400G": [ + "Eth43/1", + "Eth43/2" + ], + "4x200G": [ + "Eth43/1", + "Eth43/2", + "Eth43/3", + "Eth43/4" + ], + "8x100G": [ + "Eth43/1", + "Eth43/2", + "Eth43/3", + "Eth43/4", + "Eth43/5", + "Eth43/6", + "Eth43/7", + "Eth43/8" + ], + "1x400G(4)": [ + "Eth43/1" + ], + "1x200G(2)": [ + "Eth43/1" + ], + "1x100G(1)": [ + "Eth43/1" + ], + "1x200G(1)": [ + "Eth43/1" + ] + } + }, + "Ethernet345": { + "index": "43,43,43,43,43,43,43,43", + "lanes": "305,306,307,308,309,310,311,312", + "breakout_modes": { + "1x1600G": [ + "Eth44" + ], + "2x800G": [ + "Eth44/1", + "Eth44/2" + ], + "4x400G": [ + "Eth44/1", + "Eth44/2", + "Eth44/3", + "Eth44/4" + ], + "8x200G": [ + "Eth44/1", + "Eth44/2", + "Eth44/3", + "Eth44/4", + "Eth44/5", + "Eth44/6", + "Eth44/7", + "Eth44/8" + ], + "2x400G": [ + "Eth44/1", + "Eth44/2" + ], + "4x200G": [ + "Eth44/1", + "Eth44/2", + "Eth44/3", + "Eth44/4" + ], + "8x100G": [ + "Eth44/1", + "Eth44/2", + "Eth44/3", + "Eth44/4", + "Eth44/5", + "Eth44/6", + "Eth44/7", + "Eth44/8" + ], + "1x400G(4)": [ + "Eth44/1" + ], + "1x200G(2)": [ + "Eth44/1" + ], + "1x100G(1)": [ + "Eth44/1" + ], + "1x200G(1)": [ + "Eth44/1" + ] + } + }, + "Ethernet353": { + "index": "44,44,44,44,44,44,44,44", + "lanes": "505,506,507,508,509,510,511,512", + "breakout_modes": { + "1x1600G": [ + "Eth45" + ], + "2x800G": [ + "Eth45/1", + "Eth45/2" + ], + "4x400G": [ + "Eth45/1", + "Eth45/2", + "Eth45/3", + "Eth45/4" + ], + "8x200G": [ + "Eth45/1", + "Eth45/2", + "Eth45/3", + "Eth45/4", + "Eth45/5", + "Eth45/6", + "Eth45/7", + "Eth45/8" + ], + "2x400G": [ + "Eth45/1", + "Eth45/2" + ], + "4x200G": [ + "Eth45/1", + "Eth45/2", + "Eth45/3", + "Eth45/4" + ], + "8x100G": [ + "Eth45/1", + "Eth45/2", + "Eth45/3", + "Eth45/4", + "Eth45/5", + "Eth45/6", + "Eth45/7", + "Eth45/8" + ], + "1x400G(4)": [ + "Eth45/1" + ], + "1x200G(2)": [ + "Eth45/1" + ], + "1x100G(1)": [ + "Eth45/1" + ], + "1x200G(1)": [ + "Eth45/1" + ] + } + }, + "Ethernet361": { + "index": "45,45,45,45,45,45,45,45", + "lanes": "449,450,451,452,453,454,455,456", + "breakout_modes": { + "1x1600G": [ + "Eth46" + ], + "2x800G": [ + "Eth46/1", + "Eth46/2" + ], + "4x400G": [ + "Eth46/1", + "Eth46/2", + "Eth46/3", + "Eth46/4" + ], + "8x200G": [ + "Eth46/1", + "Eth46/2", + "Eth46/3", + "Eth46/4", + "Eth46/5", + "Eth46/6", + "Eth46/7", + "Eth46/8" + ], + "2x400G": [ + "Eth46/1", + "Eth46/2" + ], + "4x200G": [ + "Eth46/1", + "Eth46/2", + "Eth46/3", + "Eth46/4" + ], + "8x100G": [ + "Eth46/1", + "Eth46/2", + "Eth46/3", + "Eth46/4", + "Eth46/5", + "Eth46/6", + "Eth46/7", + "Eth46/8" + ], + "1x400G(4)": [ + "Eth46/1" + ], + "1x200G(2)": [ + "Eth46/1" + ], + "1x100G(1)": [ + "Eth46/1" + ], + "1x200G(1)": [ + "Eth46/1" + ] + } + }, + "Ethernet369": { + "index": "46,46,46,46,46,46,46,46", + "lanes": "297,298,299,300,301,302,303,304", + "breakout_modes": { + "1x1600G": [ + "Eth47" + ], + "2x800G": [ + "Eth47/1", + "Eth47/2" + ], + "4x400G": [ + "Eth47/1", + "Eth47/2", + "Eth47/3", + "Eth47/4" + ], + "8x200G": [ + "Eth47/1", + "Eth47/2", + "Eth47/3", + "Eth47/4", + "Eth47/5", + "Eth47/6", + "Eth47/7", + "Eth47/8" + ], + "2x400G": [ + "Eth47/1", + "Eth47/2" + ], + "4x200G": [ + "Eth47/1", + "Eth47/2", + "Eth47/3", + "Eth47/4" + ], + "8x100G": [ + "Eth47/1", + "Eth47/2", + "Eth47/3", + "Eth47/4", + "Eth47/5", + "Eth47/6", + "Eth47/7", + "Eth47/8" + ], + "1x400G(4)": [ + "Eth47/1" + ], + "1x200G(2)": [ + "Eth47/1" + ], + "1x100G(1)": [ + "Eth47/1" + ], + "1x200G(1)": [ + "Eth47/1" + ] + } + }, + "Ethernet377": { + "index": "47,47,47,47,47,47,47,47", + "lanes": "289,290,291,292,293,294,295,296", + "breakout_modes": { + "1x1600G": [ + "Eth48" + ], + "2x800G": [ + "Eth48/1", + "Eth48/2" + ], + "4x400G": [ + "Eth48/1", + "Eth48/2", + "Eth48/3", + "Eth48/4" + ], + "8x200G": [ + "Eth48/1", + "Eth48/2", + "Eth48/3", + "Eth48/4", + "Eth48/5", + "Eth48/6", + "Eth48/7", + "Eth48/8" + ], + "2x400G": [ + "Eth48/1", + "Eth48/2" + ], + "4x200G": [ + "Eth48/1", + "Eth48/2", + "Eth48/3", + "Eth48/4" + ], + "8x100G": [ + "Eth48/1", + "Eth48/2", + "Eth48/3", + "Eth48/4", + "Eth48/5", + "Eth48/6", + "Eth48/7", + "Eth48/8" + ], + "1x400G(4)": [ + "Eth48/1" + ], + "1x200G(2)": [ + "Eth48/1" + ], + "1x100G(1)": [ + "Eth48/1" + ], + "1x200G(1)": [ + "Eth48/1" + ] + } + }, + "Ethernet385": { + "index": "48,48,48,48,48,48,48,48", + "lanes": "385,386,387,388,389,390,391,392", + "breakout_modes": { + "1x1600G": [ + "Eth49" + ], + "2x800G": [ + "Eth49/1", + "Eth49/2" + ], + "4x400G": [ + "Eth49/1", + "Eth49/2", + "Eth49/3", + "Eth49/4" + ], + "8x200G": [ + "Eth49/1", + "Eth49/2", + "Eth49/3", + "Eth49/4", + "Eth49/5", + "Eth49/6", + "Eth49/7", + "Eth49/8" + ], + "2x400G": [ + "Eth49/1", + "Eth49/2" + ], + "4x200G": [ + "Eth49/1", + "Eth49/2", + "Eth49/3", + "Eth49/4" + ], + "8x100G": [ + "Eth49/1", + "Eth49/2", + "Eth49/3", + "Eth49/4", + "Eth49/5", + "Eth49/6", + "Eth49/7", + "Eth49/8" + ], + "1x400G(4)": [ + "Eth49/1" + ], + "1x200G(2)": [ + "Eth49/1" + ], + "1x100G(1)": [ + "Eth49/1" + ], + "1x200G(1)": [ + "Eth49/1" + ] + } + }, + "Ethernet393": { + "index": "49,49,49,49,49,49,49,49", + "lanes": "441,442,443,444,445,446,447,448", + "breakout_modes": { + "1x1600G": [ + "Eth50" + ], + "2x800G": [ + "Eth50/1", + "Eth50/2" + ], + "4x400G": [ + "Eth50/1", + "Eth50/2", + "Eth50/3", + "Eth50/4" + ], + "8x200G": [ + "Eth50/1", + "Eth50/2", + "Eth50/3", + "Eth50/4", + "Eth50/5", + "Eth50/6", + "Eth50/7", + "Eth50/8" + ], + "2x400G": [ + "Eth50/1", + "Eth50/2" + ], + "4x200G": [ + "Eth50/1", + "Eth50/2", + "Eth50/3", + "Eth50/4" + ], + "8x100G": [ + "Eth50/1", + "Eth50/2", + "Eth50/3", + "Eth50/4", + "Eth50/5", + "Eth50/6", + "Eth50/7", + "Eth50/8" + ], + "1x400G(4)": [ + "Eth50/1" + ], + "1x200G(2)": [ + "Eth50/1" + ], + "1x100G(1)": [ + "Eth50/1" + ], + "1x200G(1)": [ + "Eth50/1" + ] + } + }, + "Ethernet401": { + "index": "50,50,50,50,50,50,50,50", + "lanes": "321,322,323,324,325,326,327,328", + "breakout_modes": { + "1x1600G": [ + "Eth51" + ], + "2x800G": [ + "Eth51/1", + "Eth51/2" + ], + "4x400G": [ + "Eth51/1", + "Eth51/2", + "Eth51/3", + "Eth51/4" + ], + "8x200G": [ + "Eth51/1", + "Eth51/2", + "Eth51/3", + "Eth51/4", + "Eth51/5", + "Eth51/6", + "Eth51/7", + "Eth51/8" + ], + "2x400G": [ + "Eth51/1", + "Eth51/2" + ], + "4x200G": [ + "Eth51/1", + "Eth51/2", + "Eth51/3", + "Eth51/4" + ], + "8x100G": [ + "Eth51/1", + "Eth51/2", + "Eth51/3", + "Eth51/4", + "Eth51/5", + "Eth51/6", + "Eth51/7", + "Eth51/8" + ], + "1x400G(4)": [ + "Eth51/1" + ], + "1x200G(2)": [ + "Eth51/1" + ], + "1x100G(1)": [ + "Eth51/1" + ], + "1x200G(1)": [ + "Eth51/1" + ] + } + }, + "Ethernet409": { + "index": "51,51,51,51,51,51,51,51", + "lanes": "329,330,331,332,333,334,335,336", + "breakout_modes": { + "1x1600G": [ + "Eth52" + ], + "2x800G": [ + "Eth52/1", + "Eth52/2" + ], + "4x400G": [ + "Eth52/1", + "Eth52/2", + "Eth52/3", + "Eth52/4" + ], + "8x200G": [ + "Eth52/1", + "Eth52/2", + "Eth52/3", + "Eth52/4", + "Eth52/5", + "Eth52/6", + "Eth52/7", + "Eth52/8" + ], + "2x400G": [ + "Eth52/1", + "Eth52/2" + ], + "4x200G": [ + "Eth52/1", + "Eth52/2", + "Eth52/3", + "Eth52/4" + ], + "8x100G": [ + "Eth52/1", + "Eth52/2", + "Eth52/3", + "Eth52/4", + "Eth52/5", + "Eth52/6", + "Eth52/7", + "Eth52/8" + ], + "1x400G(4)": [ + "Eth52/1" + ], + "1x200G(2)": [ + "Eth52/1" + ], + "1x100G(1)": [ + "Eth52/1" + ], + "1x200G(1)": [ + "Eth52/1" + ] + } + }, + "Ethernet417": { + "index": "52,52,52,52,52,52,52,52", + "lanes": "393,394,395,396,397,398,399,400", + "breakout_modes": { + "1x1600G": [ + "Eth53" + ], + "2x800G": [ + "Eth53/1", + "Eth53/2" + ], + "4x400G": [ + "Eth53/1", + "Eth53/2", + "Eth53/3", + "Eth53/4" + ], + "8x200G": [ + "Eth53/1", + "Eth53/2", + "Eth53/3", + "Eth53/4", + "Eth53/5", + "Eth53/6", + "Eth53/7", + "Eth53/8" + ], + "2x400G": [ + "Eth53/1", + "Eth53/2" + ], + "4x200G": [ + "Eth53/1", + "Eth53/2", + "Eth53/3", + "Eth53/4" + ], + "8x100G": [ + "Eth53/1", + "Eth53/2", + "Eth53/3", + "Eth53/4", + "Eth53/5", + "Eth53/6", + "Eth53/7", + "Eth53/8" + ], + "1x400G(4)": [ + "Eth53/1" + ], + "1x200G(2)": [ + "Eth53/1" + ], + "1x100G(1)": [ + "Eth53/1" + ], + "1x200G(1)": [ + "Eth53/1" + ] + } + }, + "Ethernet425": { + "index": "53,53,53,53,53,53,53,53", + "lanes": "433,434,435,436,437,438,439,440", + "breakout_modes": { + "1x1600G": [ + "Eth54" + ], + "2x800G": [ + "Eth54/1", + "Eth54/2" + ], + "4x400G": [ + "Eth54/1", + "Eth54/2", + "Eth54/3", + "Eth54/4" + ], + "8x200G": [ + "Eth54/1", + "Eth54/2", + "Eth54/3", + "Eth54/4", + "Eth54/5", + "Eth54/6", + "Eth54/7", + "Eth54/8" + ], + "2x400G": [ + "Eth54/1", + "Eth54/2" + ], + "4x200G": [ + "Eth54/1", + "Eth54/2", + "Eth54/3", + "Eth54/4" + ], + "8x100G": [ + "Eth54/1", + "Eth54/2", + "Eth54/3", + "Eth54/4", + "Eth54/5", + "Eth54/6", + "Eth54/7", + "Eth54/8" + ], + "1x400G(4)": [ + "Eth54/1" + ], + "1x200G(2)": [ + "Eth54/1" + ], + "1x100G(1)": [ + "Eth54/1" + ], + "1x200G(1)": [ + "Eth54/1" + ] + } + }, + "Ethernet433": { + "index": "54,54,54,54,54,54,54,54", + "lanes": "337,338,339,340,341,342,343,344", + "breakout_modes": { + "1x1600G": [ + "Eth55" + ], + "2x800G": [ + "Eth55/1", + "Eth55/2" + ], + "4x400G": [ + "Eth55/1", + "Eth55/2", + "Eth55/3", + "Eth55/4" + ], + "8x200G": [ + "Eth55/1", + "Eth55/2", + "Eth55/3", + "Eth55/4", + "Eth55/5", + "Eth55/6", + "Eth55/7", + "Eth55/8" + ], + "2x400G": [ + "Eth55/1", + "Eth55/2" + ], + "4x200G": [ + "Eth55/1", + "Eth55/2", + "Eth55/3", + "Eth55/4" + ], + "8x100G": [ + "Eth55/1", + "Eth55/2", + "Eth55/3", + "Eth55/4", + "Eth55/5", + "Eth55/6", + "Eth55/7", + "Eth55/8" + ], + "1x100G(1)": [ + "Eth55" + ], + "1x200G(2)": [ + "Eth55/1" + ], + "1x400G(4)": [ + "Eth55/1" + ], + "1x200G(1)": [ + "Eth55/1" + ] + } + }, + "Ethernet441": { + "index": "55,55,55,55,55,55,55,55", + "lanes": "345,346,347,348,349,350,351,352", + "breakout_modes": { + "1x1600G": [ + "Eth56" + ], + "2x800G": [ + "Eth56/1", + "Eth56/2" + ], + "4x400G": [ + "Eth56/1", + "Eth56/2", + "Eth56/3", + "Eth56/4" + ], + "8x200G": [ + "Eth56/1", + "Eth56/2", + "Eth56/3", + "Eth56/4", + "Eth56/5", + "Eth56/6", + "Eth56/7", + "Eth56/8" + ], + "2x400G": [ + "Eth56/1", + "Eth56/2" + ], + "4x200G": [ + "Eth56/1", + "Eth56/2", + "Eth56/3", + "Eth56/4" + ], + "8x100G": [ + "Eth56/1", + "Eth56/2", + "Eth56/3", + "Eth56/4", + "Eth56/5", + "Eth56/6", + "Eth56/7", + "Eth56/8" + ], + "1x400G(4)": [ + "Eth56/1" + ], + "1x200G(2)": [ + "Eth56/1" + ], + "1x100G(1)": [ + "Eth56/1" + ], + "1x200G(1)": [ + "Eth56/1" + ] + } + }, + "Ethernet449": { + "index": "56,56,56,56,56,56,56,56", + "lanes": "401,402,403,404,405,406,407,408", + "breakout_modes": { + "1x1600G": [ + "Eth57" + ], + "2x800G": [ + "Eth57/1", + "Eth57/2" + ], + "4x400G": [ + "Eth57/1", + "Eth57/2", + "Eth57/3", + "Eth57/4" + ], + "8x200G": [ + "Eth57/1", + "Eth57/2", + "Eth57/3", + "Eth57/4", + "Eth57/5", + "Eth57/6", + "Eth57/7", + "Eth57/8" + ], + "2x400G": [ + "Eth57/1", + "Eth57/2" + ], + "4x200G": [ + "Eth57/1", + "Eth57/2", + "Eth57/3", + "Eth57/4" + ], + "8x100G": [ + "Eth57/1", + "Eth57/2", + "Eth57/3", + "Eth57/4", + "Eth57/5", + "Eth57/6", + "Eth57/7", + "Eth57/8" + ], + "1x400G(4)": [ + "Eth57/1" + ], + "1x200G(2)": [ + "Eth57/1" + ], + "1x100G(1)": [ + "Eth57/1" + ], + "1x200G(1)": [ + "Eth57/1" + ] + } + }, + "Ethernet457": { + "index": "57,57,57,57,57,57,57,57", + "lanes": "425,426,427,428,429,430,431,432", + "breakout_modes": { + "1x1600G": [ + "Eth58" + ], + "2x800G": [ + "Eth58/1", + "Eth58/2" + ], + "4x400G": [ + "Eth58/1", + "Eth58/2", + "Eth58/3", + "Eth58/4" + ], + "8x200G": [ + "Eth58/1", + "Eth58/2", + "Eth58/3", + "Eth58/4", + "Eth58/5", + "Eth58/6", + "Eth58/7", + "Eth58/8" + ], + "2x400G": [ + "Eth58/1", + "Eth58/2" + ], + "4x200G": [ + "Eth58/1", + "Eth58/2", + "Eth58/3", + "Eth58/4" + ], + "8x100G": [ + "Eth58/1", + "Eth58/2", + "Eth58/3", + "Eth58/4", + "Eth58/5", + "Eth58/6", + "Eth58/7", + "Eth58/8" + ], + "1x400G(4)": [ + "Eth58/1" + ], + "1x200G(2)": [ + "Eth58/1" + ], + "1x100G(1)": [ + "Eth58/1" + ], + "1x200G(1)": [ + "Eth58/1" + ] + } + }, + "Ethernet465": { + "index": "58,58,58,58,58,58,58,58", + "lanes": "377,378,379,380,381,382,383,384", + "breakout_modes": { + "1x1600G": [ + "Eth59" + ], + "2x800G": [ + "Eth59/1", + "Eth59/2" + ], + "4x400G": [ + "Eth59/1", + "Eth59/2", + "Eth59/3", + "Eth59/4" + ], + "8x200G": [ + "Eth59/1", + "Eth59/2", + "Eth59/3", + "Eth59/4", + "Eth59/5", + "Eth59/6", + "Eth59/7", + "Eth59/8" + ], + "2x400G": [ + "Eth59/1", + "Eth59/2" + ], + "4x200G": [ + "Eth59/1", + "Eth59/2", + "Eth59/3", + "Eth59/4" + ], + "8x100G": [ + "Eth59/1", + "Eth59/2", + "Eth59/3", + "Eth59/4", + "Eth59/5", + "Eth59/6", + "Eth59/7", + "Eth59/8" + ], + "1x400G(4)": [ + "Eth59/1" + ], + "1x200G(2)": [ + "Eth59/1" + ], + "1x100G(1)": [ + "Eth59/1" + ], + "1x200G(1)": [ + "Eth59/1" + ] + } + }, + "Ethernet473": { + "index": "59,59,59,59,59,59,59,59", + "lanes": "369,370,371,372,373,374,375,376", + "breakout_modes": { + "1x1600G": [ + "Eth60" + ], + "2x800G": [ + "Eth60/1", + "Eth60/2" + ], + "4x400G": [ + "Eth60/1", + "Eth60/2", + "Eth60/3", + "Eth60/4" + ], + "8x200G": [ + "Eth60/1", + "Eth60/2", + "Eth60/3", + "Eth60/4", + "Eth60/5", + "Eth60/6", + "Eth60/7", + "Eth60/8" + ], + "2x400G": [ + "Eth60/1", + "Eth60/2" + ], + "4x200G": [ + "Eth60/1", + "Eth60/2", + "Eth60/3", + "Eth60/4" + ], + "8x100G": [ + "Eth60/1", + "Eth60/2", + "Eth60/3", + "Eth60/4", + "Eth60/5", + "Eth60/6", + "Eth60/7", + "Eth60/8" + ], + "1x100G(1)": [ + "Eth60" + ], + "1x200G(2)": [ + "Eth60/1" + ], + "1x400G(4)": [ + "Eth60/1" + ], + "1x200G(1)": [ + "Eth60" + ] + } + }, + "Ethernet481": { + "index": "60,60,60,60,60,60,60,60", + "lanes": "409,410,411,412,413,414,415,416", + "breakout_modes": { + "1x1600G": [ + "Eth61" + ], + "2x800G": [ + "Eth61/1", + "Eth61/2" + ], + "4x400G": [ + "Eth61/1", + "Eth61/2", + "Eth61/3", + "Eth61/4" + ], + "8x200G": [ + "Eth61/1", + "Eth61/2", + "Eth61/3", + "Eth61/4", + "Eth61/5", + "Eth61/6", + "Eth61/7", + "Eth61/8" + ], + "2x400G": [ + "Eth61/1", + "Eth61/2" + ], + "4x200G": [ + "Eth61/1", + "Eth61/2", + "Eth61/3", + "Eth61/4" + ], + "8x100G": [ + "Eth61/1", + "Eth61/2", + "Eth61/3", + "Eth61/4", + "Eth61/5", + "Eth61/6", + "Eth61/7", + "Eth61/8" + ], + "1x400G(4)": [ + "Eth61/1" + ], + "1x200G(2)": [ + "Eth61/1" + ], + "1x100G(1)": [ + "Eth61/1" + ], + "1x200G(1)": [ + "Eth61/1" + ] + } + }, + "Ethernet489": { + "index": "61,61,61,61,61,61,61,61", + "lanes": "417,418,419,420,421,422,423,424", + "breakout_modes": { + "1x1600G": [ + "Eth62" + ], + "2x800G": [ + "Eth62/1", + "Eth62/2" + ], + "4x400G": [ + "Eth62/1", + "Eth62/2", + "Eth62/3", + "Eth62/4" + ], + "8x200G": [ + "Eth62/1", + "Eth62/2", + "Eth62/3", + "Eth62/4", + "Eth62/5", + "Eth62/6", + "Eth62/7", + "Eth62/8" + ], + "2x400G": [ + "Eth62/1", + "Eth62/2" + ], + "4x200G": [ + "Eth62/1", + "Eth62/2", + "Eth62/3", + "Eth62/4" + ], + "8x100G": [ + "Eth62/1", + "Eth62/2", + "Eth62/3", + "Eth62/4", + "Eth62/5", + "Eth62/6", + "Eth62/7", + "Eth62/8" + ], + "1x400G(4)": [ + "Eth62/1" + ], + "1x200G(2)": [ + "Eth62/1" + ], + "1x100G(1)": [ + "Eth62/1" + ], + "1x200G(1)": [ + "Eth62/1" + ] + } + }, + "Ethernet497": { + "index": "62,62,62,62,62,62,62,62", + "lanes": "361,362,363,364,365,366,367,368", + "breakout_modes": { + "1x1600G": [ + "Eth63" + ], + "2x800G": [ + "Eth63/1", + "Eth63/2" + ], + "4x400G": [ + "Eth63/1", + "Eth63/2", + "Eth63/3", + "Eth63/4" + ], + "8x200G": [ + "Eth63/1", + "Eth63/2", + "Eth63/3", + "Eth63/4", + "Eth63/5", + "Eth63/6", + "Eth63/7", + "Eth63/8" + ], + "2x400G": [ + "Eth63/1", + "Eth63/2" + ], + "4x200G": [ + "Eth63/1", + "Eth63/2", + "Eth63/3", + "Eth63/4" + ], + "8x100G": [ + "Eth63/1", + "Eth63/2", + "Eth63/3", + "Eth63/4", + "Eth63/5", + "Eth63/6", + "Eth63/7", + "Eth63/8" + ], + "1x400G(4)": [ + "Eth63/1" + ], + "1x200G(2)": [ + "Eth63/1" + ], + "1x100G(1)": [ + "Eth63/1" + ], + "1x200G(1)": [ + "Eth63/1" + ] + } + }, + "Ethernet505": { + "index": "63,63,63,63,63,63,63,63", + "lanes": "353,354,355,356,357,358,359,360", + "breakout_modes": { + "1x1600G": [ + "Eth64" + ], + "2x800G": [ + "Eth64/1", + "Eth64/2" + ], + "4x400G": [ + "Eth64/1", + "Eth64/2", + "Eth64/3", + "Eth64/4" + ], + "8x200G": [ + "Eth64/1", + "Eth64/2", + "Eth64/3", + "Eth64/4", + "Eth64/5", + "Eth64/6", + "Eth64/7", + "Eth64/8" + ], + "2x400G": [ + "Eth64/1", + "Eth64/2" + ], + "4x200G": [ + "Eth64/1", + "Eth64/2", + "Eth64/3", + "Eth64/4" + ], + "8x100G": [ + "Eth64/1", + "Eth64/2", + "Eth64/3", + "Eth64/4", + "Eth64/5", + "Eth64/6", + "Eth64/7", + "Eth64/8" + ], + "1x400G(4)": [ + "Eth64/1" + ], + "1x200G(2)": [ + "Eth64/1" + ], + "1x100G(1)": [ + "Eth64/1" + ], + "1x200G(1)": [ + "Eth64/1" + ] + } + }, + "Ethernet513": { + "index": "64", + "lanes": "514", + "breakout_modes": { + "1x25G": [ + "Eth65" + ] + } + }, + "Ethernet514": { + "index": "65", + "lanes": "517", + "breakout_modes": { + "1x25G": [ + "Eth66" + ] + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_asic b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_asic new file mode 100644 index 0000000000..9604676527 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_components.json b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_components.json new file mode 100644 index 0000000000..983383d34c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_components.json @@ -0,0 +1,17 @@ +{ + "chassis": { + "M2-W6951-64HC-CP": { + "component": { + "CPU_CPLD": { }, + "BASE_CPLD": { }, + "MAC_CPLDA": { }, + "MAC_CPLDB": { }, + "IO_CPLD": { }, + "FAN_CPLD": { }, + "MAC_FPGA": { }, + "IO_FPGA": { }, + "BIOS": { } + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_env.conf b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_env.conf new file mode 100644 index 0000000000..fc119184d5 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/platform_env.conf @@ -0,0 +1,2 @@ +is_ltsw_chip=1 +SYNCD_SHM_SIZE=1g diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/sfputil.py b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/sfputil.py new file mode 100644 index 0000000000..f27e64777a --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/sfputil.py @@ -0,0 +1,443 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + import traceback + import subprocess + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 65 + PORTS_IN_BLOCK = 66 + + EEPROM_OFFSET = 201 + SFP_DEVICE_TYPE = "optoe2" + QSFP_DEVICE_TYPE = "optoe1" + QSFP_DD_DEVICE_TYPE = "optoe3" + I2C_MAX_ATTEMPT = 3 + + OPTOE_TYPE1 = 1 + OPTOE_TYPE2 = 2 + OPTOE_TYPE3 = 3 + + SFP_STATUS_INSERTED = '1' + SFP_STATUS_REMOVED = '0' + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping ={} + port_dict = {} + + qsfp_ports_list = [] + qsfp_dd_ports_list = [] + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return self.qsfp_ports_list + + @property + def qsfp_dd_ports(self): + return self.qsfp_dd_ports_list + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + for x in range(self.PORT_START, self.PORTS_IN_BLOCK-2): + remainder = x % 2 + remain = (x)//2 + group = remainder + remain + if x in [2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31,34,35,38,39,42,43,46,47,50,51,54,55,58,59,62,63]: + self.port_to_i2cbus_mapping[x] = 200 + group + elif x in [0,1,4,5,8,9,12,13,16,17,20,21,24,25,28,29,32,33,36,37,40,41,44,45,48,49,52,53,56,57,60,61]: + self.port_to_i2cbus_mapping[x] = 233 + group + self.port_to_i2cbus_mapping[64] = 265 + self.port_to_i2cbus_mapping[65] = 265 + self.update_ports_list() + + SfpUtilBase.__init__(self) + + def _sfp_read_file_path(self, file_path, offset, num_bytes): + attempts = 0 + while attempts < self.I2C_MAX_ATTEMPT: + try: + file_path.seek(offset) + read_buf = file_path.read(num_bytes) + except: + attempts += 1 + time.sleep(0.05) + else: + return True, read_buf + return False, None + + def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): + """Tries to read the eeprom file to determine if the + device/sfp is present or not. If sfp present, the read returns + valid bytes. If not, read returns error 'Connection timed out""" + + if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): + return False + else: + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv + + def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): + try: + sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path + + # Write device address to new_device file + nd_file = open(sysfs_nd_path, "w") + nd_str = "%s %s" % (devtype, hex(devaddr)) + nd_file.write(nd_str) + nd_file.close() + + except Exception as err: + print("Error writing to new device file: %s" % str(err)) + return 1 + else: + return 0 + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/bus/i2c/devices" + + if port_num in self.port_to_eeprom_mapping.keys(): + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] + else: + sysfs_i2c_adapter_base_path = "/sys/bus/i2c/devices" + + i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + if i2c_adapter_id is None: + print("Error getting i2c bus num") + return None + + # Get i2c virtual bus path for the sfp + sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + str(i2c_adapter_id)) + + # If i2c bus for port does not exist + if not os.path.exists(sysfs_sfp_i2c_adapter_path): + print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + return None + + sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + str(i2c_adapter_id), + hex(devid)[-2:]) + + # If sfp device is not present on bus, Add it + if not os.path.exists(sysfs_sfp_i2c_client_path): + if port_num in self.qsfp_dd_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DD_DEVICE_TYPE) + elif port_num in self.qsfp_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE) + else: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE) + if ret != 0: + print("Error adding sfp device") + return None + + sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + return sysfs_sfp_i2c_client_eeprom_path + + def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) + if rv == False: + return None + + try: + if len(raw) == 0: + return None + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except: + return None + + return eeprom_raw + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.qsfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + cmd = "cat /sys/s3ip/transceiver/eth{}/present".format(str(port_num + 1)) + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + return False + if output == "1": + return True + return False + + def check_is_qsfpdd(self, port_num): + try: + if self.get_presence(port_num) == False: + return False + + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, 0, 1) + if eeprom_raw is None: + return False + # according to sff-8024 A0h Byte 0 is '1e','18' or '19' means the transceiver is qsfpdd, + if (eeprom_raw[0] == '1e' or eeprom_raw[0] == '18' or eeprom_raw[0] == '19'): + return True + except Exception as e: + print(traceback.format_exc()) + + return False + + def check_optoe_type(self, port_num, optoe_type): + if self.get_presence(port_num) == False: + return True + try: + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + dev_class_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/dev_class' + i2c_path = dev_class_path.format(str(self.port_to_i2cbus_mapping[port_num])) + cmd = "cat " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + if int(output) != optoe_type: + cmd = "echo " + str(optoe_type) + " > " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + return True + + except Exception as e: + print(traceback.format_exc()) + return False + + def update_ports_list(self): + self.qsfp_ports_list = [] + self.qsfp_dd_ports_list = [] + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + if (self.check_is_qsfpdd(x)): + self.qsfp_dd_ports_list.append(x) + else: + self.qsfp_ports_list.append(x) + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return True + + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + current_port_dict = {} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print ("get_transceiver_change_event:Invalid timeout value", timeout) + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print ('get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout) + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + # Check for OIR events and return updated port_dict + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(x): + current_port_dict[x] = self.SFP_STATUS_INSERTED + else: + current_port_dict[x] = self.SFP_STATUS_REMOVED + if (current_port_dict == self.port_dict): + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + self.update_ports_list() + return True, {} + else: + # Update reg value + self.update_ports_list() + self.port_dict = current_port_dict + return True, self.port_dict + print ("get_transceiver_change_event: Should not reach here.") + return False, {} + + def _twos_comp(self, num, bits): + try: + if ((num & (1 << (bits - 1))) != 0): + num = num - (1 << bits) + return num + except: + return 0 + + def get_highest_temperature(self): + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"{time.strftime('%F %T')} enter get_highest_temperature\n") + + highest_temperature = -9999 + + presence_flag = False + read_eeprom_flag = False + temperature_supported_flag = False + temperature_valid_flag = False + + for port in range(self.PORT_START, self.PORT_END + 1): + if port == 65: + continue + try: + present = self.get_presence(port) + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} present={present}\n") + + if not present: + continue + + presence_flag = True + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} eeprom_path={eeprom_path}\n") + + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + + if port in self.qsfp_dd_ports: + offset = 14 + temperature_supported_flag = True + + elif port in self.qsfp_ports: + offset = 22 + temperature_supported_flag = True + + else: + # SFP/SFP28: check A0h byte 92 bit6 before reading A2h temperature. + # bit6 = 1 means Digital Diagnostic Monitoring is implemented. + ddm_raw = self._read_eeprom_specific_bytes(eeprom, 92, 1) + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} DDM support byte={ddm_raw}\n") + + if ddm_raw is None or len(ddm_raw) != 1: + return 9999 + + ddm_type = int(ddm_raw[0], 16) + if (ddm_type & 0x40) == 0: + # DDM is not supported by this SFP/SFP28 module. + # Skip this port instead of treating it as a temperature fault. + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} DDM not supported, skip temperature\n") + continue + + offset = 256 + 96 + temperature_supported_flag = True + + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} temp_offset={offset}\n") + + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} eeprom_raw={eeprom_raw}\n") + + if eeprom_raw is None or len(eeprom_raw) != 2: + return 9999 + + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = self._twos_comp(result, 16) + result = float(result / 256.0) + + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} temp={result}\n") + + if -50 <= result <= 200: + temperature_valid_flag = True + highest_temperature = max(highest_temperature, result) + else: + return 8000 + + except Exception as e: + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} inner_exception={repr(e)}\n") + continue + + except Exception as e: + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"port={port} outer_exception={repr(e)}\n") + continue + + # all port not presence + if not presence_flag: + highest_temperature = -10000 + elif not read_eeprom_flag: + # At least one transceiver is present, but all EEPROM reads failed. + highest_temperature = 9998 + elif not temperature_supported_flag: + # EEPROM is readable, but no present transceiver supports temperature monitoring. + highest_temperature = -20000 + elif not temperature_valid_flag: + # Temperature monitoring is supported, but no valid temperature was read. + highest_temperature = 8000 + + highest_temperature = round(highest_temperature, 2) + + with open("/tmp/sfp_temp_debug.log", "a") as f: + f.write(f"{time.strftime('%F %T')} final highest={highest_temperature}\n") + + return highest_temperature diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/ssd_util.py b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/ssd_util.py new file mode 100644 index 0000000000..74ac0921dd --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/plugins/ssd_util.py @@ -0,0 +1,319 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_storage.storage_base import StorageBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(StorageBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "ER3-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" }, + "MTFDDAV240TCB-1AR1ZABAA" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + # Invalid avg_erase_count or nand_endurance. + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + if self.health == 'N/A': + return "NA" + else: + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + if self.temperature == 'N/A': + return 'NA' + else: + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pmon_daemon_control.json b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..6716a121a9 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true, + "include_sensormond": true +} diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/postinit_cmd_file.soc b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/postinit_cmd_file.soc new file mode 100644 index 0000000000..0f7f6bfea0 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/postinit_cmd_file.soc @@ -0,0 +1,4 @@ +led load /usr/share/sonic/platform/custom_led.bin +led auto on +led start +linkscan SwPortBitMap=xe,ce,cd,d3c \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/system_health_monitoring_config.json b/device/micas/x86_64-micas_m2-w6951-64hc-cp-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 399b14f2c5..5ddb6d4392 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -133,6 +133,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += \ $(MICAS_M2_W6920_32QC2X_PLATFORM_MODULE) \ $(MICAS_M2_W6510_32C_PLATFORM_MODULE) \ $(MICAS_M2_W6520_48C8QC_PLATFORM_MODULE) \ + $(MICAS_M2_W6950_128OC_PLATFORM_MODULE) \ + $(MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE) \ $(SMCI_SSE_T8164_PLATFORM_MODULE) \ $(SMCI_SSE_T8196_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-micas.mk b/platform/broadcom/platform-modules-micas.mk index 220b9a6ac0..a8fda8c096 100644 --- a/platform/broadcom/platform-modules-micas.mk +++ b/platform/broadcom/platform-modules-micas.mk @@ -72,3 +72,20 @@ export MICAS_M2_W6520_48C8QC_PLATFORM_MODULE_VERSION MICAS_M2_W6520_48C8QC_PLATFORM_MODULE = platform-modules-micas-m2-w6520-48c8qc_$(MICAS_M2_W6520_48C8QC_PLATFORM_MODULE_VERSION)_amd64.deb $(MICAS_M2_W6520_48C8QC_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6520-48c8qc-r0 $(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6520_48C8QC_PLATFORM_MODULE))) + +## M2-W6950-128OC +MICAS_M2_W6950_128OC_PLATFORM_MODULE_VERSION = 1.0 +export MICAS_M2_W6950_128OC_PLATFORM_MODULE_VERSION + +MICAS_M2_W6950_128OC_PLATFORM_MODULE = platform-modules-micas-m2-w6950-128oc_$(MICAS_M2_W6950_128OC_PLATFORM_MODULE_VERSION)_amd64.deb +$(MICAS_M2_W6950_128OC_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6950-128oc-r0 +$(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6950_128OC_PLATFORM_MODULE))) + +## M2-W6951-64HC-CP +MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE_VERSION = 1.0 +export MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE_VERSION + +MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE = platform-modules-micas-m2-w6951-64hc-cp_$(MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE_VERSION)_amd64.deb +$(MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6951-64hc-cp-r0 +$(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6951_64HC_CP_PLATFORM_MODULE))) + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/Makefile index 385dae0884..67650d7434 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/common/Makefile @@ -30,6 +30,7 @@ all: @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi @if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi @if [ -d $(PWD)/sonic_platform/ ]; then cp -rf $(PWD)/sonic_platform ${INSTALL_LIB_DIR} ;fi + cp -r $(app_build_dir)/module/*.ko $(INSTALL_MODULE_DIR) cp -r $(modules_build_dir)/*.ko $(INSTALL_MODULE_DIR) cp -r $(app_dir)/build/app/* $(INSTALL_SCRIPT_DIR) cp -r $(SCRIPT_DIR)/* $(INSTALL_SCRIPT_DIR) @@ -37,5 +38,6 @@ all: @if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi @if [ ! -d ${INSTALL_BLACK_DRIVER} ]; then mkdir -p ${INSTALL_BLACK_DRIVER} ;fi cp -r $(BLACK_DRIVER_CONF_DIR)/* $(INSTALL_BLACK_DRIVER) + clean: rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/app/Makefile index 25ba3c5a91..7931ec70e7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/Makefile @@ -7,7 +7,8 @@ INC = -I./inc COMMON_OUT_PUT := $(shell pwd)/build common_out_put_dir := $(COMMON_OUT_PUT)/app common_module_dir := $(COMMON_OUT_PUT)/module/ -export common_out_put_dir common_module_dir +port_out_put_dir := $(COMMON_OUT_PUT)/app +export common_out_put_dir common_module_dir port_out_put_dir all : CHECK $(SUBDIRS) CHECK : diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/Makefile index e4078716eb..ee4e4946b5 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/Makefile @@ -25,6 +25,7 @@ install: @mkdir -p $(common_out_put_dir) cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + rebuild: clean all clean: @rm -rf $(BUILD_OUTPUT)/* diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c index 7141ef08be..ff653acf73 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c @@ -210,7 +210,25 @@ static flash_info_t flash_info[] = { }, }; +#define TYPE_AST2500 (1) +#define TYPE_AST2600 (2) + +static bmc_id_list_t g_bmc_id_list[] = { + { + .bmc_ids = {AST2500_A0, AST2510_A0, AST2520_A0, AST2530_A0, AST2500_A1, AST2510_A1, AST2520_A1,\ + AST2530_A1, AST2500_A2, AST2510_A2, AST2520_A2, AST2530_A2}, + .bmc_type = TYPE_AST2500, + .bmc_id_reg = AST25_SILICON_REVISION_ID_REGISTER, + }, + { + .bmc_ids = {AST2600_A0, AST2600_A1, AST2600_A2, AST2600_A3, AST2620_A1, AST2620_A2, AST2620_A3}, + .bmc_type = TYPE_AST2600, + .bmc_id_reg = AST26_SILICON_REVISION_ID_REGISTER, + } +}; + static int debug_on; +static int g_bmc_type = TYPE_AST2500; static void help(void) { @@ -496,13 +514,23 @@ static void disable_ilpc2ahb(void) /* Enable CPU */ static void enable_cpu(void) { - /* unlock SCU register */ - write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); - /* enable ARM */ - write_bmc_reg(REBOOT_CPU_REGISTER, SET_BMC_CPU_BOOT); - /* lock SCU register */ - write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); - + if (g_bmc_type == TYPE_AST2600) { + /* unlock SCU register */ + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_1, UNLOCK_SCU_KEY); + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_2, UNLOCK_SCU_KEY); + /* enable ARM */ + write_bmc_reg(AST26_HARDWARE_STRAP_REGISTER_CLEAR, 0x1); + /* lock SCU register */ + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_1, LOCK_SCU_KEY); + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_2, LOCK_SCU_KEY); + } else { + /* unlock SCU register */ + write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); + /* enable ARM */ + write_bmc_reg(AST25_REBOOT_CPU_REGISTER, SET_BMC_CPU_BOOT); + /* lock SCU register */ + write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); + } return; } @@ -511,14 +539,25 @@ static void disable_cpu(void) { uint32_t scu_hw_strap_val; - /* unlock SCU register */ - write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); - /* disable ARM */ - scu_hw_strap_val = read_bmc_reg(HARDWARE_STRAP_REGISTER); - write_bmc_reg(HARDWARE_STRAP_REGISTER, scu_hw_strap_val |0x01); - /* lock SCU register */ - write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); - + if (g_bmc_type == TYPE_AST2600) { + /* unlock SCU register */ + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_1, UNLOCK_SCU_KEY); + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_2, UNLOCK_SCU_KEY); + /* disable ARM */ + scu_hw_strap_val = read_bmc_reg(AST26_HARDWARE_STRAP_REGISTER); + write_bmc_reg(AST26_HARDWARE_STRAP_REGISTER, scu_hw_strap_val |0x01); + /* lock SCU register */ + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_1, LOCK_SCU_KEY); + write_bmc_reg(AST26_PROTECTION_KEY_REGISTER_2, LOCK_SCU_KEY); + } else { + /* unlock SCU register */ + write_bmc_reg(SCU_ADDR, UNLOCK_SCU_KEY); + /* disable ARM */ + scu_hw_strap_val = read_bmc_reg(AST25_HARDWARE_STRAP_REGISTER); + write_bmc_reg(AST25_HARDWARE_STRAP_REGISTER, scu_hw_strap_val |0x01); + /* lock SCU register */ + write_bmc_reg(SCU_ADDR, LOCK_SCU_KEY); + } return; } @@ -532,7 +571,12 @@ static void enable_upgrade(void) write_bmc_reg(CE0_CONTROL_REGISTER, 0); write_bmc_reg(CE1_CONTROL_REGISTER, 0); /* disable WDT2 */ - write_bmc_reg(WATCHDOG2_CONTROL, DISABLE_WATCHDOG); + if (g_bmc_type == TYPE_AST2500) { + write_bmc_reg(WATCHDOG2_CONTROL, DISABLE_WATCHDOG); + } else { + write_bmc_reg(FMC_WDT2_CONTROL_STATUS_REGISTER, AST26_FMC_WATCHDOG_DISABLE); + write_bmc_reg(AST26_WATCHDOG2_CONTROL, DISABLE_AST26_WATCHDOG); + } return; } @@ -540,12 +584,49 @@ static void enable_upgrade(void) static void disable_upgrade(void) { enable_cpu(); - dbg_print(debug_on, "DEBUG 0x%x\n", read_bmc_reg(HARDWARE_STRAP_REGISTER)); + if (g_bmc_type == TYPE_AST2600) { + dbg_print(debug_on, "DEBUG 0x%x\n", read_bmc_reg(AST26_HARDWARE_STRAP_REGISTER)); + } else { + dbg_print(debug_on, "DEBUG 0x%x\n", read_bmc_reg(AST25_HARDWARE_STRAP_REGISTER)); + } disable_ilpc2ahb(); return; } +static int get_bmc_type(void) +{ + int i, j, size_1, size_2, ret; + uint32_t read_val; + + ret = set_ioport_rw_access(); + if (ret < 0) { + printf("IO ERROR\n"); + return -1; + } + + enable_ilpc2ahb(); + + size_1 = sizeof(g_bmc_id_list) / sizeof((g_bmc_id_list)[0]); + for (i = 0; i < size_1 ; i++) { + read_val = read_bmc_reg(g_bmc_id_list[i].bmc_id_reg); + dbg_print(debug_on, "get_bmc_type: read reg: 0x%x\n", g_bmc_id_list[i].bmc_id_reg); + dbg_print(debug_on, "get_bmc_type: reg value 0x%x\n", read_val); + size_2 = sizeof(g_bmc_id_list[i].bmc_ids) / sizeof((g_bmc_id_list[i].bmc_ids)[0]); + for (j = 0; j < size_2; j++) { + if ((read_val != 0) && (read_val == g_bmc_id_list[i].bmc_ids[j])) { + g_bmc_type = g_bmc_id_list[i].bmc_type; + dbg_print(debug_on, "get_bmc_type: success, g_bmc_type = %d\n", g_bmc_type); + disable_ilpc2ahb(); + return 0; + } + } + } + + disable_ilpc2ahb(); + return -1; +} + static void watchdog_status_debug(void) { uint32_t watchdog_reg; @@ -739,8 +820,47 @@ static void fmc_debug(void) return; } -/* Enable WatchDog to reset BMC*/ -static void enable_watchdog(int cs) +static int get_current_bmc(void) +{ + if (g_bmc_type == TYPE_AST2600) { + return (read_bmc_reg(FMC_WDT2_CONTROL_STATUS_REGISTER) & 0x010) >> 4; + } else { + return (read_bmc_reg(WATCHDOG2_TSR) & 0x02) >> 1; + } +} + +#if 0 +/* Enable WatchDog to reset 2600 BMC*/ +static void enable_ast26_watchdog(int cs) { + + if (cs == get_current_bmc()) { + /* reset to current chip by wdt2*/ + write_bmc_reg(AST26_WATCHDOG2_CLEAR_STATUS, CLEAR_WATCHDOG_STATUS); + write_bmc_reg(AST26_WATCHDOG2_RESET_FUN_MASK_2, AST26_WATCHDOG_GATEMASK_2); + write_bmc_reg(AST26_WATCHDOG2_RELOAD_VALUE, WATCHDOG_NEW_COUNT); + write_bmc_reg(AST26_WATCHDOG2_COUNTER_RST, WATCHDOG_RELOAD_COUNTER); + write_bmc_reg(AST26_WATCHDOG2_CONTROL, AST26_ENABLE_WATCH_CMD); + } else { + /* reset to another chip by fmt_wdt*/ + write_bmc_reg(FMC_WDT2_TIMER_RELOAD_VALUE_REGISTER, AST26_FMT_WATCHDOG_NEW_COUNT); + write_bmc_reg(FMC_WDT2_CONTROL_STATUS_REGISTER, AST26_ENABLE_FMC_WATCH_CMD); + } + + return; +} +#endif + +/* Enable WatchDog to reset 2600 BMC*/ +/* 2600 BMC WDT2 full chip reset is invalid , so use this funtion to reset bmc by fmc_wdt */ +static void enable_ast26_watchdog(int cs) { + dbg_print(debug_on, "enable_ast26_watchdog cs: %d\n", cs); + write_bmc_reg(FMC_WDT2_TIMER_RELOAD_VALUE_REGISTER, AST26_FMT_WATCHDOG_NEW_COUNT); + write_bmc_reg(FMC_WDT2_CONTROL_STATUS_REGISTER, AST26_ENABLE_FMC_WATCH_CMD); + return; +} + +/* Enable WatchDog to reset 2500 BMC*/ +static void enable_ast25_watchdog(int cs) { uint32_t enable_watch_cmd; @@ -756,7 +876,11 @@ static void enable_watchdog(int cs) static void bmc_reboot(int cs) { - enable_watchdog(cs); + if (g_bmc_type == TYPE_AST2600) { + enable_ast26_watchdog(cs); + } else { + enable_ast25_watchdog(cs); + } watchdog_status_debug(); disable_upgrade(); printf("Upgrade-Complete, BMC rebooting...\n"); @@ -764,20 +888,20 @@ static void bmc_reboot(int cs) return; } -static int get_current_bmc(void) -{ - return (read_bmc_reg(WATCHDOG2_TSR) & 0x02) >> 1; -} - static void get_flash_base_and_ce_ctrl(int current_bmc, int cs, uint32_t *flash_base_addr, uint32_t *ce_ctrl_addr) { uint32_t ce0_addr_range_reg_val, ce0_decode_addr; uint32_t ce1_addr_range_reg_val, ce1_decode_addr; ce0_addr_range_reg_val = read_bmc_reg(CE0_ADDRESS_RANGE_REGISTER); - ce0_decode_addr = SEGMENT_ADDR_START(ce0_addr_range_reg_val); ce1_addr_range_reg_val = read_bmc_reg(CE1_ADDRESS_RANGE_REGISTER); - ce1_decode_addr = SEGMENT_ADDR_START(ce1_addr_range_reg_val); + if (g_bmc_type == TYPE_AST2600) { + ce0_decode_addr = AST26_SEGMENT_ADDR_START(ce0_addr_range_reg_val); + ce1_decode_addr = AST26_SEGMENT_ADDR_START(ce1_addr_range_reg_val); + } else { + ce0_decode_addr = AST25_SEGMENT_ADDR_START(ce0_addr_range_reg_val); + ce1_decode_addr = AST25_SEGMENT_ADDR_START(ce1_addr_range_reg_val); + } dbg_print(debug_on,"CE0 addr decode range reg value:0x%08x, decode addr:0x%08x.\n", ce0_addr_range_reg_val, ce0_decode_addr); dbg_print(debug_on,"CE1 addr decode range reg value:0x%08x, decode addr:0x%08x.\n", @@ -1509,7 +1633,6 @@ static int program_flash_main(int argc, char* argv[]) { int cs, erase_way, ret; char *stopstring; - char tmp[128]; if (argc != 5) { printf("Input invalid.\n"); @@ -1519,8 +1642,7 @@ static int program_flash_main(int argc, char* argv[]) cs = strtol(argv[3], &stopstring, 10); if ((strlen(stopstring) != 0) || cs < 0 || cs > 2) { - snprintf(tmp, sizeof(tmp), "%s", argv[3]); - printf("Incorrect chip select %s\n", tmp); + printf("Incorrect chip select %s\n", argv[3]); help(); return -1; } @@ -1530,12 +1652,17 @@ static int program_flash_main(int argc, char* argv[]) } else if (strcmp(argv[4], "block") == 0) { erase_way = BLOCK_ERASE; } else { - snprintf(tmp, sizeof(tmp), "%s", argv[4]); - printf("Incorrect erase type %s\n", tmp); + printf("Incorrect erase type %s\n", argv[4]); help(); return -1; } + ret = get_bmc_type(); + if (ret < 0) { + printf("get bmc type fail\n"); + return ret; + } + printf("============BMC Upgrade Tool=============\n"); ret = upgrade_bmc(argv[2], cs, erase_way); return ret; @@ -1546,7 +1673,6 @@ static int read_bmc_flash_main(int argc, char* argv[]) int cs, ret, read_size, is_print; uint32_t start_addr; char *stopstring; - char tmp[128]; if (argc != 6) { printf("Input invalid.\n"); @@ -1556,8 +1682,7 @@ static int read_bmc_flash_main(int argc, char* argv[]) cs = strtol(argv[2], &stopstring, 10); if ((strlen(stopstring) != 0) || cs < 0 || cs > 1) { - snprintf(tmp, sizeof(tmp), "%s", argv[2]); - printf("Incorrect chip select %s\n", tmp); + printf("Incorrect chip select %s\n", argv[2]); help(); return -1; } @@ -1582,6 +1707,12 @@ static int read_bmc_flash_main(int argc, char* argv[]) is_print = 0; } + ret = get_bmc_type(); + if (ret < 0) { + printf("get bmc type fail\n"); + return ret; + } + printf("============READ BMC FLASH=============\n"); ret = read_bmc_flash(cs, start_addr, read_size, is_print); return ret; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h index aa012b8ab6..7fa988104b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h @@ -41,11 +41,22 @@ #define CE1_CONTROL_REGISTER (FMC_BASE_ADDR + 0x14) #define CE0_ADDRESS_RANGE_REGISTER (FMC_BASE_ADDR + 0x30) #define CE1_ADDRESS_RANGE_REGISTER (FMC_BASE_ADDR + 0x34) +#define FMC_WDT2_CONTROL_STATUS_REGISTER (FMC_BASE_ADDR + 0x64) +#define FMC_WDT2_TIMER_RELOAD_VALUE_REGISTER (FMC_BASE_ADDR + 0x68) /* SCU REGISTER ADDR */ #define SCU_ADDR (0x1E6E2000) -#define HARDWARE_STRAP_REGISTER (SCU_ADDR + 0x70) -#define REBOOT_CPU_REGISTER (SCU_ADDR + 0x7C) +/* AST25 */ +#define AST25_HARDWARE_STRAP_REGISTER (SCU_ADDR + 0x70) +#define AST25_REBOOT_CPU_REGISTER (SCU_ADDR + 0x7C) +#define AST25_SILICON_REVISION_ID_REGISTER (SCU_ADDR + 0x7C) + +/* AST26 */ +#define AST26_PROTECTION_KEY_REGISTER_1 (SCU_ADDR + 0) +#define AST26_SILICON_REVISION_ID_REGISTER (SCU_ADDR + 0x04) +#define AST26_PROTECTION_KEY_REGISTER_2 (SCU_ADDR + 0x10) +#define AST26_HARDWARE_STRAP_REGISTER (SCU_ADDR + 0x500) +#define AST26_HARDWARE_STRAP_REGISTER_CLEAR (SCU_ADDR + 0x504) /* SCU KEY */ #define UNLOCK_SCU_KEY (0x1688A8A8) @@ -67,6 +78,17 @@ #define WATCHDOG2_CLEAR_STATUS (WATCHDOG_ADDR + 0x34) #define WATCHDOG2_RESET_FUN_MASK (WATCHDOG_ADDR + 0x3C) +#define AST26_WATCHDOG2_ADDR_BASE (0x1E785040) +#define AST26_WATCHDOG2_RELOAD_VALUE (AST26_WATCHDOG2_ADDR_BASE + 0x04) +#define AST26_WATCHDOG2_COUNTER_RST (AST26_WATCHDOG2_ADDR_BASE + 0x08) +#define AST26_WATCHDOG2_CONTROL (AST26_WATCHDOG2_ADDR_BASE + 0x0C) +#define AST26_WATCHDOG2_TSR (AST26_WATCHDOG2_ADDR_BASE + 0x10) +#define AST26_WATCHDOG2_CLEAR_STATUS (AST26_WATCHDOG2_ADDR_BASE + 0x14) +#define AST26_WATCHDOG2_RESET_FUN_MASK_1 (AST26_WATCHDOG2_ADDR_BASE + 0x1C) +#define AST26_WATCHDOG2_RESET_FUN_MASK_2 (AST26_WATCHDOG2_ADDR_BASE + 0x20) +#define AST26_FMC_WATCHDOG_DISABLE (0x0) +#define DISABLE_AST26_WATCHDOG (0x00000000) + /* User Mode Command */ #define WRITE_STATUS (0x01) #define COMMON_PAGE_PROGRAM (0x02) @@ -164,6 +186,11 @@ #define WATCHDOG_NEW_COUNT (0x00050000) #define WATCHDOG_RELOAD_COUNTER (0x4755) +#define AST26_WATCHDOG_GATEMASK_2 (0x03FFFFF3) +#define AST26_ENABLE_WATCH_CMD (0x33) +#define AST26_ENABLE_FMC_WATCH_CMD (0x1) +#define AST26_FMT_WATCHDOG_NEW_COUNT (0x3) + #define CE0_SPI_TYPE (0x00000002) #define CE1_SPI_TYPE (0x00000008) #define ERROR_COMMAND (0x00000400) @@ -190,7 +217,9 @@ #define REGISTER_HEAD (0x1e000000) #define DEFAULT_WIDTH (16) #define MAX_FILENAME_LENGTH (64) -#define SEGMENT_ADDR_START(_r) ((((_r) >> 16) & 0xFF) << 23) +#define AST26_AHB_BASE_PHY_ADDR (0x20000000) +#define AST25_SEGMENT_ADDR_START(_r) ((((_r) >> 16) & 0xFF) << 23) +#define AST26_SEGMENT_ADDR_START(_r) ((((_r) & 0xFFFF) << 16) | AST26_AHB_BASE_PHY_ADDR) typedef struct flash_info { uint32_t flash_size; @@ -247,4 +276,39 @@ typedef enum flash_size { M128 = 0x08000000, /* 128M */ } flash_size_t; +typedef enum ast25_bmc_id_list { + AST2500_A0 = 0x04000303, + AST2510_A0 = 0x04000103, + AST2520_A0 = 0x04000203, + AST2530_A0 = 0x04000403, + + AST2500_A1 = 0x04010303, + AST2510_A1 = 0x04010103, + AST2520_A1 = 0x04010203, + AST2530_A1 = 0x04010403, + + AST2500_A2 = 0x04030303, + AST2510_A2 = 0x04030103, + AST2520_A2 = 0x04030203, + AST2530_A2 = 0x04030403, + + AST2600_A0 = 0x05000303, + AST2600_A1 = 0x05010303, + AST2600_A2 = 0x05010303, + AST2600_A3 = 0x05030303, + + AST2620_A1 = 0x05010203, + AST2620_A2 = 0x05010203, + AST2620_A3 = 0x05030203, +} ast25_bmc_id_list_t; + + +typedef struct bmc_id_list_s { + uint32_t bmc_ids[64]; + int bmc_type; + uint32_t bmc_id_reg; +} bmc_id_list_t; + + + #endif /*_FW_UPGRADE_H_*/ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/Makefile new file mode 100644 index 0000000000..3c9049c2db --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/Makefile @@ -0,0 +1,15 @@ +pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST)) +pes_parent_dir:=$(shell dirname $(pes_parent_dir)) + +SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}') +INC = -I./inc + +all : CHECK $(SUBDIRS) +CHECK : + @echo $(pes_parent_dir) + +$(SUBDIRS):ECHO + make -C $@ + +ECHO: + @echo $(SUBDIRS) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/Makefile new file mode 100644 index 0000000000..13c99a2951 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/Makefile @@ -0,0 +1,31 @@ +top_srcdir:=$(shell pwd) +#include $(top_srcdir)/Rules.mk +DIR=$(shell pwd) +BUILD_OUTPUT=$(DIR)/tmp +SRCS=$(wildcard *.c) +OBJS=$(patsubst %.c, $(BUILD_OUTPUT)/%.o, $(SRCS)) +DEPS=$(patsubst %.o, %.d, $(OBJS)) +CFLAGS+=-Wall -W -g -I$(DIR)/include +LDFLAGS= +PROGRAM=hw_test.bin + +.PHONY: all + +all:$(OBJS) + $(CC) $(OBJS) $(LDFLAGS) -o $(BUILD_OUTPUT)/$(PROGRAM) + @if [ ! -d ${common_out_put_dir} ]; then mkdir -p ${common_out_put_dir} ;fi + cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + +$(OBJS):$(SRCS) + @if [ ! -d ${BUILD_OUTPUT} ]; then mkdir -p ${BUILD_OUTPUT} ;fi + $(CC) -c $(CFLAGS) $(INCLUDE) $(*F).c -o $@ + +.PHONY: install +install: + @mkdir -p $(install_sbin_dir) + cp -p $(BUILD_OUTPUT)/$(PROGRAM) $(common_out_put_dir) + + +rebuild: clean all +clean: + @rm -rf $(BUILD_OUTPUT)/* \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/ft_ddr_test.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/ft_ddr_test.c new file mode 100644 index 0000000000..3f9f80c3de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/ft_ddr_test.c @@ -0,0 +1,2074 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef USE_DMA /* Disable DMA */ +typedef unsigned int uint32; +#define MEMORY_SIZE_1G (1024 * 1024 * 1024ul) + +volatile uint32 *pp = 0; +uint32 p1 = 0, p2 = 0, p0 = 0; +int fail = 0; +int segs = 0; +struct vars variables = { }; +struct vars *v = &variables; +//dma_tx_data_t g_dma_tx_data[MAX_DMA_CHAN][NUM_LINK_DESC]; +static unsigned int SEED_X = 521288629; +static unsigned int SEED_Y = 362436069; + +/* Memory block size at dma transfer time */ +int blk_size_array[BLK_SIZE_NUM_MAX] = { + 0x2000000, /* 32MB */ + 0x1800000, /* 24MB */ + 0x1000000, /* 16MB */ + 0xA00000, /* 10MB */ + 0x800000, /* 8MB */ + 0x600000, /* 6MB */ + 0x500000, /* 5MB */ + 0x300000, /* 3MB */ + 0x200000, /* 2MB */ +}; + +#if 0 +extern int dma_mov_addr(int engine, int from_addr, int to_addr, int size); +#endif +static int ddr_half_mov_inv_random_pat(char *desc); +static int ddr_mov_inv_random_pat(char *desc); +static int ddr_mov_inv_0_1(char *desc); +static int ddr_mov_inv_8_pat(char *desc); +static int ddr_mov_inv_32_pat(char *desc); +static int ddr_mod20_random_pat(char *desc); +static int ddr_mod20_0_1_pat(char *desc); +static int ddr_mod20_8_pat(char *desc); +static int ddr_addr_walking(char *desc); +static int ddr_march_c(char *desc); +static int ddr_march_g(char *desc); +static int ddr_galloping(char *desc); +static int ddr_column_operate(char *desc); +static int ddr_swap_blocks(char *desc); + +ft_ddr_test_interface_t ft_ddr_test_fun[TETS_TOTAL_NUMBER] = { + {0, ddr_half_mov_inv_random_pat, "Half move inversion - random number test"}, /* Half move inversion - random number test, no copying */ + {1, ddr_mov_inv_random_pat, "Move inversion - random number test"}, /* Move inversion - random number test */ + {0, ddr_mov_inv_0_1, "Move inversion -0&1 test"}, /* Move inversion -0&1 test, no copying */ + {1, ddr_mov_inv_8_pat, "Move inversion -8bit test"}, /* Move inversion -8bit test */ + {0, ddr_mov_inv_32_pat, "Move inversion -32bit test"}, /* Move inversion -32bit test, no copying */ + {0, ddr_mod20_random_pat, "Mode 20- Random number test"}, /* Mode 20- Random number test, no copying */ + {1, ddr_mod20_0_1_pat, "Mode 20-0&1 test"}, /* Mode 20-0&1 test*/ + {1, ddr_mod20_8_pat, "Mode 20-8bit test"}, /* Mode 20-8bit test */ + {1, ddr_addr_walking, "Go 1 address test"}, /* Go 1 address test*/ + {0, ddr_march_c, "March C test"}, /* March Ctest, no copying */ + {1, ddr_march_g, "March G test"}, /* March G test */ + {1, ddr_galloping, "Galloping test "}, /* Galloping test */ + {1, ddr_column_operate, "Column operate test"}, /* Column operate test */ + {0, ddr_swap_blocks, " block move test"}, /* block move test, no copying */ +}; + +static inline ulong roundup(ulong value, ulong mask) +{ + return (value + mask) & ~mask; +} + +#if 0 +static inline void set_vars(ulong start, ulong end) +{ + int i = 0; + + for (i = 0; i < v->msegs; i++) { + v->pmap[i].start = (uint)start; + v->pmap[i].end = (uint)end; + v->map[i].start = (ulong *)start; + v->map[i].end = (ulong *)end; + } +} +#endif + +#if 1 +void rand_seed(unsigned int seed1, unsigned int seed2) +{ + if (seed1) + SEED_X = seed1; /* use default seeds if parameter is 0 */ + if (seed2) + SEED_Y = seed2; +} + +static inline unsigned int ft_rand() +{ + static unsigned int a = 18000, b = 30903; + + SEED_X = a * (SEED_X & 65535) + (SEED_X >> 16); + SEED_Y = b * (SEED_Y & 65535) + (SEED_Y >> 16); + + return ((SEED_X << 16) + (SEED_Y & 65535)); +} +#else +static inline unsigned long ft_rand() +{ + if (sizeof(ulong) == 8) { + return ((ulong)rand() << 32) | rand(); + } + + return rand(); +} + +#endif +/** + * addrress_walking + * + * Use the "address test" algorithm + * The address translation rules for writing data are as follows: + * address = initial address | (mask << 1) + * + * No return value + */ +static int addrress_walking(char *desc) +{ + int i, j, k; + uint32 *pt, *end, mask, bank; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + /* Test the global address bits */ + for (p1 = 0, j = 0; j < 2; j++) { + /* Set the initial address 0x20000 to align */ + pp = (uint32 *)roundup((ulong)v->map[0].start, 0x1ffff); + *pp = p1; + + /* Now write pattern compliment */ + p1 = ~p1; + end = v->map[segs - 1].end; + for (i = 0; i < 1000; i++) { + mask = 4; + do { + pt = (uint32 *) ((ulong) pp | mask); + if (pt == pp) { + mask = mask << 1; + continue; + } + if (pt >= end) { + break; + } + *pt = p1; + if (*pp != ~p1) { + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, ~p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + mask = mask << 1; + } while (mask); + } + FT_DDR_SHOW(); + } + + /* Now check the address bits in each bank + * If we have more than 8mb of memory then the bank size must be + * bigger than 256k. If so use 1mb for the bank size. + */ + if (v->pmap[v->msegs - 1].end > (0x800000 >> 12)) { + bank = 0x100000; + } else { + bank = 0x40000; + } + + for (p1 = 0, k = 0; k < 2; k++) { + for (j = 0; j < segs; j++) { + pp = v->map[j].start; + /* Set the initial address to 256k alignment */ + pp = (uint32 *) roundup((ulong) pp, bank - 1); + end = v->map[j].end; + while (pp < end) { + *pp = p1; + p1 = ~p1; + for (i = 0; i < 200; i++) { + mask = 4; + do { + pt = (uint32 *)((ulong) pp | mask); + if (pt == pp) { + mask = mask << 1; + continue; + } + if (pt >= end) { + break; + } + *pt = p1; + if (*pp != ~p1) { + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, ~p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + mask = mask << 1; + } while (mask); + } + if (pp + bank > pp) { + pp += bank; + } else { + pp = end; + } + p1 = ~p1; + } + } + p1 = ~p1; + FT_DDR_SHOW(); + } + + return FT_DDR_SUCCESS; +} + +/** + * moving_inversions + * @iter: number of repetitions + * @p1: The data is written for pattern1 + * @p2: The data is written for pattern2 + * + * Use the "move inversion" algorithm to write memory addresses from low to high and from high to address; + * First write p1 data format to the test memory area, and verify that the written data is correct; + * Write ~p1 data format to the test memory area, and verify that the written data is correct; + * + * Returns 0 on success; Return 1 on failure + */ +static int moving_inversions(char * desc, int iter, uint32 p1, uint32 p2) +{ + int i, j, done; + uint32 *pe; + uint32 *start, *end; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "Iter:%d P1:0x%x P2:0x%x.\n", iter, p1, p2); + /* From the low address to the high address, write p1 values to the test memory area */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + for (; pp < pe; pp++) { + *pp = p1; + } + } while (!done); + FT_DDR_SHOW(); + } + + for (i = 0; i < iter; i++) { + /* Validate write data, from low to high address, write p2 value to test memory area */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + for (; pp < pe; pp++) { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p2; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* Verify the write data, from the high address to the low address, write p1 value to the test memory area */ + for (j = segs - 1; j >= 0; j--) { + start = v->map[j].start; + end = v->map[j].end; + pe = end - 1; + pp = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (*pp != p2) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p1; + } while (pp-- > pe); + } while (!done); + FT_DDR_SHOW(); + } + } + + return FT_DDR_SUCCESS; +} + +/** + * moving_inversions32 + * @iter: number of repetitions + * @p1: indicates the pattern of data written to memory for the first time + * @low_pattern: indicates the initial data pattern for writing data from low addresses to high addresses + * @high_pattern: indicates the initial data pattern for writing data from high addresses to low addresses + * @sval: The value required or on the data pattern for each modification + * @offset: indicates the bit offset when the memory is written for the first time. low_pattern = p1 >> offset + * + * Use the "move inverse-32bit" algorithm, which takes 32 write operations as a cycle, each write operation + * After doing, for low address to high address write memory, write data pattern needs to move 1 bit left; + * For high address to low address write memory, write data pattern needs to be shifted 1 bit to the right. + * + * Returns 0 on success; Return 1 on failure + */ +static int moving_inversions32(char *desc, int iter, uint32 p1, uint32 low_pattern, uint32 high_pattern, int sval, int offset) +{ + int i, j, k = 0, done; + uint32 *pe; + uint32 *start, *end; + uint32 pattern = 0; + uint32 p3 = sval << 31; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "Iter:%d P1:0x%x low_pattern:0x%x high_pattern:0x%x sval:%d offset:%d.\n", + iter, p1, low_pattern, high_pattern, sval, offset); + /* Writes pattern values to the test memory area from low to high addresses */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + k = offset; + pattern = p1; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + while (pp < pe) { + *pp = pattern; + if (++k >= 32) { + pattern = low_pattern; + k = 0; + } else { + pattern = pattern << 1; + pattern |= sval; + } + pp++; + } + } while (!done); + FT_DDR_SHOW(); + } + + for (i = 0; i < iter; i++) { + /* Validate write data, from low address to high address, write pattern value to test memory area */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + k = offset; + pattern = p1; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + while (pp < pe) { + if (*pp != pattern) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, pattern, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, pattern, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = ~pattern; + if (++k >= 32) { + pattern = low_pattern; + k = 0; + } else { + pattern = pattern << 1; + pattern |= sval; + } + pp++; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* Validate write data, from high address to low address, write pattern value to test memory area */ + pattern = low_pattern; + if (0 != (k = (k - 1) & 31)) { + pattern = (pattern << k); + if (sval) + pattern |= ((sval << k) - 1); + } + k++; + for (j = segs - 1; j >= 0; j--) { + start = v->map[j].start; + end = v->map[j].end; + pp = end - 1; + pe = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (*pp != ~pattern) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, ~pattern, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, ~pattern, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = pattern; + if (--k <= 0) { + pattern = high_pattern; + k = 32; + } else { + pattern = pattern >> 1; + pattern |= p3; + } + } while (pp-- > pe); + } while (!done); + FT_DDR_SHOW(); + } + } + + return FT_DDR_SUCCESS; +} + +/** + * modtst + * @offset: indicates the offset address of the P1 value + * @iter: number of times to write P2 + * @p1: indicates written data 1 + * @p2: indicates written data 2 + * + * Write p1 data to the offset address of 20 * n + offset in the test memory area; To other + * Offset address write p2 data, repeat iter times; Verify the offset address of 20 * n + offset + * Whether the data written is correct. + * + * Returns 0 on success; Return 1 on failure + */ +static int modtst(char *desc, int offset, int iter, uint32 p1, uint32 p2) +{ + int j, k, l, done; + uint32 *pe; + uint32 *start, *end; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "offset:%d Iter:%d P1:0x%x p2:0x%x.\n", offset, iter, p1, p2); + /* Write p1 data to the offset address of 20 * n + offset in the test memory area*/ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = (uint32 *) start; + pp = start + offset; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + for (; pp < pe; pp += MOD_SZ) { + *pp = p1; + } + + } while (!done); + FT_DDR_SHOW(); + } + + /* Write p2 data to other offset addresses, repeat iter times */ + for (l = 0; l < iter; l++) { + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = (uint32 *) start; + pp = start; + done = 0; + k = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + for (; pp < pe; pp++) { + if (k != offset) { + *pp = p2; + } + if (++k > MOD_SZ - 1) { + k = 0; + } + } + + } while (!done); + FT_DDR_SHOW(); + } + } + + /* Now check every nth location */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = (uint32 *) start; + pp = start + offset; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + for (; pp < pe; pp += MOD_SZ) { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + } + + } while (!done); + FT_DDR_SHOW(); + } + + return FT_DDR_SUCCESS; +} + +/** + * march_c + * @iter: number of repetitions + * @p1: The data is written for pattern1 + * @p2: The data is written for pattern2 + * + * Low address to high address, read p1, write p2, read p2, write p1 + * High address to low address, read p1, write p2, read p2, write p1 + * + * No return value + */ +static int march_c(char *desc, int iter, uint32 p1, uint32 p2) +{ + int i, j, done; + uint32 *pe; + uint32 *start, *end; + uint32 p_temp; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "Iter:%d P1:0x%x p2:0x%x.\n", iter, p1, p2); + /* From low address to high address, write p1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + *pp = p1; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* From low address to high address, read p1, write p2, read p2 again, write p1 */ + for (i = 0; i < 2; i++) { + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p2; + } + + } while (!done); + FT_DDR_SHOW(); + } + /* p1 and p2 values are exchanged */ + p_temp = p1; + p1 = p2; + p2 = p_temp; + } + + /* High address to low address, read p1, write p2, read p2, write p1 */ + for (i = 0; i < 2; i++) { + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = end - 1; + pp = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p2; + } while (pp-- > pe); + + } while (!done); + FT_DDR_SHOW(); + } + + /* p1 and p2 values are exchanged */ + p_temp = p1; + p1 = p2; + p2 = p_temp; + } + + /* Verify the last p1 value written */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + } + + } while (!done); + FT_DDR_SHOW(); + } + + return FT_DDR_SUCCESS; +} + +/** + * march_g + * @iter: number of repetitions + * @p1: The data is written for pattern1 + * @p2: The data is written for pattern2 + * + * From low address to high address, for the same address: read p1, write p2, read p2, write p1 + * From low address to high address, for the same address: read p2, write p1 and then p2 + * High address to low address, for the same address: read p2, write p1 first, write p2, then write p1 + * High address to low address, for the same address: read p1, first write p2, then write p1 + * + * No return value + */ +static int march_g(char *desc, int iter, uint32 p1, uint32 p2) +{ + int j, done; + uint32 *pe; + uint32 *start, *end; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "Iter:%d P1:0x%x p2:0x%x.\n", iter, p1, p2); + /* From low address to high address, write p1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + *pp = p1; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* From low address to high address, read p1, write p2, read p2, and write p1 to the same address */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p2; + if (*pp != p2) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p1; + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p2; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* From low address to high address, read p2, write p1 and then p2 to the same address */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (*pp != p2) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p1; + *pp = p2; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* From high address to low address, for the same address: read p2, write p1 first, write p2, and then write p1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = end - 1; + pp = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (*pp != p2) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p1; + *pp = p2; + *pp = p1; + } while (pp-- > pe); + + } while (!done); + FT_DDR_SHOW(); + } + + /* From high address to low address, for the same address: read p1, write p2, and then write p1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = end - 1; + pp = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = p2; + *pp = p1; + } while (pp-- > pe); + + } while (!done); + FT_DDR_SHOW(); + } + + /* From high address to low address, read p1 for the same address */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + } + + } while (!done); + FT_DDR_SHOW(); + } + + return FT_DDR_SUCCESS; +} + +/** + * column_operate + * @iter: number of repetitions + * @p1: The data is written for pattern1 + * @col_num: indicates the column address offset + * + * Adopts the "column operation" algorithm + * From the low address to the high address, write p1 to the (n * step + col_addr) address + * + * No return value + */ +static int column_operate(char *desc, int iter, uint32 p1, uint32 col_num) +{ + int j, k, done; + uint32 *pe; + uint32 *start, *end; + ulong n; + ulong step = 0x2000; + ulong addr; + ulong col_addr; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + /* From the low address to the high address, write p1 to the (n * step + col_addr) address */ + for (k = 0; k < iter; k++) { + + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + + if (((ulong) start % step) <= (col_num & 0x3FF) << 3) { + n = (ulong) start / step; + } else { + n = (ulong) start / step + 1; + } + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp >= pe) { + break; + } + do { + col_addr = (col_num & 0x3FF) << 3; + addr = n * step + col_addr; + pp = (uint32 *) addr; + if (pp >= end) + break; + *pp = p1; + n++; + } while (pp < pe); + } while (!done); + } + //FT_DDR_SHOW(); + + /* From low address to high address, verify the (n * step + col_addr) address value */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + if (((ulong) start % step) < (col_num & 0x3FF) << 3) { + n = (ulong) start / step; + } else { + n = (ulong) start / step + 1; + } + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp >= pe) { + break; + } + do { + col_addr = (col_num & 0x3FF) << 3; + addr = n * step + col_addr; + pp = (uint32 *) addr; + if (pp >= end) + break; + if (*pp != p1) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p1, *pp); + fail = 1; + return FT_DDR_ERR; + } + n++; + } while (pp < pe); + } while (!done); + } + //FT_DDR_SHOW(); + } + + return FT_DDR_SUCCESS; +} + +/** + * galloping + * @p1: The data is written for pattern1 + * @p2: The data is written for pattern2 + * + * From low address to high address, write p2 to addr, read addr+1, and p1 to addr+1 + * From high address to low address, write p2 to addr, read ADDR-1, read addr, and write p1 to ADDR-1 + * + * No return value + */ +static int galloping(char *desc, uint32 p1, uint32 p2) +{ + int j, done; + uint32 *pe; + uint32 *start, *end; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + /* From low address to high address, write p1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + *pp = p1; + } + } while (!done); + FT_DDR_SHOW(); + } + + /* From low address to high address, write p2 to addr, read addr+1, read addr, and write p1 to addr+1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (pp + 1 >= pe) + break; + *pp = p2; + *(pp + 1) = p1; + } + *pp = p2; + + } while (!done); + FT_DDR_SHOW(); + } + + /* From low address to high address, read p2 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + if (*pp != p2) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + fail = 1; + return FT_DDR_ERR; + } + } + } while (!done); + FT_DDR_SHOW(); + } + + /* From high address to low address, write p2 to addr, read ADDR-1, read addr, and write p1 to ADDR-1 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = end - 1; + pp = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (pp - 1 <= pe) + break; + *pp = p2; + *(pp - 1) = p1; + } while (pp-- > pe); + *pp = p2; + } while (!done); + FT_DDR_SHOW(); + } + + /* From high address to low address, read p2 */ + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = end - 1; + pp = end - 1; + done = 0; + do { + /* Check for underflow */ + if (pe - SPINSZ < pe) { + pe -= SPINSZ; + } else { + pe = start; + } + if (pe <= start) { + pe = start; + done++; + } + if (pp == pe) { + break; + } + + do { + if (*pp != p2) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, p2, *pp); + fail = 1; + return FT_DDR_ERR; + } + } while (pp-- > pe); + + } while (!done); + FT_DDR_SHOW(); + } + + return FT_DDR_SUCCESS; +} + +#if 0 +void dma_mov_addr(int chan_id, int from_addr, int to_addr, int size) +{ + dma_tx_data_init(); + get_dma_chan_cb(chan_id); + g_dma_tx_data[chan_id][0].src_addr = from_addr; + g_dma_tx_data[chan_id][0].dest_addr = to_addr; + g_dma_tx_data[chan_id][0].size = size; + dma_move(chan_id, 1); +} +#endif + +static void block_move_use_long_type(ulong *s, ulong *d, int blk_size) +{ + uint32 k; + + for (k = 0; k < blk_size / sizeof(ulong); k++) { + *(d++) = *(s++); + } +} + +/** + * swap_blocks + * @iter: Number of repetitions + * @swap_times: indicates the number of block exchange repetitions + * @blk_size: indicates the size of each memory block + * + * The memory area to be tested is divided into n+1 blocks, with the n+1 block as a temporary swap block + * From block 1 to block n, exchange the data of two adjacent blocks + * From block n to block 1, exchange the data of two adjacent blocks + * + * No return value + */ +static int swap_blocks(char *desc, int iter, int swap_times, ulong blk_size) +{ + int i, j, done; + uint32 *pe; + uint32 *start, *end; + uint32 *ptemp; + uint32 *pprev; + uint32 *pnext; + ulong n; + int t; + int seed1, seed2; + int times; + uint32 num; + uint32 *pend; + ulong test_size; + + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + + iter = 1; + for (times = 0; times < iter; times++) { + start = v->map[0].start; + end = v->map[0].end; + pe = start; + pp = start; + done = 0; + seed1 = 521288629; + seed2 = 362436069; + + rand_seed(seed1, seed2); + + /* From low address to high address, write rand() */ + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + *pp = ft_rand(); + } + } while (!done); + FT_DDR_SHOW(); + + start = v->map[0].start; + end = v->map[0].end; + pe = start; + pp = start; + done = 0; + + for (t = 0; t < swap_times; t++) { + test_size = (ulong)end - (ulong)start; + n = test_size / blk_size; + FAC_LOG_DBG(GRTD_LOG_DEBUG,"start = %p, end = %p, test_size:0x%lx n = %lu\r\n", start, end, test_size, n); + + /* The last full block serves as the swap block */ + while (1) { + ptemp = (uint32 *)((ulong)start + (n + 1) * blk_size); + pend = (uint32 *)((ulong)ptemp + blk_size); + if (pend >= end) { + n--; + } else { + break; + } + } + FT_DDR_SHOW(); + FAC_LOG_DBG(GRTD_LOG_DEBUG,"n = %lu\r\n", n); + + FAC_LOG_DBG(GRTD_LOG_DEBUG,"Test form 1 to %lu.\r\n", n); + /* From the first block to the n block, the data of the two adjacent blocks is exchanged */ + for (i = 0; (ulong)i < n; i++) { + pprev = (uint32 *) ((ulong) start + i * blk_size); + for (j = i + 1; (ulong)j <= n; j++) { + /* All data of the current block i is written to the swap block */ + pprev = (uint32 *) ((ulong) start + i * blk_size); + ptemp = (uint32 *) ((ulong) start + (n + 1) * blk_size); + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"pprev:%p ptemp:%p.\r\n", pprev, ptemp); +#ifndef USE_DMA + block_move_use_long_type((ulong *)pprev, (ulong *)ptemp, blk_size); +#else + ret = dma_mov_addr(0, (ulong)pprev, (ulong)ptemp, blk_size); + if (ret) { + fail = 1; + return FT_DDR_ERR; + } + //return; +#endif + + /* All the data of the current i+1 block is written to the current i block */ + pprev = (uint32 *)((ulong) start + i * blk_size); + pnext = (uint32 *)((ulong) start + j * blk_size); + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"pprev:%p pnext:%p.\r\n", pprev, pnext); +#ifndef USE_DMA + block_move_use_long_type((ulong *)pnext, (ulong *)pprev, blk_size); +#else + ret = dma_mov_addr(0, (ulong) pnext, (ulong) pprev, blk_size); + if (ret) { + fail = 1; + return FT_DDR_ERR; + } + +#endif + /* All the data of the current switch block is written to the current i+1 block */ + pnext = (uint32 *) ((ulong) start + j * blk_size); + ptemp = (uint32 *) ((ulong) start + (n + 1) * blk_size); + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"pnext:%p ptemp:%p.\r\n", pnext, ptemp); +#ifndef USE_DMA + block_move_use_long_type((ulong *)ptemp, (ulong *)pnext, blk_size); +#else + ret = dma_mov_addr(0, (ulong) ptemp, (ulong) pnext, blk_size); + if (ret) { + fail = 1; + return FT_DDR_ERR; + } + +#endif + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"test time %d-%d\r\n", i, j); + } + FT_DDR_SHOW(); + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG,"Test form %lu to 1.\r\n", n); + ptemp = (uint32 *) ((ulong) start + (n + 1) * blk_size); + /* From block n to block 1, the data of the two adjacent blocks is exchanged */ + for (i = n; i > 0; i--) { + pprev = (uint32 *) ((ulong) start + i * blk_size); + for (j = i - 1; j >= 0; j--) { + /* All data of the current block i is written to the swap block */ + pprev = (uint32 *) ((ulong) start + i * blk_size); + ptemp = (uint32 *) ((ulong) start + (n + 1) * blk_size); + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"pprev:%p ptemp:%p.\r\n", pprev, ptemp); +#ifndef USE_DMA + block_move_use_long_type((ulong *)pprev, (ulong *)ptemp, blk_size); +#else + ret = dma_mov_addr(0, (ulong) pprev, (ulong) ptemp, blk_size); + if (ret) { + fail = 1; + return FT_DDR_ERR; + } + +#endif + /* All the data of the current block I-1 is written to the current block i */ + pnext = (uint32 *) ((ulong) start + j * blk_size); + pprev = (uint32 *) ((ulong) start + i * blk_size); + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"pnext:%p pprev:%p.\r\n", pnext, pprev); +#ifndef USE_DMA + block_move_use_long_type((ulong *)pnext, (ulong *)pprev, blk_size); +#else + ret = dma_mov_addr(0, (ulong) pnext, (ulong) pprev, blk_size); + if (ret) { + fail = 1; + return FT_DDR_ERR; + } + +#endif + /* All the data of the current switch block is written to the current block i-1 */ + pnext = (uint32 *) ((ulong) start + j * blk_size); + ptemp = (uint32 *) ((ulong) start + (n + 1) * blk_size); + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"pnext:%p ptemp:%p.\r\n", pnext, ptemp); +#ifndef USE_DMA + block_move_use_long_type((ulong *)ptemp, (ulong *)pnext, blk_size); +#else + ret = dma_mov_addr(0, (ulong) ptemp, (ulong) pnext, blk_size); + if (ret) { + fail = 1; + return FT_DDR_ERR; + } + +#endif + //FAC_LOG_DBG(GRTD_LOG_DEBUG,"test time %d-%d\r\n", i, j); + } + FT_DDR_SHOW(); + } + + /* Low address to high address, read rand() */ + pe = start; + pp = start; + done = 0; + end = (uint32 *) ((ulong)pend - blk_size); + rand_seed(seed1, seed2); + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + num = ft_rand(); + if (*pp != num) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, num, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, num, *pp); + fail = 1; + return FT_DDR_ERR; + } + } + } while (!done); + FT_DDR_SHOW(); + } + } + + return FT_DDR_SUCCESS; +} + +/** + * ft_ddr_test_init + * + * Initializes the area of memory to be tested, defaulting to all ranges allowed by the factory test + * + * No return valu + */ +void ft_ddr_test_init(void *start, size_t size) +{ + int i; + + v->rdtsc = 1; + v->msegs = 1; /* The number of memory areas currently set for testing is 1 */ + fail = 0; + segs = 1; + + FAC_LOG_DBG(GRTD_LOG_ERR, "star:%p size:0x%lx(%lu MB).\n", start, size, size / 1024 / 1024); + for (i = 0; i < v->msegs; i++) { + v->pmap[i].start = (ulong)start; + v->pmap[i].end = ((ulong)start + size); + v->map[i].start = (uint32 *)start; + v->map[i].end = (uint32 *)((ulong)start + size); + } +} + +/** + * ddr_half_mov_inv_random_pat + * + * Use "half-move inversion" algorithm to write memory address from low address to high address; + * First write p1 data format to the test memory area, and verify that the written data is correct; + * Write ~p1 data format to the test memory area, and verify that the written data is correct; + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_half_mov_inv_random_pat(char *desc) +{ + int i, j, done, seed1, seed2; + uint32 *pe; + uint32 *start, *end; + uint32 num; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_half_mov_inv_random_pat test.\n"); + if (fail) { + sprintf(desc, "No test."); + return FT_DDR_ERR; + } + /* Initialize memory with initial sequence of random numbers. */ + seed1 = 521288629 + v->pass; + seed2 = 362436069 - v->pass; + rand_seed(seed1, seed2); + + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + for (; pp < pe; pp++) { + *pp = ft_rand(); + } + } while (!done); + printf("."); + } + + /* Do moving inversions test. Check for initial pattern and then + * write the complement for each memory location. Test from bottom + * up and then from the top down. + */ + for (i = 0; i < 2; i++) { + rand_seed(seed1, seed2); + for (j = 0; j < segs; j++) { + start = v->map[j].start; + end = v->map[j].end; + pe = start; + pp = start; + done = 0; + do { + /* Check for overflow */ + if (pe + SPINSZ > pe) { + pe += SPINSZ; + } else { + pe = end; + } + if (pe >= end) { + pe = end; + done++; + } + if (pp == pe) { + break; + } + + for (; pp < pe; pp++) { + num = ft_rand(); + if (i) { + num = ~num; + } + if (*pp != num) { + FAC_LOG_DBG(GRTD_LOG_ERR, "[%p] should be 0x%x,but is 0x%x.\n", pp, num, *pp); + sprintf(desc, "[%p] should be 0x%x,but is 0x%x.\n", pp, num, *pp); + fail = 1; + return FT_DDR_ERR; + } + *pp = ~num; + } + } while (!done); + } + } + + return FT_DDR_SUCCESS; +} + +/** + * ddr_mov_inv_random_pat + * + * Use the "move inversion" algorithm to write memory addresses from low to high and from high to address; + * First write p1 data format to the test memory area, and verify that the written data is correct; + * Write ~p1 data format to the test memory area, and verify that the written data is correct; + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mov_inv_random_pat(char *desc) +{ + /* Random Data */ + p1 = ft_rand(); + p2 = ~p1; + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mov_inv_random_pat test.\n"); + return moving_inversions(desc, 2, p1, p2); +} + +/** + * ddr_mov_inv_0_1 + * @show: indicates the information output control parameter + * + * Use the "move reversal" algorithm + * Data format :p1 = 0; p2 = ~0; Or p1 = ~0; p2 = 0; + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mov_inv_0_1(char *desc) +{ + static unsigned int test_times = 0; + + test_times++; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mov_inv_0_1 test.\n"); + /* Moving inversions, all ones and zeros */ + if (test_times % 2 == 1) { + p1 = 0; + p2 = ~p1; + } else { + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + } + + return moving_inversions(desc, 3, p1, p2); +} + +/** + * ddr_mov_inv_8_pat + * @show: indicates the information output control parameter + * + * Use the "move reversal" algorithm + * Data format: + * After each call to this function, p0 moves 1 bit to the left + * p1 = p0; p2 = ~p0; Or p1 = ~p0; p2 = p0; + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mov_inv_8_pat(char *desc) +{ + static int times = 0; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mov_inv_8_pat test.\n"); + /* Moving inversions, 8 bit wide walking ones and zeros. */ + if (times == 0) { + p0 = 0x80; + } else { + p0 = p0 >> 1; + } + p1 = p0 | (p0 << 8) | (p0 << 16) | (p0 << 24); + + if (times % 2 == 0) { + p2 = ~p1; + } else { + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + } + times++; + + if (times >= 8) { + times = 0; + } + + return moving_inversions(desc, 3, p1, p2); +} + +/** + * ddr_mov_inv_32_pat + * @show: indicates the information output control parameter + * + * Use the "Move inversion 32" algorithm + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mov_inv_32_pat(char *desc) +{ + static int times = 0; + static unsigned int test_times = 0; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mov_inv_32_pat test.\n"); + test_times++; + if (times == 0) { + p1 = 1; + } else { + p1 = p1 << 1; + times ++; + if (times >= 32) + times = 0; + } + + if (moving_inversions32(desc, 2, p1, 1, 0x80000000, 0, times) || + moving_inversions32(desc, 2, ~p1, 0xfffffffe, 0x7fffffff, 1, times)) { + return FT_DDR_ERR; + } + + return FT_DDR_SUCCESS; +} + +/** + * ddr_mod20_random_pat + * @show: indicates the information output control parameter + * + * Adopts the "module 20" algorithm + * Data format: + * p1 = ft_rand(); p2 = ~ft_rand(); Or p1 = ~ft_rand(); p2 = ft_rand(); + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mod20_random_pat(char *desc) +{ + static int mod20_rand_times = 0; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mod20_random_pat test.\n"); + /* Modulo 20 check, Random pattern */ + if (mod20_rand_times % 40 == 0) { + p1 = ft_rand(); + mod20_rand_times = 0; + } else { + mod20_rand_times++; + } + + if (mod20_rand_times % 2 == 0) { + p2 = ~p1; + } else { + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + } + + return modtst(desc, mod20_rand_times, 3, p1, p2); +} + +/** + * ddr_mod20_0_1_pat + * @show: indicates the information output control parameter + * + * Adopts the "module 20" algorithm + * Data format :p1 = 0; p2 = ~0; Or p1 = ~0; p2 = 0; + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mod20_0_1_pat(char *desc) +{ + static int ddr_mod20_0_1_times = 0; + int times; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mod20_0_1_pat test.\n"); + /* Modulo 20 check, all ones and zeros */ + p1 = 0; + times = ddr_mod20_0_1_times % MOD_SZ; + ddr_mod20_0_1_times++; + + if (times % 2 == 0) { + p2 = ~p1; + /* modtst(times, 3, p1, p2); */ + } else { + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + /* modtst(times, 3, p1, p2); */ + } + + return modtst(desc, times, 3, p1, p2); +} + +/** + * ddr_mod20_8_pat + * @show: indicates the information output control parameter + * + * Adopts the "module 20" algorithm + * Data format: + * After each call to this function, p0 moves 1 bit to the left + * p1 = p0; p2 = ~p0; Or p1 = ~p0; p2 = p0; + * + * Returns 0 on success; Return 1 on failure + */ +static int ddr_mod20_8_pat(char *desc) +{ + static int pass = 0; + static int ddr_mod20_8_pat_times = 0; + int times; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_mod20_8_pat test.\n"); + /* Modulo 20 check, 8 bit pattern */ + pass = ddr_mod20_8_pat_times / MOD_SZ; + pass = pass % 8; + if (pass == 0) { + p0 = 0x80; + } else { + p0 = p0 >> 1; + } + + p1 = p0 | (p0 << 8) | (p0 << 16) | (p0 << 24); + + times = ddr_mod20_8_pat_times % MOD_SZ; + if (times % 2 == 0) { + p2 = ~p1; + } else { + /* Switch patterns */ + p2 = p1; + p1 = ~p2; + } + ddr_mod20_8_pat_times ++; + + return modtst(desc, times, 2, p1, p2); +} + +static int ddr_addr_walking(char *desc) +{ + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_addr_walking test.\n"); + return addrress_walking(desc); +} + +static int ddr_march_c(char *desc) +{ + static unsigned int test_times = 0; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_march_c test.\n"); + test_times++; + if (test_times == 1) { + p1 = 0; + } else { + p1 = ft_rand(); + } + p2 = ~p1; + + return march_c(desc, 1, p1, p2); +} + +static int ddr_march_g(char *desc) +{ + static unsigned int test_times = 0; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_march_g test.\n"); + test_times++; + if (test_times == 1) { + p1 = 0; + } else { + p1 = ft_rand(); + } + p2 = ~p1; + + return march_g(desc, 1, p1, p2); +} + +static int ddr_galloping(char *desc) +{ + static unsigned int test_times=0; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_galloping test.\n"); + test_times ++; + if (test_times == 1) { + p1 = 0; + } else { + p1 = ft_rand(); + } + p2 = ~p1; + + return galloping(desc, p1, p2); +} + +static int ddr_column_operate(char *desc) +{ + int i; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_column_operate test.\n"); + for (i = 0; i < 1023; i++) { + p1 = ~i; + /* column_operate(1, p1, i); */ + if (column_operate(desc, 1, p1, i)) { + return FT_DDR_ERR; + } + if (i % 100 == 0) { + FT_DDR_SHOW(); + } + } + + return FT_DDR_SUCCESS; +} + +static int ddr_swap_blocks(char *desc) +{ + static unsigned int test_times = 0; + ulong blk_size; + int ret; + int swap_times = 1; + struct vars v_tmp; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ddr_swap_blocks test.\n"); + test_times++; + blk_size = (ulong)blk_size_array[1]; /* 24MB */ + + memcpy(&v_tmp, v, sizeof(struct vars)); + if (((ulong)v->map[0].end - (ulong)v->map[0].start) > MEMORY_SIZE_1G) { + FAC_LOG_DBG(GRTD_LOG_DEBUG, "set memory size to 0x%lx.\n", MEMORY_SIZE_1G); + v->map[0].end = (unsigned int *)((ulong)v->map[0].start + MEMORY_SIZE_1G); + } + ret = swap_blocks(desc, test_times, swap_times, blk_size); + memcpy(v, &v_tmp, sizeof(struct vars)); + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_dram.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_dram.c new file mode 100644 index 0000000000..16f2404265 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_dram.c @@ -0,0 +1,804 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int platform_fac_dbg = GRTD_LOG_NONE; +static int do_mlock = 1; +static ulong mem_test_data1 = sizeof(ulong) == 4 ? 0x55555555UL : 0x5555555555555555ULL; +static ulong mem_test_data2 = sizeof(ulong) == 4 ? 0xAAAAAAAAUL : 0xAAAAAAAAAAAAAAAAULL; + +int dram_wr_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int dram_rd_main(int argc, char **argv) +{ + int fd, i, ret; + unsigned char buffer[1024]; + memset(buffer, 0, 1024); + argc = argc; + argv = argv; + if ((fd = open("/dev/mem",O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO)) < 0 ) { + printf("xxxx:%s\r\n", strerror(errno)); + return fd; + } + + if ((ret = lseek(fd, 0x1f400000, SEEK_SET)) < 0) { + printf("llseek:%s\r\n", strerror(errno)); + close(fd); + return ret; + } + if ((ret = read(fd, buffer, 1024)) < 0) { + printf("read:%s\r\n", strerror(errno)); + close(fd); + return ret; + } + + for (i = 0; i < 1024; i++) { + printf("%02x ", buffer[i]); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } + printf("\r\n"); + + close(fd); + return 0; +} + +int dram_chk_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +static int dram_test_arg_pars(int argc, char **argv, int *simple, int *all, int *debug) +{ + switch(argc) { + case 1: + *simple = 1; + *all = 0; + *debug = 0; + return 0; + case 2: + if (strcmp(argv[1], "simple") == 0) { + *simple = 1; + *all = 0; + *debug = 0; + } else if (strcmp(argv[1], "complex") == 0) { + *simple = 0; + *all = 0; + *debug = 0; + } else if (strcmp(argv[1], "debug") == 0) { + *simple = 1; + *all = 0; + *debug = 1; + } else { + break; + } + return 0; + case 3: + if (strcmp(argv[1], "simple") == 0 && strcmp(argv[2], "debug") == 0) { + *simple = 1; + *all = 0; + *debug = 1; + } else if (strcmp(argv[1], "complex") == 0) { + if (strcmp(argv[2], "some") == 0) { + *simple = 0; + *all = 0; + *debug = 0; + } else if (strcmp(argv[2], "all") == 0) { + *simple = 0; + *all = 1; + *debug = 0; + } else if (strcmp(argv[2], "debug") == 0) { + *simple = 0; + *all = 0; + *debug = 1; + } + } else { + break; + } + return 0; + case 4: + if (strcmp(argv[1], "complex") == 0) { + if (strcmp(argv[2], "some") == 0 && strcmp(argv[3], "debug") == 0) { + *simple = 0; + *all = 0; + *debug = 1; + } else if (strcmp(argv[2], "all") == 0 && strcmp(argv[3], "debug") == 0) { + *simple = 0; + *all = 1; + *debug = 1; + } else { + break; + } + } else { + break; + } + return 0; + default: + break; + } + + return -1; +} + +int platform_devfile_read(const char *filename, char *buf, int size, int offset) +{ + int fd; + int nread; + int ret; + + if (filename == NULL || buf == NULL) { + FAC_LOG_DBG(GRTD_LOG_ERR, "param is error!\n"); + return FAC_TEST_FAIL; + } + ret = FAC_TEST_OK; + if ((fd = open(filename, O_RDONLY | O_SYNC)) < 0) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: Open file[%s] failed(%s)!\n", filename, strerror(errno)); + return FAC_TEST_FAIL; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: lseek file[%s] error(%s)!\n", filename, strerror(errno)); + ret = FAC_TEST_FAIL; + goto error; + } + + nread = read(fd, buf, size); + if (nread < 0) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: Read file[%s] error(%s)!\n", filename, strerror(errno)); + ret = FAC_TEST_FAIL; + goto error; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "%s read data(off:0x%x):0x%x\n", filename, offset, buf[0]); +error: + close(fd); + return ret; +} + +int platform_devfile_write(const char *filename, char *buf, int size, int offset) +{ + int fd; + int nwrite; + int ret; + + if (filename == NULL || buf == NULL) { + FAC_LOG_DBG(GRTD_LOG_ERR, "param is error!\n"); + return FAC_TEST_FAIL; + } + ret = FAC_TEST_OK; + if ((fd = open(filename, O_CREAT | O_RDWR | O_TRUNC | O_SYNC, 0)) < 0) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: Open file[%s] failed(%s)!\n", filename, strerror(errno)); + return FAC_TEST_FAIL; + } + + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: lseek file[%s] error(%s)!\n", filename, strerror(errno)); + ret = FAC_TEST_FAIL; + goto error; + } + + nwrite = write(fd, buf, size); + if (nwrite != size) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: Write file[%s] error(%s)!\n", filename, strerror(errno)); + ret = FAC_TEST_FAIL; + goto error; + } + +error: + close(fd); + sync(); + return ret; +} + +int platform_get_sys_memory_size_form_cmdline(unsigned int *sys_memory_size) +{ + int ret; + char *start; + char *mem_start_string; + char mem_size_buf[FAC_MEM_SIZE_BUF_LEN]; + + /* MEMORY information area start string */ + mem_start_string = "RAMSZ="; + /* Get memory size from the /proc/octeon_info file */ + memset(mem_size_buf, 0, FAC_MEM_SIZE_BUF_LEN); + ret = platform_devfile_read("/proc/cmdline", mem_size_buf, FAC_MEM_SIZE_BUF_LEN - 1, 0); + if (ret) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Read mem info fail!\n"); + return FAC_TEST_FAIL; + } + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:mem info[%s]\n", mem_size_buf); + + /* Extract the memory size information from the read information */ + start = strstr(mem_size_buf, mem_start_string); + if (start != NULL) { + start = start + strlen(mem_start_string); + *sys_memory_size = strtoul(start, NULL, 10); + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Mem size[%d MB]\n", *sys_memory_size); + return FAC_TEST_OK; + } else { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Get mem size fail!\n"); + return FAC_TEST_FAIL; + } +} + +/* + * platform_simple_get_mem_space - Gets the space for the memory test + * @buf: pointer to the start address + * @size: indicates the space size + * + * return: FAC_TEST_FAIL | FAC_TEST_OK + */ +static int platform_simple_get_mem_space(void **buf, size_t *size) +{ + size_t pagesize, wantsize, alignedsize; + void *start, *aligned; + int done_mem; + ptrdiff_t pagesizemask; + + start = NULL; + done_mem = 0; + wantsize = FAC_MEM_TEST_SIZE; + pagesize = 4096; + pagesizemask = (ptrdiff_t) ~(pagesize - 1); + + while (!done_mem) { + while (!start && wantsize) { + start = (void *) malloc(wantsize); + if (!start) wantsize -= pagesize; + } + + if (!wantsize) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Malloc simple space failed\n"); + return FAC_TEST_FAIL; + } + + memset(start, 0, wantsize); + *size = wantsize; + alignedsize = wantsize; + + fflush(stdout); + if (do_mlock && wantsize) { + fflush(stdout); + + if ((size_t) start % pagesize) { + aligned = (void *) ((size_t) start & pagesizemask) + pagesize; + alignedsize -= ((size_t) aligned - (size_t) start); + } else { + aligned = start; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "trying mlock ...start[0x%lx], size[0x%x]", (ulong)start, + (int)alignedsize); + /* Try mlock */ + if (mlock(aligned, alignedsize) < 0) { + switch(errno) { + case EAGAIN: + FAC_LOG_DBG(GRTD_LOG_ERR, "over system/pre-process limit, reducing...\n"); + free(start); + start = NULL; + wantsize -= pagesize; + break; + case ENOMEM: + FAC_LOG_DBG(GRTD_LOG_ERR, "too many pages, reducing...\n"); + free(start); + start = NULL; + wantsize -= pagesize; + break; + case EPERM: + FAC_LOG_DBG(GRTD_LOG_ERR, "insufficient permission.\n"); + FAC_LOG_DBG(GRTD_LOG_ERR, "Trying again, unlocked:\n"); + do_mlock = 0; + free(start); + start = NULL; + wantsize = FAC_MEM_TEST_SIZE; + break; + default: + FAC_LOG_DBG(GRTD_LOG_ERR, "failed for unknown reason.\n"); + do_mlock = 0; + done_mem = 1; + } + } else { + FAC_LOG_DBG(GRTD_LOG_DEBUG, "locked.\n"); + done_mem = 1; + } + } else { + done_mem = 1; + } + } + + if (!wantsize) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Malloc space failed\n"); + return FAC_TEST_FAIL; + } + if (!do_mlock) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Mlock mmap'ed space failed\n"); + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM WARNING:Continuing with unlocked memory;" + " testing will be slower and less reliable.\n"); + } + *buf = start; + return FAC_TEST_OK; +} + +static int platform_simple_check_addrline(ulong *start, size_t size, char *desc) +{ + ulong *p1; + ulong j; + size_t i; + size_t physaddr; + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:addr line check START[0x%lx] SIZE[0x%lx]!\n", + (ulong)start, (ulong)size); + fflush(stdout); + for (j = 0; j < 2; j++) { + p1 = start; + + fflush(stdout); + for (i = 0; i < size; i += sizeof(ulong), p1++) { + *((volatile ulong *)p1) = ((((j + i) % 2) == 0) ? (ulong)p1 : ~((ulong)p1)); + } + + fflush(stdout); + + p1 = start; + for (i = 0; i < size; i += sizeof(ulong), p1++) { + if (*((volatile ulong *)p1) != (((j + i) % 2) == 0 ? (ulong)p1 : ~((ulong)p1))) { + physaddr = (size_t)start + (i * sizeof(ulong)); + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Possible bad address line at physical " + "address 0x%08lx.\n", physaddr); + sprintf(desc, "MEM ERROR:Possible bad address line at physical " + "address 0x%08lx.\n", physaddr); + fflush(stdout); + return FAC_TEST_FAIL; + } + } + } + fflush(stdout); + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:addr line check OK!\n"); + return FAC_TEST_OK; +} +static int platform_simple_check_data(ulong *start, size_t size, char *desc) +{ + int i; + size_t j; + ulong data = 0; + ulong *p1; + ulong check_error = 0; + + /* Walking 1's Test */ + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Walking 1's Test START[0x%lx] SIZE[0x%lx]!\n", + (ulong)start, (ulong)size); + for (i = 0; i < 8; i++) { + data = (data << 1) + 1; + p1 = start; + fflush(stdout); + for (j = 0; j < size; j += sizeof(ulong), p1++) { + *((volatile ulong *)p1) = data; + } + fflush(stdout); + p1 = start; + for (j = 0; j < size; j += sizeof(ulong), p1++) { + if (*((volatile ulong *)p1) != data) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:[0x%lx] should be 0x%lx,but is 0x%lx.\n", + (ulong)p1, data, *((volatile ulong *)p1)); + check_error++; + sprintf(desc, "MEM ERROR:[0x%lx] should be 0x%lx,but is 0x%lx.\n", + (ulong)p1, data, *((volatile ulong *)p1)); + return FAC_TEST_FAIL; + } + } + } + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Walking 1's Test END!\n"); + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Bus Noise Test START[0x%lx] SIZE[0x%lx]!\n", + (ulong)start, (ulong)size); + + /* Bus Noise Test */ + fflush(stdout); + p1 = start; + for (j = 0; j < size; j += sizeof(ulong), p1++) { + *((volatile ulong *)p1) = (j % 2) ? mem_test_data1 : mem_test_data2; + } + fflush(stdout); + p1 = start; + for (j = 0; j < size; j += sizeof(ulong), p1++) { + if (*((volatile ulong *)p1) != ((j % 2) ? mem_test_data1 : mem_test_data2)) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:[0x%lx] should be 0x%lx,but is 0x%lx.\n", + (ulong)p1, ((j % 2) ? mem_test_data1 : mem_test_data2), *((volatile ulong *)p1)); + check_error++; + sprintf(desc, "MEM ERROR:[0x%lx] should be 0x%lx,but is 0x%lx.\n", + (ulong)p1, ((j % 2) ? mem_test_data1 : mem_test_data2), *((volatile ulong *)p1)); + return FAC_TEST_FAIL; + } + } + fflush(stdout); + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Bus Noise Test END!\n"); + return check_error; +} + +static void platform_simple_free_mem_space(void *buf, size_t size) +{ + if (do_mlock) { + munlock(buf, size); + } + free(buf); +} + +static int platform_simple_sdram_ecc_detect() +{ + char c; + char *loc, *next; + FILE *fp; + char file_line[FAC_FILE_LINE_LEN]; + int i, core_num, temp, ecc_error; + + i = 0; + core_num = 0; + ecc_error = 0; + + /* Open the MTD device file */ + if ((fp = fopen("/proc/interrupts", "r")) == NULL) { + FAC_LOG_DBG(GRTD_LOG_ERR, "Fopen /proc/interrupts fail!\t err_no[%d]\n", errno); + return FAC_TEST_FAIL; + } + + memset(file_line, 0, FAC_FILE_LINE_LEN); + /* Find the MTD device name available for production testing on each line in the MTD file */ + while (fgets(file_line, FAC_FILE_LINE_LEN, fp) != NULL) { + if (i == 0) { + loc = strrchr(file_line, 'U'); + core_num = strtoul(loc + 1, NULL, 10); + } + i++; + if (strstr(file_line, "LMC") != NULL) { + goto find; + } + } + FAC_LOG_DBG(GRTD_LOG_ERR, "ECC: Not find lmc info in file\n"); + fclose(fp); + return ecc_error; +find: + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ECC: Get ecc info[%s]\n", file_line); + /* Gets the number of the MTD device name that can be production-tested, with the device name and device partition size delimiters as colons */ + c = ':'; + if ((loc = strchr(file_line, c))!= NULL) { + i = 0; + loc++; + while (i <= core_num) { + temp = strtoul(loc, &next, 10); + loc = next; + ecc_error += temp; + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ECC: cpu %d ecc error num: %d\n", i, temp); + i++; + } + + } + + fclose(fp); + FAC_LOG_DBG(GRTD_LOG_DEBUG, "ECC: ecc error num: %d\n", ecc_error); + return ecc_error; + +} + +int platform_simple_sys_memory_test(char *desc) +{ + void *buf, *aligned; + size_t size, alignedsize, pagesize; + ptrdiff_t pagesizemask; + int ret = FAC_TEST_OK; + + /* Gets the memory space available for testing */ + if (platform_simple_get_mem_space(&buf, &size) != FAC_TEST_OK) { + ret = GRTD_SDRAM_WR_ERR; + goto ecctest; + } + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Get test space success, start at [0x%lx] size[0x%lx]\n", + (ulong)buf, (ulong)size); + + /* Align 4K */ + pagesize = 4096; + pagesizemask = (ptrdiff_t) ~(pagesize - 1); + alignedsize = size; + if ((size_t) buf % pagesize) { + aligned = (void *) ((size_t) buf & pagesizemask) + pagesize; + alignedsize -= ((size_t) aligned - (size_t) buf); + } else { + aligned = buf; + } + + /* Check address line */ + if (platform_simple_check_addrline((ulong *)aligned, alignedsize, desc) != FAC_TEST_OK) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Check address line failed!\n"); + ret = GRTD_SDRAM_WR_ERR; + goto _error; + } + + /* Memory read/write check */ + if (platform_simple_check_data((ulong *)aligned, alignedsize, desc)) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Check data failed!\n"); + ret = GRTD_SDRAM_WR_ERR; + goto _error; + } + +_error: + platform_simple_free_mem_space(buf, size); +ecctest: + /* Memory ECC error detection */ + if (platform_simple_sdram_ecc_detect()) { + FAC_LOG_DBG(GRTD_LOG_ERR, "ERROR: ECC error occured!\n"); + ret = GRTD_SDRAM_ECC_ERR; + } + return ret; +} + +static int platform_get_system_free_mem(size_t *free_size) +{ + int len; + FILE *fp; + char *loc; + char mem_file_line[FAC_FILE_LINE_LEN]; + char mem_size[FAC_FILE_LINE_LEN]; + size_t all_free_size; + + if ((fp = fopen("/proc/meminfo", "r")) == NULL) { + FAC_LOG_DBG(GRTD_LOG_ERR, "Open meminfo fail(%s)!\n", strerror(errno)); + return FAC_TEST_FAIL; + } + + /* Gets the path to the mount */ + memset(mem_file_line, 0, sizeof(mem_file_line)); + while (fgets(mem_file_line, FAC_FILE_LINE_LEN, fp) != NULL) { + FAC_LOG_DBG(GRTD_LOG_DEBUG, "meminfo file content:%s \n", mem_file_line); + loc = strstr(mem_file_line, "MemFree:"); + if (loc == NULL) { + continue; + } + + loc = loc + strlen("MemFree:"); + while (*loc == ' ') { + loc++; + } + len = 0; + while (*(loc + len) != ' ') { + len++; + } + FAC_LOG_DBG(GRTD_LOG_DEBUG, "free mem info:%s, len:%d \n", loc, len); + snprintf(mem_size, len, "%s", loc); + mem_size[len] = 0; + all_free_size = strtoul(mem_size, NULL, 10); + /* Use 90% to test */ + *free_size = all_free_size / 4 / 10 * 9 * 4096; + goto getok; + } + + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM free info get failed!\n"); + fclose(fp); + return FAC_TEST_FAIL; + +getok: + FAC_LOG_DBG(GRTD_LOG_DEBUG, "free mem: total--0x%lx use--0x%lx\n", all_free_size * 1024, *free_size); + fclose(fp); + return FAC_TEST_OK; +} + +/* + * platform_get_mem_space - Gets the space for the memory test + * @buf: pointer to the obtained start address + * @size: indicates the space size + * + * Return int: FAC_TEST_FAIL | FAC_TEST_OK + */ +static int platform_get_mem_space(void **buf, size_t *size) +{ + void *start; + size_t pagesize, wantsize; + + start = NULL; + if (platform_get_system_free_mem(&wantsize)) { + FAC_LOG_DBG(GRTD_LOG_DEBUG, "Get free mem info fail,use defaul size(0x%x)\n", FAC_MEM_TEST_SIZE); + wantsize = FAC_MEM_TEST_SIZE; + } + pagesize = 4096; /* The page size is 4K*/ + +retry: + while (!start && wantsize) { + start = (void *) malloc(wantsize); + if (!start) wantsize -= pagesize; + } + if (!wantsize) { + FAC_LOG_DBG(GRTD_LOG_ERR, "MEM ERROR:Malloc space failed\n"); + return FAC_TEST_FAIL; + } + memset(start, 0, wantsize); + *size = wantsize; + FAC_LOG_DBG(GRTD_LOG_DEBUG, "trying mlock ...start[%p], size[0x%lx]\n", start, wantsize); + /* mlock Memory space */ + if (mlock(start, wantsize) < 0) { + FAC_LOG_DBG(GRTD_LOG_ERR, "failed for mlock(%s), retry.\n", strerror(errno)); + free(start); + start = NULL; + wantsize -= pagesize; + goto retry; + } + + *buf = start; + return FAC_TEST_OK; +} + +/* + * platform_free_mem_space - Release the memory required for the memory test + * + * Return void: + */ +static void platform_free_mem_space(void *buf, size_t size) +{ + munlock(buf, size); + free(buf); +} + +/** + * platform_complex_sys_memory_test - Memory test + * @sdram_test: Output details of memory test results + * @kaoji: Enter, is the machine currently copied * + * Return int: FAC_TEST_FAIL | FAC_TEST_OK + */ +int platform_complex_sys_memory_test(char *desc, int kaoji) +{ + int ret; + void *buf; + size_t size, autotest_size; + int i; + char desc_tmp[128]; + + if (desc == NULL) { + FAC_LOG_DBG(GRTD_LOG_ERR, "param is error!\n"); + return FAC_TEST_FAIL; + } + + ret = FAC_TEST_OK; + /* Gets the memory space available for testing */ + if (platform_get_mem_space(&buf, &size) != FAC_TEST_OK) { + return FAC_TEST_FAIL; + } + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "MEM:Get test space success, start at [0x%lx] size[0x%lx]\n", + (ulong)buf, (ulong)size); + + autotest_size = size; +#if 0 + /* Init ddr test. */ + if (kaoji && autotest_size > FAC_MEM_AUTOTEST_SIZE) { + autotest_size = FAC_MEM_AUTOTEST_SIZE; + } else if (autotest_size > FAC_MEM_MAX_SIZE) { + autotest_size = FAC_MEM_MAX_SIZE; + } +#endif + ft_ddr_test_init(buf, autotest_size); + /* init memory */ + memset((char *)buf, 0, autotest_size); + + /* Test memory */ + memset((char *)desc_tmp, 0, 128); + for (i = 0 ; i < TETS_TOTAL_NUMBER; i++) { + if (ft_ddr_test_fun[i].always == 0 && kaoji) { + /* In the copy state, some test items are not tested */ + continue; + } + + if (ft_ddr_test_fun[i].ddr_test != NULL) { + if (ft_ddr_test_fun[i].ddr_test(desc_tmp) != FT_DDR_SUCCESS) { + sprintf(desc, "%s:%s", ft_ddr_test_fun[i].name, desc_tmp); + ret = GRTD_SDRAM_WR_ERR; + break; + } + } + } + FT_DDR_SHOW_END(); + + FAC_LOG_DBG(GRTD_LOG_DEBUG, "TEST ok(ret:%d).\n", ret); + /* Free memory */ + platform_free_mem_space(buf, size); + return ret; +} + +static int memory_test(int simple, int all) +{ + unsigned int memory_size; + char desc[128]; + int ret; + + if (platform_get_sys_memory_size_form_cmdline(&memory_size)) { + printf("Get memory size fail\n"); + return FAC_TEST_FAIL; + } + + if (simple) { + ret = platform_simple_sys_memory_test(desc); + } else { + if (all) { + ret = platform_complex_sys_memory_test(desc, 0); + } else { + ret = platform_complex_sys_memory_test(desc, 1); + } + } + + if (simple) { + printf("\n[Simple Algorithm]\n"); + } else { + if (all) { + printf("\n[Complex All Algorithm]\n"); + } else { + printf("\n[Complex Some Algorithm]\n"); + } + } + printf(" SDRAM Space: %d(MB)\n", memory_size); + if (ret != FAC_TEST_OK) { + switch (ret) { + case GRTD_SDRAM_ECC_ERR: + printf(" ECC check error\r\n"); + break; + case GRTD_SDRAM_WR_ERR: + printf(" Error type: Memory read/write error\r\n"); + break; + case GRTD_SDRAM_GET_MEM_SIZE_ERR: + printf(" Error type: Failed to obtain memory capacity\r\n"); + break; + default: + printf(" Unknown cause of failure(%d)\r\n", ret); + break; + } + printf(" %s", desc); + printf(" Test Result: Fail\n\n"); + } else { + printf(" Test Result: Pass\n\n"); + } + return ret; +} + +int dram_test_main(int argc, char **argv) +{ + int simple,all,debug; + int ret; + + printf("\r\n" + "********************** dram test **********************\r\n"); + + debug = 0; + simple = 0; + all = 0; + ret = dram_test_arg_pars(argc, argv, &simple, &all, &debug); + if (ret < 0) { + fprintf(stderr, + "Usage: dram_test [simple|complex some|complex all] \r\n" + " simple Use the simple Algorithm \r\n" + " complex some Use some the complex Algorithm \r\n" + " complex all Use all the complex Algorithm \r\n"); + exit(1); + return -1; + } + if (debug) { + platform_fac_dbg = GRTD_LOG_DEBUG; + } + + return memory_test(simple, all); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_emmc.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_emmc.c new file mode 100644 index 0000000000..229bb26822 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_emmc.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define EMMC_SYS_BLOCK_PATH "/sys/block/emmcblk0/size" +#define EMMC_DEV_FACTEST_PATH "/dev/emmcblk0p7" +#define EMMC_BLK_SIZE 512 +#if 0 +/* The test values are the same as nandflash, and the emmc factory_test partition is nearly 16MB */ +static char emmc_test_ch[] = { + 0x00, 0xFF, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, + 0xBF, 0x7F +}; +#endif +int emmc_test_main(int argc, char **argv) +{ +#if 1 + argc = argc; + argv = argv; + return -1; +#else + char *buf; + int fd, i, j, ret; + + if (argc != 1) { + fprintf(stderr, "Error: Wrong input!\n"); + return -1; + } + argv = argv; + + ret = posix_memalign((void **) &buf, EMMC_BLK_SIZE, EMMC_BLK_SIZE); + if (ret != 0) { + fprintf(stderr, "Error: Alloc memory failed(%d,%s)!\n", + ret, strerror(ret)); + return -1; + } + + fd = open(EMMC_DEV_FACTEST_PATH, O_RDWR | O_DIRECT, S_IRWXU); + if (fd < 0) { + fprintf(stderr, "ERROR: Open file[rw,%s] failed(%s)!\n", + EMMC_DEV_FACTEST_PATH, strerror(errno)); + goto out_free; + } + + for (i = 0; i < (int) sizeof(emmc_test_ch); i++) { + memset(buf, emmc_test_ch[i], EMMC_BLK_SIZE); + ret = write(fd, buf, EMMC_BLK_SIZE); + if (ret != EMMC_BLK_SIZE) { + fprintf(stderr, "ERROR: Write file error(%d,%d,%s)!\n", + ret, i, strerror(errno)); + goto out_close; + } + } + + ret = fsync(fd); + if (ret != 0) { + fprintf(stderr, "ERROR: Fsync file error(%d,%s)!\n", + ret, strerror(errno)); + goto out_close; + } + + close(fd); + + fd = open(EMMC_DEV_FACTEST_PATH, O_RDONLY | O_DIRECT, S_IRWXU); + if (fd < 0) { + fprintf(stderr, "ERROR: Open file[rd,%s] failed(%s)!\n", + EMMC_DEV_FACTEST_PATH, strerror(errno)); + goto out_free; + } + + for (i = 0; i < (int) sizeof(emmc_test_ch); i++) { + memset(buf, 0x11, EMMC_BLK_SIZE); /* 0x11 does not belong to any test value */ + ret = read(fd, buf, EMMC_BLK_SIZE); + if (ret != EMMC_BLK_SIZE) { + fprintf(stderr, "ERROR: Read file error(%d,%d,%s)!\n", + ret, i, strerror(errno)); + goto out_close; + } + + for (j = 0; j < EMMC_BLK_SIZE; j++) { + if (buf[j] != emmc_test_ch[i]) { + fprintf(stderr, "ERROR: Check error(%d,%d,%d,%d)!\n", + i, j, buf[j], emmc_test_ch[i]); + goto out_close; + } + } + } + + close(fd); + + free(buf); + + printf("SUCCESS: eMMC test pass!\n"); + + return 0; + +out_close: + close(fd); + +out_free: + free(buf); + + return -1; +#endif +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_i2c.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_i2c.c new file mode 100644 index 0000000000..be04e59a2a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_i2c.c @@ -0,0 +1,692 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void rtc_help(char *name) +{ + fprintf(stderr, + "Usage: %s rtc year month day hour minute second \r\n" + " rtc rtc number(default 0) \r\n" + " year \r\n" + " month \r\n" + " day \r\n" + " hour \r\n" + " minute \r\n" + " second \r\n", + name); + exit(1); +} + +static void i2c_help(char *name) +{ + fprintf(stderr, + "Usage: %s i2c_bus slave_addr offset data [data_len] [times] [offset_len] \r\n" + " i2c_bus controller integer or an I2C bus name \r\n" + " slave_addr i2c device address \r\n" + " offset The relative offset within the device \r\n" + " data Test data(8bit) \r\n" + " [data_len] The length of test data(default 1) \r\n" + " [times} \r\n", + name); + exit(1); +} + +static int lookup_i2c_bus(const char *i2cbus_arg) +{ + unsigned long i2cbus; + char *end; + + i2cbus = strtoul(i2cbus_arg, &end, 0); + if (*end || !*i2cbus_arg) { + /* Not a number, maybe a name? */ + //return lookup_i2c_bus_by_name(i2cbus_arg); + return -EINVAL; + } + if (i2cbus > 0xFFFFF) { + fprintf(stderr, "Error: I2C bus out of range!\n"); + return -EINVAL; + } + + return i2cbus; +} + +static int parse_i2c_address(const char *address_arg) +{ + long address; + char *end; + + address = strtol(address_arg, &end, 0); + if (*end || !*address_arg) { + fprintf(stderr, "Error: slave address is not a number!\n"); + return -EINVAL; + } + if (address < 0x03 || address > 0x255) { + fprintf(stderr, "Error: save address out of range " + "(0x03-0x77)!\n"); + return -EINVAL; + } + + return address; +} + +static int i2c_arg_check(int argc, char **argv, struct i2c_dev_priv *i2c_priv, int min_arg) +{ + int i2cbus, address, offset = 0, data = 0, data_len = 1, times = 1; + int offset_len = 1; + char *end; + int flags = 0; + + if (argc < min_arg) { + return -EINVAL; + } + + i2cbus = lookup_i2c_bus(argv[flags + 1]); + if (i2cbus < 0) { + return -EINVAL; + } + + address = parse_i2c_address(argv[flags + 2]); + if (address < 0) { + return -EINVAL; + } + + offset = strtol(argv[flags + 3], &end, 0); + if (*end || offset < 0 || offset > 0xffff) { + fprintf(stderr, "Error: Data offset invalid!\n"); + return -EINVAL; + } + + if (argc > 4) { + data = strtol(argv[flags + 4], &end, 0); + if (*end || data < 0) { + fprintf(stderr, "Error: Data invalid!\n"); + return -EINVAL; + } + } + + if (argc > 5) { + data_len = strtol(argv[flags + 5], &end, 0); + if (*end || data_len < 0) { + fprintf(stderr, "Error: Data length invalid!\n"); + return -EINVAL; + } + } + + if (argc > 6) { + times = strtol(argv[flags + 6], &end, 0); + if (*end || times < 0) { + fprintf(stderr, "Error: times invalid!\n"); + return -EINVAL; + } + } + + if (argc > 7) { + offset_len = strtol(argv[flags + 7], &end, 0); + if (*end || offset_len < 0) { + fprintf(stderr, "Error: offset_len invalid!\n"); + return -EINVAL; + } + } + + i2c_priv->i2cbus = i2cbus; + i2c_priv->save_addr = address; + i2c_priv->offset = offset; + i2c_priv->offset_len = offset_len; + i2c_priv->data = data; + i2c_priv->data_len = data_len; + i2c_priv->times = times; + return 0; +} + +static int open_i2c_dev(int i2cbus) +{ + int file, ret; + char filename[I2C_MAX_NAME_SIZE]; + + ret = snprintf(filename, I2C_MAX_NAME_SIZE, "/dev/i2c-%d", i2cbus); + filename[ret] = '\0'; + if ((file = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "`%s': %s\n", filename, strerror(errno)); + } + + return file; +} + +#if 0 +static int set_slave_addr(int file, int address, int force) +{ + /* With force, let the user read from/write to the registers + even when a driver is also running */ + if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) { + fprintf(stderr, + "Error: Could not set address to 0x%02x: %s\n", + address, strerror(errno)); + return -errno; + } + + return 0; +} +#endif + +/** + * + * i2c_transfer + * + * + * @param file + * @param i2c_priv + * @param read_write 0:write 1:read + * @param num_msgs + * + * @return int + */ +static int i2c_transfer(int file, struct i2c_dev_priv *i2c_priv, int read_write, int num_msgs) +{ + int i; + unsigned char offset[2]; + struct i2c_msg msgs[2]; + struct i2c_rdwr_ioctl_data ioctl_data; + int len; + + if (i2c_priv->buffer == NULL) { + i2c_priv->buffer = malloc(i2c_priv->data_len); + if (i2c_priv->buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + return -ENOMEM; + } + } + + for (i = 0; i < i2c_priv->data_len && !read_write; i++) { + i2c_priv->buffer[i] = i2c_priv->data; + } + + if (i2c_priv->offset_len == 1) { + offset[0] = (i2c_priv->offset & 0xFF); + len = 1; + } else { + offset[0] = ((i2c_priv->offset & 0xFF00) >> 8); + offset[1] = (i2c_priv->offset & 0xFF); + len = 2; + } + + switch (num_msgs) { + case 1: + msgs[0].addr = i2c_priv->save_addr; + msgs[0].flags = read_write; + msgs[0].buf = i2c_priv->buffer; + msgs[0].len = i2c_priv->data_len; + + ioctl_data.msgs = msgs; + ioctl_data.nmsgs = 1; + break; + case 2: + msgs[0].addr = i2c_priv->save_addr; + msgs[0].flags = 0; + msgs[0].buf = offset; + msgs[0].len = len; + + msgs[1].addr = i2c_priv->save_addr; + msgs[1].flags = read_write; + msgs[1].buf = i2c_priv->buffer; + msgs[1].len = i2c_priv->data_len; + + ioctl_data.msgs = msgs; + ioctl_data.nmsgs = 2; + break; + default: + break; + } + + if (ioctl(file, I2C_RDWR, &ioctl_data) < 0) { + fprintf(stderr, + "Error: i2c_transfer error %s\n", + strerror(errno)); + return -1; + } + + return 0; +} + +static void print_arg(struct i2c_dev_priv *i2c_priv) +{ + printf("I2C Controller %d, Slave addr: 0x%02X, Offset: 0x%02X", + i2c_priv->i2cbus, i2c_priv->save_addr, i2c_priv->offset); + + if (i2c_priv->data) { + printf(", Data = 0x%02X", i2c_priv->data); + } + + if (i2c_priv->data_len) { + printf(", Data_len = %d", i2c_priv->data_len); + } + + if (i2c_priv->times) { + printf(", Times = %u", i2c_priv->times); + } + + if (i2c_priv->offset_len) { + printf(", Offset_len = %u", i2c_priv->offset_len); + } + + printf("\r\n"); +} + +static int i2c_check_data(unsigned char *buffer, struct i2c_dev_priv *i2c_priv) +{ + int i; + for (i = 0; i < i2c_priv->data_len; i++) { + if (buffer[i] != i2c_priv->buffer[i]) { + return (-1); + } + } + + return (0); +} + +int i2c_wr_main(int argc, char **argv) +{ + int ret, fd; + struct i2c_dev_priv i2c_priv; + + memset(&i2c_priv, 0, sizeof(struct i2c_dev_priv)); + + ret = i2c_arg_check(argc, argv, &i2c_priv, 5); + if (ret < 0) { + i2c_help("i2c_wr"); + return -1; + } + + printf("\r\n" + "********************** I2C write test **********************\r\n"); + print_arg(&i2c_priv); + + if ((fd = open_i2c_dev(i2c_priv.i2cbus)) < 0) { + return -1; + } + +#if 0 + if ((ret = set_slave_addr(fd, i2c_priv.save_addr, 0)) < 0) { + close(fd); + return -1; + } +#endif + + while (i2c_priv.times--) { + if ((ret = i2c_transfer(fd, &i2c_priv, 0, 2)) < 0) { + goto error_out; + } + } + +error_out: + printf("\r\n******************** I2C read test End ********************\r\n\r\n"); + if (i2c_priv.buffer) { + free(i2c_priv.buffer); + } + close(fd); + return ret; +} + +int i2c_rd_main(int argc, char **argv) +{ + int i, ret, fd; + struct i2c_dev_priv i2c_priv; + + memset(&i2c_priv, 0, sizeof(struct i2c_dev_priv)); + ret = i2c_arg_check(argc, argv, &i2c_priv, 4); + if (ret < 0) { + i2c_help("i2c_rd"); + return -1; + } + + if ((fd = open_i2c_dev(i2c_priv.i2cbus)) < 0) { + return -1; + } + + printf("\r\n" + "********************** I2C read test **********************\r\n"); + print_arg(&i2c_priv); + +#if 0 + if ((ret = set_slave_addr(fd, i2c_priv.save_addr, 0)) < 0) { + close(fd); + return -1; + } +#endif + + while (i2c_priv.times--) { + if ((ret = i2c_transfer(fd, &i2c_priv, I2C_M_RD, 2)) < 0) { + goto error_out; + } + } + printf("Last Read: \r\n"); + /* dump data */ + for (i = 0; i < i2c_priv.data_len; i++) { + printf("%02X ", i2c_priv.buffer[i]); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } + +error_out: + printf("\r\n******************** I2C read test End ********************\r\n\r\n"); + if (i2c_priv.buffer) { + free(i2c_priv.buffer); + } + close(fd); + return ret; +} + +int i2c_chk_main(int argc, char **argv) +{ + int ret, fd; + struct i2c_dev_priv i2c_priv; + unsigned char *buffer; + + memset(&i2c_priv, 0, sizeof(struct i2c_dev_priv)); + + ret = i2c_arg_check(argc, argv, &i2c_priv, 5); + if (ret < 0) { + i2c_help("i2c_chk"); + return -1; + } + + printf("\r\n" + "********************** I2C write test **********************\r\n"); + print_arg(&i2c_priv); + + if ((fd = open_i2c_dev(i2c_priv.i2cbus)) < 0) { + return -1; + } + +#if 0 + if ((ret = set_slave_addr(fd, i2c_priv.save_addr, 0)) < 0) { + close(fd); + return -1; + } +#endif + + buffer = malloc(i2c_priv.data_len); + if (buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + ret = -ENOMEM; + goto error_out; + } + while (i2c_priv.times--) { + if ((ret = i2c_transfer(fd, &i2c_priv, 0, 2)) < 0) { + goto error_out; + } + memcpy(buffer, i2c_priv.buffer, i2c_priv.data_len); + if ((ret = i2c_transfer(fd, &i2c_priv, I2C_M_RD, 2)) < 0) { + goto error_out; + } + if ((ret = i2c_check_data(buffer, &i2c_priv)) < 0) { + i2c_priv.check_test_errors++; + } + } + printf("Check test errors = %u\r\n", i2c_priv.check_test_errors); + +error_out: + printf("\r\n******************** I2C read test End ********************\r\n\r\n"); + if (i2c_priv.buffer) { + free(i2c_priv.buffer); + } + if (buffer) { + free(buffer); + } + close(fd); + return ret; +} + +int i2c_reset_main(int argc, char **argv) +{ + printf("not support %s argc:%d, \r\n", argv[0], argc); + return 0; +} + +int pca9548_rd_main(int argc, char **argv) +{ + int i, ret, fd; + struct i2c_dev_priv i2c_priv; + + memset(&i2c_priv, 0, sizeof(struct i2c_dev_priv)); + ret = i2c_arg_check(argc, argv, &i2c_priv, 4); + if (ret < 0) { + i2c_help("pca9548_rd"); + return -1; + } + + printf("\r\n" + "********************** I2C multiplexer read test **********************\r\n"); + print_arg(&i2c_priv); + + if ((fd = open_i2c_dev(i2c_priv.i2cbus)) < 0) { + return -1; + } + +#if 0 + if ((ret = set_slave_addr(fd, i2c_priv.save_addr, 0)) < 0) { + close(fd); + return -1; + } +#endif + + while (i2c_priv.times--) { + if ((ret = i2c_transfer(fd, &i2c_priv, I2C_M_RD, 1)) < 0) { + goto error_out; + } + } + printf("Last Read: \r\n"); + /* dump data */ + for (i = 0; i < i2c_priv.data_len; i++) { + printf("%02X ", i2c_priv.buffer[i]); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } + +error_out: + printf("\r\n******************** I2C multiplexer read test End ********************\r\n\r\n"); + if (i2c_priv.buffer) { + free(i2c_priv.buffer); + } + close(fd); + return ret; +} + +int pca9548_wr_main(int argc, char **argv) +{ + int ret, fd; + struct i2c_dev_priv i2c_priv; + + memset(&i2c_priv, 0, sizeof(struct i2c_dev_priv)); + + ret = i2c_arg_check(argc, argv, &i2c_priv, 5); + if (ret < 0) { + i2c_help("pca9548_wr"); + return -1; + } + + printf("\r\n" + "********************** I2C multiplexer write test **********************\r\n"); + print_arg(&i2c_priv); + + if ((fd = open_i2c_dev(i2c_priv.i2cbus)) < 0) { + return -1; + } + +#if 0 + if ((ret = set_slave_addr(fd, i2c_priv.save_addr, 0)) < 0) { + close(fd); + return -1; + } +#endif + + while (i2c_priv.times--) { + if ((ret = i2c_transfer(fd, &i2c_priv, 0, 1)) < 0) { + goto error_out; + } + } + +error_out: + printf("\r\n******************** I2C multiplexer read test End ********************\r\n\r\n"); + if (i2c_priv.buffer) { + free(i2c_priv.buffer); + } + close(fd); + return ret; +} + +int rtc_rd_main(int argc, char **argv) +{ + int ret, fd; + struct rtc_time rtc; + int rtc_num; + char *end, filename[I2C_MAX_NAME_SIZE]; + + if (argc < 2) { + rtc_help("rtc_rd"); + } + + rtc_num = strtol(argv[1], &end, 0); + if (*end || rtc_num < 0 || rtc_num > 0xff) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_rd"); + return -EINVAL; + } + + ret = snprintf(filename, I2C_MAX_NAME_SIZE, "/dev/rtc%d", rtc_num); + filename[ret] = '\0'; + if ((fd = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "`%s': %s\n", filename, strerror(errno)); + return -1; + } + + if (ioctl(fd, RTC_RD_TIME, &rtc) < 0) { + fprintf(stderr, + "Error: get rtc error %s\n", + strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("\r\n******************** RTC read test ********************\r\n"); + + printf("Read RTC: %d-%d-%d, %d:%d:%d\n", + rtc.tm_year + 1900, rtc.tm_mon + 1, rtc.tm_mday, + rtc.tm_hour, rtc.tm_min, rtc.tm_sec); + printf("\r\n******************** RTC read test End ********************\r\n\r\n"); + + return 0; +} + +int rtc_wr_main(int argc, char **argv) +{ + int ret, fd, year; + struct rtc_time rtc; + int rtc_num; + char *end, filename[I2C_MAX_NAME_SIZE]; + + if (argc < 8) { + rtc_help("rtc_wr"); + } + + rtc_num = strtol(argv[1], &end, 0); + if (*end || rtc_num < 0 || rtc_num > 0xff) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + year = strtol(argv[2], &end, 0); + if (*end || year < 0) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + rtc.tm_year = year - 1900; + + rtc.tm_mon = strtol(argv[3], &end, 0); + if (*end || rtc.tm_mon <= 0 || rtc.tm_mon > 12) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + rtc.tm_mon = rtc.tm_mon - 1; + + rtc.tm_mday = strtol(argv[4], &end, 0); + if (*end || rtc.tm_mday < 0 || rtc.tm_mday > 31) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + rtc.tm_hour = strtol(argv[5], &end, 0); + if (*end || rtc.tm_hour < 0 || rtc.tm_hour > 23) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + rtc.tm_min = strtol(argv[6], &end, 0); + if (*end || rtc.tm_min < 0 || rtc.tm_min > 59) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + rtc.tm_sec = strtol(argv[7], &end, 0); + if (*end || rtc.tm_sec < 0 || rtc.tm_sec > 59) { + fprintf(stderr, "Error: Invalid argument!\n"); + rtc_help("rtc_wr"); + return -EINVAL; + } + + ret = snprintf(filename, I2C_MAX_NAME_SIZE, "/dev/rtc%d", rtc_num); + filename[ret] = '\0'; + if ((fd = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "`%s': %s\n", filename, strerror(errno)); + return -1; + } + + if (ioctl(fd, RTC_SET_TIME, &rtc) < 0) { + fprintf(stderr, + "Error: get rtc error %s\n", + strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("\r\n******************** RTC write test ********************\r\n"); + + printf("Set RTC: %d-%d-%d, %d:%d:%d\n", + year, rtc.tm_mon + 1, rtc.tm_mday, + rtc.tm_hour, rtc.tm_min, rtc.tm_sec); + printf("\r\n******************** RTC write test End ********************\r\n\r\n"); + + return 0; +} \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_misc.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_misc.c new file mode 100644 index 0000000000..37baa383f6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_misc.c @@ -0,0 +1,712 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void dram_help(char *name) +{ + fprintf(stderr, + "Usage: %s reg_addr [reg_data] \r\n" + " reg_addr \r\n" + " reg_data \r\n", + name); + exit(1); +} + +static void phy_help(char *name) +{ + fprintf(stderr, + "Usage: %s phy_index(dec) regnum(hex) [regval(hex)] \r\n" + " phy_index phydev index \r\n" + " regnum phydev register address \r\n" + " regval phydev register value \r\n", + name); + exit(1); +} + +static void mdio_help(char *name) +{ + fprintf(stderr, + "Usage: %s mdio_index(dec) phyaddr(hex) regnum(hex) [regval(hex)] \r\n" + " mdio_index mdiodev index \r\n" + " phyaddr phydev address \r\n" + " regnum phydev register address \r\n" + " regval phydev register value \r\n", + name); + exit(1); +} + +static int dram_arg_parse(int argc, char **argv, + u64 *reg_addr, u64 *reg_data, + int min_arg) +{ + u64 reg_addr_tmp, reg_data_tmp = 0; + char *end; + int flags = 0; + + if (argc < min_arg) { + return -EINVAL; + } + + reg_addr_tmp = strtoul(argv[flags + 1], &end, 0); + if (*end) { + fprintf(stderr, "Error: reg addr invalid!\n"); + return -EINVAL; + } + + if (argc > 2) { + reg_data_tmp = strtoul(argv[flags + 2], &end, 0); + if (*end) { + fprintf(stderr, "Error: reg data invalid!\n"); + return -EINVAL; + } + } + + *reg_addr = reg_addr_tmp; + *reg_data = reg_data_tmp; + + return 0; +} + +static int phydev_arg_parse(int argc, char **argv, + int *phy_index, u32 *regnum, u32 *regval, + int min_arg) +{ + + unsigned long index, regaddr, value; + char *end; + + if (argc < min_arg) { + return -EINVAL; + } + + index = strtoul(argv[1], &end, 0); + if (*end) { + fprintf(stderr, "Error: index invalid!\n"); + return -EINVAL; + } + + regaddr = strtoul(argv[2], &end, 16); + if (*end || regaddr > 0xffff) { + fprintf(stderr, "Error: regaddr invalid!\n"); + return -EINVAL; + } + + if (argc > 3) { + value = strtoul(argv[3], &end, 16); + if (*end) { + fprintf(stderr, "Error: reg data invalid!\n"); + return -EINVAL; + } + + *regval = (u32)value; + } + + *phy_index = (u32)index; + *regnum = (u32)regaddr; + + return 0; +} + +static int mdiodev_arg_parse(int argc, char **argv, + int *mdio_index, int *phyaddr, u32 *regnum, u32 *regval, + int min_arg) +{ + + unsigned long index, addr, regaddr, value; + char *end; + + if (argc < min_arg) { + return -EINVAL; + } + + index = strtoul(argv[1], &end, 0); + if (*end) { + fprintf(stderr, "Error: index invalid!\n"); + return -EINVAL; + } + + addr = strtoul(argv[2], &end, 16); + if (*end || addr > 0x1f) { + fprintf(stderr, "Error: phyaddr invalid!\n"); + return -EINVAL; + } + + regaddr = strtoul(argv[3], &end, 16); + if (*end || regaddr > 0xffff) { + fprintf(stderr, "Error: regaddr invalid!\n"); + return -EINVAL; + } + + if (argc > 4) { + value = strtoul(argv[4], &end, 16); + if (*end) { + fprintf(stderr, "Error: reg data invalid!\n"); + return -EINVAL; + } + + *regval = (u32)value; + } + + *mdio_index = (u32)index; + *phyaddr = (int)addr; + *regnum = (u32)regaddr; + + return 0; +} + +int reload_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int sys_info_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int mem_dump_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int cache_flush_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int reg_wr64_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + unsigned int reg_data1, reg_data2; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 3); + if (ret < 0) { + dram_help("reg_wr64"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek :%s\n", strerror(errno)); + close(fd); + return -1; + } + reg_data2 = (unsigned int)(((u64)reg_data) >> 32) & 0xFFFFFFFF; + reg_data1 = (unsigned int)reg_data & 0xFFFFFFFF; + buf[0] = (reg_data1 >> 0) & 0xFF; + buf[1] = (reg_data1 >> 8) & 0xFF; + buf[2] = (reg_data1 >> 16) & 0xFF; + buf[3] = (reg_data1 >> 24) & 0xFF; + + buf[4] = (reg_data2 >> 0) & 0xFF; + buf[5] = (reg_data2 >> 8) & 0xFF; + buf[6] = (reg_data2 >> 16) & 0xFF; + buf[7] = (reg_data2 >> 24) & 0xFF; + + if ((ret = write(fd, buf, 8)) < 0) { + fprintf(stderr, "Error: Could not write file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Write quad-word 0x%16llX to address 0x%16llX.\n\n", reg_data, reg_addr); + return 0; +} + +int reg_rd64_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + unsigned int reg_data1, reg_data2; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 2); + if (ret < 0) { + dram_help("reg_rd64"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if ((ret = read(fd, buf, 8)) < 0) { + fprintf(stderr, "Error: Could not read file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + reg_data1 = (buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24)); + reg_data2 = (buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24)); + + printf("Read quad-word from address 0x%16llX: 0x%08X%08X\n\n", reg_addr, reg_data2, reg_data1); + return 0; +} + +int reg_wr32_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + unsigned int reg_data1, reg_data2; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 3); + if (ret < 0) { + dram_help("reg_wr32"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek :%s\n", strerror(errno)); + close(fd); + return -1; + } + reg_data2 = (unsigned int)(((u64)reg_data) >> 32) & 0xFFFFFFFF; + reg_data1 = (unsigned int)reg_data & 0xFFFFFFFF; + buf[0] = (reg_data1 >> 0) & 0xFF; + buf[1] = (reg_data1 >> 8) & 0xFF; + buf[2] = (reg_data1 >> 16) & 0xFF; + buf[3] = (reg_data1 >> 24) & 0xFF; + + buf[4] = (reg_data2 >> 0) & 0xFF; + buf[5] = (reg_data2 >> 8) & 0xFF; + buf[6] = (reg_data2 >> 16) & 0xFF; + buf[7] = (reg_data2 >> 24) & 0xFF; + + if ((ret = write(fd, buf, 4)) < 0) { + fprintf(stderr, "Error: Could not write file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Write word 0x%08X to address 0x%16llX.\n\n", reg_data1, reg_addr); + return 0; +} + +int reg_rd32_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + unsigned int reg_data1; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 2); + if (ret < 0) { + dram_help("reg_rd32"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if ((ret = read(fd, buf, 4)) < 0) { + fprintf(stderr, "Error: Could not read file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + reg_data1 = (buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24)); + + printf("Read word from address 0x%16llX: 0x%08X\n\n", reg_addr, reg_data1); + return 0; +} + +int reg_wr16_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + unsigned int reg_data1, reg_data2; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 3); + if (ret < 0) { + dram_help("reg_wr16"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek :%s\n", strerror(errno)); + close(fd); + return -1; + } + reg_data2 = (unsigned int)(((u64)reg_data) >> 32) & 0xFFFFFFFF; + reg_data1 = (unsigned int)reg_data & 0xFFFFFFFF; + buf[0] = (reg_data1 >> 0) & 0xFF; + buf[1] = (reg_data1 >> 8) & 0xFF; + buf[2] = (reg_data1 >> 16) & 0xFF; + buf[3] = (reg_data1 >> 24) & 0xFF; + + buf[4] = (reg_data2 >> 0) & 0xFF; + buf[5] = (reg_data2 >> 8) & 0xFF; + buf[6] = (reg_data2 >> 16) & 0xFF; + buf[7] = (reg_data2 >> 24) & 0xFF; + + if ((ret = write(fd, buf, 2)) < 0) { + fprintf(stderr, "Error: Could not write file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Write half-word 0x%02X%02X to address 0x%16llX.\n\n", buf[1], buf[0], reg_addr); + return 0; +} + +int reg_rd16_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 2); + if (ret < 0) { + dram_help("reg_rd16"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if ((ret = read(fd, buf, 2)) < 0) { + fprintf(stderr, "Error: Could not read file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Read half-word from address 0x%16llX: 0x%02X%02X\n\n", reg_addr, buf[1], buf[0]); + return 0; +} + +int reg_wr8_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + unsigned int reg_data1, reg_data2; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 3); + if (ret < 0) { + dram_help("reg_wr8"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek :%s\n", strerror(errno)); + close(fd); + return -1; + } + reg_data2 = (unsigned int)(((u64)reg_data) >> 32) & 0xFFFFFFFF; + reg_data1 = (unsigned int)reg_data & 0xFFFFFFFF; + buf[0] = (reg_data1 >> 0) & 0xFF; + buf[1] = (reg_data1 >> 8) & 0xFF; + buf[2] = (reg_data1 >> 16) & 0xFF; + buf[3] = (reg_data1 >> 24) & 0xFF; + + buf[4] = (reg_data2 >> 0) & 0xFF; + buf[5] = (reg_data2 >> 8) & 0xFF; + buf[6] = (reg_data2 >> 16) & 0xFF; + buf[7] = (reg_data2 >> 24) & 0xFF; + + if ((ret = write(fd, buf, 1)) < 0) { + fprintf(stderr, "Error: Could not write file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Write byte 0x%02X to address 0x%16llX.\n\n", buf[0], reg_addr); + return 0; +} + +int reg_rd8_main(int argc, char **argv) +{ + u64 reg_addr, reg_data; + int fd; + long int ret; + unsigned char buf[MAX_DATA_SIZE]; + + ret = dram_arg_parse(argc, argv, ®_addr, ®_data, 2); + if (ret < 0) { + dram_help("reg_rd8"); + return -1; + } + + if ((fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + if ((ret = lseek(fd, reg_addr, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if ((ret = read(fd, buf, 1)) < 0) { + fprintf(stderr, "Error: Could not read file : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Read byte from address 0x%16llX: 0x%02X\n\n", reg_addr, buf[0]); + return 0; +} + +int phydev_list_main(int argc, char **argv) +{ + int fd; + + argc = argc; + argv = argv; + fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + (void)ioctl(fd, CMD_PHY_LIST, NULL); + + close(fd); + + return 0; +} + +int phydev_rd_main(int argc, char **argv) +{ + struct phydev_user_info phy_info; + int fd; + long int ret; + + ret = phydev_arg_parse(argc, argv, &phy_info.phy_index, &phy_info.regnum, &phy_info.regval, 3); + if (ret < 0) { + phy_help("phydev_rd"); + return -1; + } + + fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + ret = ioctl(fd, CMD_PHY_READ, &phy_info); + if (ret < 0) { + fprintf(stderr, "Error: phy read error : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Read success --- phydev%d regnum: 0x%x, value: 0x%x\n",phy_info.phy_index, phy_info.regnum, phy_info.regval); + + return 0; +} + +int phydev_wr_main(int argc, char **argv) +{ + struct phydev_user_info phy_info; + int fd; + long int ret; + + ret = phydev_arg_parse(argc, argv, &phy_info.phy_index, &phy_info.regnum, &phy_info.regval, 4); + if (ret < 0) { + phy_help("phydev_wr"); + return -1; + } + + fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + ret = ioctl(fd, CMD_PHY_WRITE, &phy_info); + if (ret < 0) { + fprintf(stderr, "Error: phy write error : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("write success --- phydev%d regnum: 0x%x, value: 0x%x\n",phy_info.phy_index, phy_info.regnum, phy_info.regval); + + return 0; +} + +int mdiodev_list_main(int argc, char **argv) +{ + int fd; + + argc = argc; + argv = argv; + fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + (void)ioctl(fd, CMD_MDIO_LIST, NULL); + + close(fd); + + return 0; +} + +int mdiodev_rd_main(int argc, char **argv) +{ + struct mdio_dev_user_info mdio_info; + int fd; + long int ret; + + ret = mdiodev_arg_parse(argc, argv, &mdio_info.mdio_index, &mdio_info.phyaddr, &mdio_info.regnum, &mdio_info.regval, 4); + if (ret < 0) { + mdio_help("mdiodev_rd"); + return -1; + } + + fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + ret = ioctl(fd, CMD_MDIO_READ, &mdio_info); + if (ret < 0) { + fprintf(stderr, "Error: mdio read error : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("Read success\n mdio_index phyaddr regnum value\n"); + printf(" %-10d %#-10x %#-10x %#-10x\n", mdio_info.mdio_index, mdio_info.phyaddr, mdio_info.regnum, mdio_info.regval); + + return 0; +} + +int mdiodev_wr_main(int argc, char **argv) +{ + struct mdio_dev_user_info mdio_info; + int fd; + long int ret; + + ret = mdiodev_arg_parse(argc, argv, &mdio_info.mdio_index, &mdio_info.phyaddr, &mdio_info.regnum, &mdio_info.regval, 5); + if (ret < 0) { + mdio_help("mdiodev_wr"); + return -1; + } + + fd = open("/dev/dram_test", O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + fprintf(stderr, "Error: Could not open file " + "/dev/dram: %s\n", strerror(errno)); + return -1; + } + + ret = ioctl(fd, CMD_MDIO_WRITE, &mdio_info); + if (ret < 0) { + fprintf(stderr, "Error: mdio write error : %s\n", strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + printf("write success\n mdio_index phyaddr regnum value\n"); + printf(" %-10d %#-10x %#-10x %#-10x\n", mdio_info.mdio_index, mdio_info.phyaddr, mdio_info.regnum, mdio_info.regval); + + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_mtdflash.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_mtdflash.c new file mode 100644 index 0000000000..c754480bad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_mtdflash.c @@ -0,0 +1,699 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void mtdflash_help(char *name) +{ + fprintf(stderr, + "Usage: %s start_addr end_addr data1 data2 [times] \r\n" + " start_addr Flash start address \r\n" + " end_addr Flash end address \r\n" + " data1 Test data1(8bit) \r\n" + " data2 Test data2(8bit) \r\n" + " [times} \r\n", + name); + exit(1); +} + +static int mtd_arg_get(int argc, char **argv, struct mtd_dev_priv *mtd_priv, int min_arg) +{ + unsigned int start_addr, end_addr, data1 = 0, data2 = 0, times = 1; + char *end; + int flags = 0; + + if (argc < min_arg) { + return -EINVAL; + } + + start_addr = strtol(argv[flags + 1], &end, 0); + if (*end) { + fprintf(stderr, "Error: start addr invalid!\n"); + return -EINVAL; + } + + end_addr = strtol(argv[flags + 2], &end, 0); + if (*end) { + fprintf(stderr, "Error: end addr invalid!\n"); + return -EINVAL; + } + + if (argc > 3) { + data1 = strtol(argv[flags + 3], &end, 0); + if (*end) { + fprintf(stderr, "Error: data1 invalid!\n"); + return -EINVAL; + } + } + + if (argc > 4) { + data2 = strtol(argv[flags + 4], &end, 0); + if (*end) { + fprintf(stderr, "Error: data2 invalid!\n"); + return -EINVAL; + } + } + + if (argc > 5) { + times = strtol(argv[flags + 5], &end, 0); + if (*end) { + fprintf(stderr, "Error: times invalid!\n"); + return -EINVAL; + } + } + + mtd_priv->start_addr = start_addr; + mtd_priv->end_addr = end_addr; + mtd_priv->data1 = data1; + mtd_priv->data2 = data2; + mtd_priv->times = times; + return 0; +} + +static void print_arg(struct mtd_dev_priv *mtd_priv) +{ + printf("Start: 0x%08X, End: 0x%08X\n", + mtd_priv->start_addr, mtd_priv->end_addr); + printf("Data1 = 0x%02X, Data2 = 0x%02X", + mtd_priv->data1, mtd_priv->data2); + + printf(", Times = %u", mtd_priv->times); + + printf("\r\n"); +} + +static int open_mtd_dev(char *test_name) +{ + FILE *fd; + int file, ret; + char buffer[MAX_BUFFER_SIZE], filename[MAX_BUFFER_SIZE], *ptr; + + if ((fd = fopen("/proc/mtd", "r")) == NULL) { + fprintf(stderr, "Error: Could not open file " + "/proc/mtd: %s\n", strerror(errno)); + return -1; + } + + while (fgets(buffer, MAX_BUFFER_SIZE, fd)) { + if ((ptr = strstr(buffer, test_name)) != NULL) { + break; + } + } + fclose(fd); + + if ((ptr = strstr(buffer, ":")) == NULL) { + return -1; + } + *ptr = '\0'; + + ret = snprintf(filename, MAX_BUFFER_SIZE, "/dev/%s", buffer); + filename[ret] = '\0'; + + printf("....................%s\r\n", filename); + + if ((file = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "`%s': %s\n", filename, strerror(errno)); + } + + return file; +} + +static int mtd_arg_check(int fd, + struct mtd_dev_priv *mtd_priv, + unsigned int *nand_erasesize) +{ + int ret; + struct mtd_info_user mtd; + + if ((ret = ioctl(fd, MEMGETINFO, &mtd)) < 0) { + perror("MEMGETINFO"); + return -1; + } + + if ((mtd.type != MTD_NANDFLASH && mtd.type != MTD_NORFLASH) || + (mtd.flags != MTD_CAP_NANDFLASH && mtd.flags != MTD_CAP_NORFLASH)) { + printf("Error, Not NandFlash or NorFlash!\r\n"); + return -1; + } + + if ((mtd_priv->start_addr & (mtd.writesize - 1)) || + (mtd_priv->end_addr & (mtd.writesize -1))) { + printf("Error, Address must be %d bytes aligned!\r\n", mtd.writesize); + return -1; + } + + if (mtd_priv->end_addr > mtd.size) { + printf("Error, Address out of test range!\r\n"); + return -1; + } + + if (mtd_priv->start_addr >= mtd_priv->end_addr) { + printf("Error, start address is higher than end address!\r\n"); + return -1; + } + + *nand_erasesize = mtd.erasesize; + + return 0; +} + +static int mtd_check_data(unsigned char *buffer, + struct mtd_dev_priv *mtd_priv, + unsigned long len) +{ + unsigned int i; + len = mtd_priv->end_addr - mtd_priv->start_addr; + for (i = 0; i < len; i++) { + if (buffer[i] != mtd_priv->buffer[i]) { + return (-1); + } + } + + return (0); +} + +int nand_wr_main(int argc, char **argv) +{ + int ret, fd; + unsigned long i, len; + unsigned int nand_erasesize; + struct mtd_dev_priv nand_priv; + struct erase_info_user erase; + + memset(&nand_priv, 0, sizeof(struct mtd_dev_priv)); + + ret = mtd_arg_get(argc, argv, &nand_priv, 5); + if (ret < 0) { + mtdflash_help("nand_wr"); + return -1; + } + + if ((fd = open_mtd_dev(NAND_TEST_PARTITION)) < 0) { + return -1; + } + + if ((ret = mtd_arg_check(fd, &nand_priv, &nand_erasesize)) < 0) { + close(fd); + return -1; + } + + len = nand_priv.end_addr - nand_priv.start_addr; + if (nand_priv.buffer == NULL) { + nand_priv.buffer = malloc(len); + if (nand_priv.buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + close(fd); + return -ENOMEM; + } + } + + printf("\r\n********************** NANDFLASH write test **********************\r\n"); + print_arg(&nand_priv); + + while (nand_priv.times--) { + erase.start = (nand_priv.start_addr / nand_erasesize) * nand_erasesize; + erase.length = ((len + nand_erasesize) / nand_erasesize) * nand_erasesize; + if ((ret = ioctl(fd, MEMERASE, &erase)) < 0) { + perror("MEMERASE"); + goto error_out; + } + if (nand_priv.times % 2) { + for (i = 0; i < len;) { + nand_priv.buffer[i++] = nand_priv.data1; + nand_priv.buffer[i++] = nand_priv.data2; + } + } else { + for (i = 0; i < len;) { + nand_priv.buffer[i++] = nand_priv.data2; + nand_priv.buffer[i++] = nand_priv.data1; + } + } + + if ((ret = lseek(fd, nand_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + + if ((ret = write(fd, nand_priv.buffer, len)) < 0) { + fprintf(stderr, "%s: write, size %ld, %d\n", __func__, len, ret); + perror("write"); + goto error_out; + } + } + +error_out: + printf("\r\n******************** NANDFLASH write test End ********************\r\n\r\n"); + close(fd); + if (nand_priv.buffer) { + free(nand_priv.buffer); + } + return ret; +} + +int nand_rd_main(int argc, char **argv) +{ + int ret, fd; + unsigned long len; + unsigned int nand_erasesize; + struct mtd_dev_priv nand_priv; + + memset(&nand_priv, 0, sizeof(struct mtd_dev_priv)); + + ret = mtd_arg_get(argc, argv, &nand_priv, 3); + if (ret < 0) { + mtdflash_help("nand_rd"); + return -1; + } + + if ((fd = open_mtd_dev(NAND_TEST_PARTITION)) < 0) { + return -1; + } + + if ((ret = mtd_arg_check(fd, &nand_priv, &nand_erasesize)) < 0) { + close(fd); + return -1; + } + + len = nand_priv.end_addr - nand_priv.start_addr; + if (nand_priv.buffer == NULL) { + nand_priv.buffer = malloc(len); + if (nand_priv.buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + close(fd); + return -ENOMEM; + } + } + + printf("\r\n********************** NANDFLASH read test **********************\r\n"); + print_arg(&nand_priv); + + while (nand_priv.times--) { + if ((ret = lseek(fd, nand_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + if ((ret = read(fd, nand_priv.buffer, len)) < 0) { + fprintf(stderr, "%s: read, size %ld, %d\n", __func__, len, ret); + perror("read"); + goto error_out; + } + } +#if 0 + printf("Last Read: \r\n"); + /* dump data */ + for (i = 0; i < len; i++) { + printf("%02X ", nand_priv.buffer[i]); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } +#endif + +error_out: + printf("\r\n******************** NANDFLASH read test End ********************\r\n\r\n"); + close(fd); + if (nand_priv.buffer) { + free(nand_priv.buffer); + } + return ret; +} + +int nand_chk_main(int argc, char **argv) +{ + int ret, fd; + unsigned long i, len; + unsigned int nand_erasesize; + struct mtd_dev_priv nand_priv; + struct erase_info_user erase; + unsigned char *buffer = NULL; + + memset(&nand_priv, 0, sizeof(struct mtd_dev_priv)); + + ret = mtd_arg_get(argc, argv, &nand_priv, 5); + if (ret < 0) { + mtdflash_help("nand_chk"); + return -1; + } + + if ((fd = open_mtd_dev(NAND_TEST_PARTITION)) < 0) { + return -1; + } + + if ((ret = mtd_arg_check(fd, &nand_priv, &nand_erasesize)) < 0) { + close(fd); + return -1; + } + + len = nand_priv.end_addr - nand_priv.start_addr; + if (nand_priv.buffer == NULL) { + nand_priv.buffer = malloc(len); + if (nand_priv.buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + ret = -ENOMEM; + goto error_out; + } + } + buffer = malloc(len); + if (buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + ret = -ENOMEM; + goto error_out; + } + memset(buffer, 0, len); + + printf("\r\n********************** NANDFLASH write test **********************\r\n"); + print_arg(&nand_priv); + + while (nand_priv.times--) { + erase.start = (nand_priv.start_addr / nand_erasesize) * nand_erasesize; + erase.length = ((len + nand_erasesize) / nand_erasesize) * nand_erasesize; + if ((ret = ioctl(fd, MEMERASE, &erase)) < 0) { + perror("MEMERASE"); + goto error_out; + } + if (nand_priv.times % 2) { + for (i = 0; i < len;) { + nand_priv.buffer[i++] = nand_priv.data1; + nand_priv.buffer[i++] = nand_priv.data2; + } + } else { + for (i = 0; i < len;) { + nand_priv.buffer[i++] = nand_priv.data2; + nand_priv.buffer[i++] = nand_priv.data1; + } + } + + if ((ret = lseek(fd, nand_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + + if ((ret = write(fd, nand_priv.buffer, len)) < 0) { + fprintf(stderr, "%s: write, size %ld, %d\n", __func__, len, ret); + perror("write"); + goto error_out; + } + + if ((ret = lseek(fd, nand_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + + if ((ret = read(fd, buffer, len)) < 0) { + fprintf(stderr, "%s: write, size %ld, %d\n", __func__, len, ret); + perror("write"); + goto error_out; + } + if ((ret = mtd_check_data(buffer, &nand_priv, len)) < 0) { + nand_priv.check_test_errors++; + } + } + +error_out: + printf("Check test errors = %u\r\n", nand_priv.check_test_errors); + printf("\r\n******************** NANDFLASH write test End ********************\r\n\r\n"); + close(fd); + if (nand_priv.buffer) { + free(nand_priv.buffer); + } + if (buffer) { + free(buffer); + } + return ret; +} + +int nor_wr_main(int argc, char **argv) +{ + int ret, fd; + unsigned long i, len; + unsigned int nor_erasesize; + struct mtd_dev_priv nor_priv; + struct erase_info_user erase; + + memset(&nor_priv, 0, sizeof(struct mtd_dev_priv)); + + ret = mtd_arg_get(argc, argv, &nor_priv, 5); + if (ret < 0) { + mtdflash_help("nor_wr"); + return -1; + } + + if ((fd = open_mtd_dev(NOR_TEST_PARTITION)) < 0) { + return -1; + } + + if ((ret = mtd_arg_check(fd, &nor_priv, &nor_erasesize)) < 0) { + close(fd); + return -1; + } + + len = nor_priv.end_addr - nor_priv.start_addr; + if (nor_priv.buffer == NULL) { + nor_priv.buffer = malloc(len); + if (nor_priv.buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + close(fd); + return -ENOMEM; + } + } + + printf("\r\n********************** NORFLASH write test **********************\r\n"); + print_arg(&nor_priv); + + while (nor_priv.times--) { + erase.start = (nor_priv.start_addr / nor_erasesize) * nor_erasesize; + erase.length = ((len + nor_erasesize) / nor_erasesize) * nor_erasesize; + if ((ret = ioctl(fd, MEMERASE, &erase)) < 0) { + perror("MEMERASE"); + goto error_out; + } + if (nor_priv.times % 2) { + for (i = 0; i < len;) { + nor_priv.buffer[i++] = nor_priv.data1; + nor_priv.buffer[i++] = nor_priv.data2; + } + } else { + for (i = 0; i < len;) { + nor_priv.buffer[i++] = nor_priv.data2; + nor_priv.buffer[i++] = nor_priv.data1; + } + } + + if ((ret = lseek(fd, nor_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + + if ((ret = write(fd, nor_priv.buffer, len)) < 0) { + fprintf(stderr, "%s: write, size %ld, %d\n", __func__, len, ret); + perror("write"); + goto error_out; + } + } + +error_out: + printf("\r\n******************** NORFLASH write test End ********************\r\n\r\n"); + close(fd); + if (nor_priv.buffer) { + free(nor_priv.buffer); + } + return ret; +} + +int nor_rd_main(int argc, char **argv) +{ + int ret, fd; + unsigned long i, len; + unsigned int nor_erasesize; + struct mtd_dev_priv nor_priv; + + memset(&nor_priv, 0, sizeof(struct mtd_dev_priv)); + + ret = mtd_arg_get(argc, argv, &nor_priv, 3); + if (ret < 0) { + mtdflash_help("nor_rd"); + return -1; + } + + if ((fd = open_mtd_dev(NOR_TEST_PARTITION)) < 0) { + return -1; + } + + if ((ret = mtd_arg_check(fd, &nor_priv, &nor_erasesize)) < 0) { + close(fd); + return -1; + } + + len = nor_priv.end_addr - nor_priv.start_addr; + if (nor_priv.buffer == NULL) { + nor_priv.buffer = malloc(len); + if (nor_priv.buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + close(fd); + return -ENOMEM; + } + } + + printf("\r\n********************** NORFLASH read test **********************\r\n"); + print_arg(&nor_priv); + + while (nor_priv.times--) { + if ((ret = lseek(fd, nor_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + if ((ret = read(fd, nor_priv.buffer, len)) < 0) { + fprintf(stderr, "%s: read, size %ld, %d\n", __func__, len, ret); + perror("read"); + goto error_out; + } + } +#if 1 + printf("Last Read: \r\n"); + /* dump data */ + for (i = 0; i < len; i++) { + printf("%02X ", nor_priv.buffer[i]); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } +#endif + +error_out: + printf("\r\n******************** NORFLASH read test End ********************\r\n\r\n"); + close(fd); + if (nor_priv.buffer) { + free(nor_priv.buffer); + } + return ret; +} + +int nor_chk_main(int argc, char **argv) +{ + int ret, fd; + unsigned long i, len; + unsigned int nor_erasesize; + struct mtd_dev_priv nor_priv; + struct erase_info_user erase; + unsigned char *buffer = NULL; + + memset(&nor_priv, 0, sizeof(struct mtd_dev_priv)); + + ret = mtd_arg_get(argc, argv, &nor_priv, 5); + if (ret < 0) { + mtdflash_help("nand_chk"); + return -1; + } + + if ((fd = open_mtd_dev(NOR_TEST_PARTITION)) < 0) { + return -1; + } + + if ((ret = mtd_arg_check(fd, &nor_priv, &nor_erasesize)) < 0) { + close(fd); + return -1; + } + + len = nor_priv.end_addr - nor_priv.start_addr; + if (nor_priv.buffer == NULL) { + nor_priv.buffer = malloc(len); + if (nor_priv.buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + ret = -ENOMEM; + goto error_out; + } + } + buffer = malloc(len); + if (buffer == NULL) { + fprintf(stderr, + "Error: Could not malloc memory %s\n", + strerror(errno)); + ret = -ENOMEM; + goto error_out; + } + memset(buffer, 0, len); + + printf("\r\n********************** NORFLASH write test **********************\r\n"); + print_arg(&nor_priv); + + while (nor_priv.times--) { + erase.start = (nor_priv.start_addr / nor_erasesize) * nor_erasesize; + erase.length = ((len + nor_erasesize) / nor_erasesize) * nor_erasesize; + if ((ret = ioctl(fd, MEMERASE, &erase)) < 0) { + perror("MEMERASE"); + goto error_out; + } + if (nor_priv.times % 2) { + for (i = 0; i < len;) { + nor_priv.buffer[i++] = nor_priv.data1; + nor_priv.buffer[i++] = nor_priv.data2; + } + } else { + for (i = 0; i < len;) { + nor_priv.buffer[i++] = nor_priv.data2; + nor_priv.buffer[i++] = nor_priv.data1; + } + } + + if ((ret = lseek(fd, nor_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + + if ((ret = write(fd, nor_priv.buffer, len)) < 0) { + fprintf(stderr, "%s: write, size %ld, %d\n", __func__, len, ret); + perror("write"); + goto error_out; + } + + if ((ret = lseek(fd, nor_priv.start_addr, SEEK_SET)) < 0) { + perror("lseek"); + goto error_out; + } + + if ((ret = read(fd, buffer, len)) < 0) { + fprintf(stderr, "%s: write, size %ld, %d\n", __func__, len, ret); + perror("write"); + goto error_out; + } + if ((ret = mtd_check_data(buffer, &nor_priv, len)) < 0) { + nor_priv.check_test_errors++; + } + } + +error_out: + printf("Check test errors = %u\r\n", nor_priv.check_test_errors); + printf("\r\n******************** NORFLASH write test End ********************\r\n\r\n"); + close(fd); + if (nor_priv.buffer) { + free(nor_priv.buffer); + } + if (buffer) { + free(buffer); + } + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_pci.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_pci.c new file mode 100644 index 0000000000..7140b80dbe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_pci.c @@ -0,0 +1,469 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void pci_help(char *name) +{ + fprintf(stderr, + "Usage: %s bus slot fn bar offset data [times] \r\n" + " bus pci bus number \r\n" + " slot pci slot number \r\n" + " fn pci device function number \r\n" + " bar pci resource bar number \r\n" + " offset pci register offset \r\n" + " data pci test data[32bit] \r\n" + " [times] \r\n", + name); + exit(1); +} + +static void pci_cfg_help(char *name) +{ + fprintf(stderr, + "Usage: %s bus slot fn offset data [times] \r\n" + " bus pci bus number \r\n" + " slot pci slot number \r\n" + " fn pci device function number \r\n" + " offset pci register offset \r\n" + " data pci test data[8bit] \r\n" + " [times] \r\n", + name); + exit(1); +} + +static int pci_arg_parse(int argc, char **argv, + struct pci_dev_priv *pci_priv, int min_arg, int is_cfg) +{ + int pcibus, slot, fn, bar = 0, offset = 0, times = 1; + unsigned long int data = 0; + char *end; + int flags = 0; + + if (argc < min_arg) { + return -EINVAL; + } + + pcibus = strtol(argv[flags + 1], &end, 0); + if (*end || pcibus < 0 || pcibus > 255) { + fprintf(stderr, "Error: pci bus number invalid!\n"); + return -EINVAL; + } + + slot = strtol(argv[flags + 2], &end, 0); + if (*end || slot < 0 || slot > 255) { + fprintf(stderr, "Error: pci slot number invalid!\n"); + return -EINVAL; + } + + fn = strtol(argv[flags + 3], &end, 0); + if (*end || fn < 0 || fn > 32) { + fprintf(stderr, "Error: pci device function number invalid!\n"); + return -EINVAL; + } + + if (!is_cfg) { + bar = strtol(argv[flags + 4], &end, 0); + if (*end || bar < 0 || bar > 12) { + fprintf(stderr, "Error: pci resource bar number invalid!\n"); + return -EINVAL; + } + flags++; + } + + offset = strtol(argv[flags + 4], &end, 0); + if (*end || offset < 0 || (offset & 0x3)) { + fprintf(stderr, "Error: pci register offset invalid!\n"); + return -EINVAL; + } + + if ((argc - flags) > 5) { + data = strtoul(argv[flags + 5], &end, 0); + if (*end) { + fprintf(stderr, "Error: data invalid!\n"); + return -EINVAL; + } + } + + if ((argc - flags) > 6) { + times = strtol(argv[flags + 6], &end, 0); + if (*end || times < 0) { + fprintf(stderr, "Error: times invalid!\n"); + return -EINVAL; + } + } + + pci_priv->pcibus = pcibus; + pci_priv->slot = slot; + pci_priv->fn = fn; + pci_priv->bar = bar; + pci_priv->offset = offset; + pci_priv->data = (unsigned int)data; + pci_priv->times = times; + return 0; +} + +static void print_arg(struct pci_dev_priv *pci_priv, int is_cfg) +{ + printf("Bus: %d, Slot: %d/%d", + pci_priv->pcibus, pci_priv->slot, pci_priv->fn); + + if (!is_cfg) { + printf(", Bar: %d", pci_priv->bar); + } + printf(", offset: 0x%X", pci_priv->offset); + + if (pci_priv->data) { + printf(", Data = 0x%08X", pci_priv->data); + } + + if (pci_priv->times) { + printf(", Times = %u", pci_priv->times); + } + + printf("\r\n"); +} + +static int open_pci_dev(struct pci_dev_priv *pci_priv, int is_cfg) +{ + int file, ret; + char filename[PCI_MAX_NAME_SIZE]; + + if (is_cfg) { + ret = snprintf(filename, PCI_MAX_NAME_SIZE, + "/sys/class/pci_bus/%04x:%02x/device/%04x:%02x:%02x.%d/config", + 0, pci_priv->pcibus, 0, pci_priv->pcibus, pci_priv->slot, pci_priv->fn); + } else { + ret = snprintf(filename, PCI_MAX_NAME_SIZE, + "/sys/class/pci_bus/%04x:%02x/device/%04x:%02x:%02x.%d/resource%d", + 0, pci_priv->pcibus, 0, pci_priv->pcibus, pci_priv->slot, pci_priv->fn, + pci_priv->bar); + } + + filename[ret] = '\0'; + if ((file = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + fprintf(stderr, "Error: Could not open file " + "`%s': %s\n", filename, strerror(errno)); + } + + printf("file;%s\r\n", filename); + return file; +} + +int pci_wr_main(int argc, char **argv) +{ + int ret, fd; + struct pci_dev_priv pci_priv; + unsigned int *ptr; + struct stat sb; + + memset(&pci_priv, 0, sizeof(struct pci_dev_priv)); + ret = pci_arg_parse(argc, argv, &pci_priv, 6, 0); + if (ret < 0) { + pci_help("pci_wr"); + return -1; + } + + if ((fd = open_pci_dev(&pci_priv, 0)) < 0) { + return -1; + } + + if ((ret = fstat(fd, &sb)) == -1) { + fprintf(stderr, "Error: Could not fstat : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if (pci_priv.offset >= sb.st_size) { + fprintf(stderr, "Error: offset is out of range\n"); + close(fd); + return -1; + } + + if ((ptr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0)) == MAP_FAILED) { + fprintf(stderr, "Error: Could not mmap : %s or resource is IO\n", strerror(errno)); + close(fd); + return -1; + } + + printf("\r\n" + "********************** PCI write test **********************\r\n"); + print_arg(&pci_priv, 1); + + while (pci_priv.times--) { + *((volatile unsigned int *)(ptr + pci_priv.offset / sizeof(unsigned int))) = pci_priv.data; + } + printf("Write 0x%08X to offset 0x%08X.\n\n", pci_priv.data, pci_priv.offset); + + printf("\r\n******************** PCI write test End ********************\r\n\r\n"); + munmap(ptr, sb.st_size); + close(fd); + return ret; +} + +int pci_rd_main(int argc, char **argv) +{ + int ret, fd; + struct pci_dev_priv pci_priv; + unsigned int data; + unsigned int *ptr; + struct stat sb; + + memset(&pci_priv, 0, sizeof(struct pci_dev_priv)); + ret = pci_arg_parse(argc, argv, &pci_priv, 6, 0); + if (ret < 0) { + pci_help("pci_rd"); + return -1; + } + + if ((fd = open_pci_dev(&pci_priv, 0)) < 0) { + return -1; + } + + if ((ret = fstat(fd, &sb)) == -1) { + fprintf(stderr, "Error: Could not fstat : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if (pci_priv.offset >= sb.st_size) { + fprintf(stderr, "Error: offset is out of range\n"); + close(fd); + return -1; + } + + if ((ptr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0)) == MAP_FAILED) { + fprintf(stderr, "Error: Could not mmap : %s or resource is IO\n", strerror(errno)); + close(fd); + return -1; + } + + printf("\r\n" + "********************** PCI read test **********************\r\n"); + print_arg(&pci_priv, 1); + + data = 0; + while (pci_priv.times--) { + data = *((volatile unsigned int *)(ptr + pci_priv.offset / sizeof(unsigned int))); + } + printf("Last Read: Data = 0x%08X\n", data); + + printf("\r\n******************** PCI read test End ********************\r\n\r\n"); + munmap(ptr, sb.st_size); + close(fd); + return ret; +} + +int pci_cfg_wr_main(int argc, char **argv) +{ + int ret, fd; + struct pci_dev_priv pci_priv; + char buf[16]; + + memset(&pci_priv, 0, sizeof(struct pci_dev_priv)); + ret = pci_arg_parse(argc, argv, &pci_priv, 6, 1); + if (ret < 0) { + pci_cfg_help("pci_cfg_wr"); + return -1; + } + + if ((fd = open_pci_dev(&pci_priv, 1)) < 0) { + return -1; + } + + printf("\r\n" + "********************** PCI config write test **********************\r\n"); + print_arg(&pci_priv, 1); + + while (pci_priv.times--) { + if ((ret = lseek(fd, pci_priv.offset, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek : %s\n", strerror(errno)); + goto error_out; + } + + buf[0] = (pci_priv.data >> 0) & 0xFF; + buf[1] = (pci_priv.data >> 8) & 0xFF; + buf[2] = (pci_priv.data >> 16) & 0xFF; + buf[3] = (pci_priv.data >> 24) & 0xFF; + if ((ret = write(fd, buf, sizeof(unsigned int))) < 0) { + fprintf(stderr, "Error: Could not read file : %s\n", strerror(errno)); + goto error_out; + } + } + printf("Write 0x%08X to offset 0x%08X.\n\n", pci_priv.data, pci_priv.offset); + +error_out: + printf("\r\n******************** PCI config write test End ********************\r\n\r\n"); + close(fd); + return ret; +} + +int pci_cfg_rd_main(int argc, char **argv) +{ + int ret, fd; + struct pci_dev_priv pci_priv; + unsigned int data; + + memset(&pci_priv, 0, sizeof(struct pci_dev_priv)); + ret = pci_arg_parse(argc, argv, &pci_priv, 5, 1); + if (ret < 0) { + pci_cfg_help("pci_cfg_rd"); + return -1; + } + + if ((fd = open_pci_dev(&pci_priv, 1)) < 0) { + return -1; + } + + printf("\r\n" + "********************** PCI config read test **********************\r\n"); + print_arg(&pci_priv, 1); + + while (pci_priv.times--) { + if ((ret = lseek(fd, pci_priv.offset, SEEK_SET)) < 0) { + fprintf(stderr, "Error: Could not llseek : %s\n", strerror(errno)); + goto error_out; + } + + if ((ret = read(fd, &data, sizeof(unsigned int))) < 0) { + fprintf(stderr, "Error: Could not read file : %s\n", strerror(errno)); + goto error_out; + } + } + printf("Last Read: Data = 0x%08X\n", data); + +error_out: + printf("\r\n******************** PCI config read test End ********************\r\n\r\n"); + close(fd); + return ret; +} + +int pci_chk_main(int argc, char **argv) +{ + int ret, fd; + struct pci_dev_priv pci_priv; + unsigned int data; + unsigned int *ptr; + struct stat sb; + + memset(&pci_priv, 0, sizeof(struct pci_dev_priv)); + ret = pci_arg_parse(argc, argv, &pci_priv, 6, 0); + if (ret < 0) { + pci_help("pci_wr"); + return -1; + } + + if ((fd = open_pci_dev(&pci_priv, 0)) < 0) { + return -1; + } + + if ((ret = fstat(fd, &sb)) == -1) { + fprintf(stderr, "Error: Could not fstat : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if (pci_priv.offset >= sb.st_size) { + fprintf(stderr, "Error: offset is out of range\n"); + close(fd); + return -1; + } + + if ((ptr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0)) == MAP_FAILED) { + fprintf(stderr, "Error: Could not mmap : %s or resource is IO\n", strerror(errno)); + close(fd); + return -1; + } + + printf("\r\n" + "********************** PCI Check test **********************\r\n"); + print_arg(&pci_priv, 1); + + while (pci_priv.times--) { + *((volatile unsigned int *)(ptr + pci_priv.offset / sizeof(unsigned int))) = pci_priv.data; + data = *((volatile unsigned int *)(ptr + pci_priv.offset / sizeof(unsigned int))); + if (pci_priv.data != data) { + pci_priv.check_test_errors++; + } + } + printf("Check test errors = %u\r\n", pci_priv.check_test_errors); + + printf("\r\n******************** PCI Check test End ********************\r\n\r\n"); + munmap(ptr, sb.st_size); + close(fd); + return ret; +} + +int pci_dump_main(int argc, char **argv) +{ + int ret, fd, i; + struct pci_dev_priv pci_priv; + unsigned int *ptr; + unsigned char *p; + struct stat sb; + + memset(&pci_priv, 0, sizeof(struct pci_dev_priv)); + ret = pci_arg_parse(argc, argv, &pci_priv, 6, 0); + if (ret < 0) { + pci_help("pci_dump"); + return -1; + } + + if ((fd = open_pci_dev(&pci_priv, 0)) < 0) { + return -1; + } + + if ((ret = fstat(fd, &sb)) == -1) { + fprintf(stderr, "Error: Could not fstat : %s\n", strerror(errno)); + close(fd); + return -1; + } + + if (pci_priv.offset >= sb.st_size) { + fprintf(stderr, "Error: offset is out of range\n"); + close(fd); + return -1; + } + + if ((ptr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0)) == MAP_FAILED) { + fprintf(stderr, "Error: Could not mmap : %s or resource is IO\n", strerror(errno)); + close(fd); + return -1; + } + + printf("\r\n" + "********************** PCI dump test **********************\r\n"); + print_arg(&pci_priv, 1); + + printf(" Address | 0 1 2 3 4 5 6 7 8 9 A B C D E F\r\n"); + while (pci_priv.times--) { + p = (unsigned char *)ptr; + for (i = 0; i < pci_priv.offset; i++, p++) { + if (i % 16 == 0) { + printf("%08X | ", (unsigned int)((unsigned long)p - (unsigned long)ptr)); + } + printf("%02X ", *p); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } + } + + printf("\r\n******************** PCI dump test End ********************\r\n\r\n"); + munmap(ptr, sb.st_size); + close(fd); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_test.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_test.c new file mode 100644 index 0000000000..1cfaa22505 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_test.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct hw_applet hw_applets[] = { + /* I2C */ + HWTEST_APPLET(i2c_wr, "i2c_wr slave_addr offset data [data_len] [times] [offset_len]"), + HWTEST_APPLET(i2c_rd, "i2c_rd slave_addr offset [data_len] [times] [offset_len]"), + HWTEST_APPLET(i2c_chk, "i2c_chk slave_addr offset data [data_len] [times]"), + HWTEST_APPLET(i2c_reset, "not support"), + HWTEST_APPLET(pca9548_rd, "pca9548 i2c_bus slave_addr offset data [data_len] [times]"), + HWTEST_APPLET(pca9548_wr, "pca9548 i2c_bus slave_addr offset data [data_len] [times]"), + HWTEST_APPLET(rtc_rd, "rtc_rd rtc year month day hour minute second"), + HWTEST_APPLET(rtc_wr, "rtc_wr rtc year month day hour minute second"), + /* NorFlash */ + HWTEST_APPLET(nor_wr, "nor_wr start_addr end_addr data1 data2 [times]"), + HWTEST_APPLET(nor_rd, "nor_rd start_addr end_addr data1 data2 [times]"), + HWTEST_APPLET(nor_chk, "nor_chk start_addr end_addr data1 data2 [times]"), + /* NandFlash */ + HWTEST_APPLET(nand_wr, "nand_wr start_addr end_addr data1 data2 [times]"), + HWTEST_APPLET(nand_rd, "nand_rd start_addr end_addr data1 data2 [times]"), + HWTEST_APPLET(nand_chk, "nand_chk start_addr end_addr data1 data2 [times]"), + /* Dram */ + HWTEST_APPLET(dram_wr, "not support"), + HWTEST_APPLET(dram_rd, "not support"), + HWTEST_APPLET(dram_chk, "not support"), + HWTEST_APPLET(dram_test, "dram_test [simple|complex some|complex all]"), + /* PCI */ + HWTEST_APPLET(pci_wr, "pci_wr bus slot fn bar offset data [times]"), + HWTEST_APPLET(pci_rd, "pci_rd bus slot fn bar offset data [times]"), + HWTEST_APPLET(pci_dump, "pci_dump bus slot fn bar offset data [times]"), + HWTEST_APPLET(pci_cfg_wr, "pci_cfg_wr bus slot fn offset data [times]"), + HWTEST_APPLET(pci_cfg_rd, "pci_cfg_rd bus slot fn offset data [times]"), + HWTEST_APPLET(pci_chk, "pci_chk bus slot fn bar offset data [times]"), + /* USB */ + HWTEST_APPLET(usb_write, "not support"), + HWTEST_APPLET(usb_read, "not support"), + HWTEST_APPLET(usb_check, "not support"), + /* eMMC */ + HWTEST_APPLET(emmc_test, "emmc_test"), + /* MISC */ + HWTEST_APPLET(reload, "not support"), + HWTEST_APPLET(sys_info, "not support"), + HWTEST_APPLET(mem_dump, "not support"), + HWTEST_APPLET(cache_flush, "not support"), + HWTEST_APPLET(reg_wr64, "reg_wr64 reg_addr [reg_data]"), + HWTEST_APPLET(reg_rd64, "reg_rd64 reg_addr [reg_data]"), + HWTEST_APPLET(reg_wr32, "reg_wr32 reg_addr [reg_data]"), + HWTEST_APPLET(reg_rd32, "reg_rd32 reg_addr [reg_data]"), + HWTEST_APPLET(reg_wr16, "reg_wr16 reg_addr [reg_data]"), + HWTEST_APPLET(reg_rd16, "reg_rd16 reg_addr [reg_data]"), + HWTEST_APPLET(reg_wr8, "reg_wr8 reg_addr [reg_data]"), + HWTEST_APPLET(reg_rd8, "reg_rd8 reg_addr [reg_data]"), + /* phydev */ + HWTEST_APPLET(phydev_list, "phydev_list"), + HWTEST_APPLET(phydev_rd, "phydev_rd phy_index reg_addr"), + HWTEST_APPLET(phydev_wr, "phydev_wr phy_index reg_addr reg_data"), + /* mdio bus */ + HWTEST_APPLET(mdiodev_list, "mdiodev_list"), + HWTEST_APPLET(mdiodev_rd, "mdiodev_rd mdio_index phyaddr reg_addr"), + HWTEST_APPLET(mdiodev_wr, "mdiodev_wr mdio_index phyaddr reg_addr reg_data"), + /* hw help */ + HWTEST_APPLET(hw_help, "help") +}; + +static size_t hw_num_applets = (sizeof(hw_applets) / sizeof(struct hw_applet)); + +static void error_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + fflush(stdout); + vfprintf(stderr, s, p); + va_end(p); + fputs("\r\n", stderr); + exit(1); +} + +static int applet_name_compare (const void *x, const void *y) +{ + const char *name = x; + const struct hw_applet *applet = y; + + return strcmp (name, applet->name); +} + +struct hw_applet *find_applet_by_name (const char *name) +{ + return lfind(name, hw_applets, &hw_num_applets, sizeof(struct hw_applet), + applet_name_compare); +} + +static void show_usage () +{ + size_t i; + for (i = 0; i < hw_num_applets; i++) { + printf("%-20s\t\t\t%s\r\n", hw_applets[i].name, hw_applets[i].help); + } + exit (0); +} + +int hw_help_main(int argc, char **argv) +{ + argc = argc; + argv = argv; + show_usage(); + return 0; +} + +static void run_applet_by_name (const char *name, int argc, char **argv) +{ + struct hw_applet *applet_using; + + if (argc == 0) { + show_usage (); + } + + if(!strncmp(name, "hw_test", 7)) { + run_applet_by_name(argv[1], argc - 1, argv + 1); + } + + applet_using = find_applet_by_name(name); + if(applet_using) { + if(argc == 2 && !strcmp(argv[1], "--help")) { + show_usage (); + } + exit ((*(applet_using->main)) (argc, argv)); + } +} + +int main(int argc, char **argv) +{ + char *applet_name, *s; + applet_name = argv[0]; + + for (s = applet_name; *s; ) { + if (*(s++) == '/') { + applet_name = s; + } + } + + run_applet_by_name(applet_name, argc, argv); + error_msg_and_die("%s: applet not found", applet_name); + return 0; +} \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_usb.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_usb.c new file mode 100644 index 0000000000..7f33c38396 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/hw_usb.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int usb_write_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int usb_read_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} + +int usb_check_main(int argc, char **argv) +{ + printf("%s, %d, %d, %s\r\n", __FUNCTION__, __LINE__, argc, argv[0]); + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/fac_common.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/fac_common.h new file mode 100644 index 0000000000..2fb6ee417a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/fac_common.h @@ -0,0 +1,32 @@ +#ifndef _FAC_AC_COMMON_H_ +#define _FAC_AC_COMMON_H_ + +#define FAC_TEST_OK 0 +#define FAC_TEST_FAIL 1 +#define GRTD_LOG_DEBUG 2 +#define GRTD_LOG_ERR 1 +#define GRTD_LOG_NONE 0 +#define FAC_MEM_SIZE_BUF_LEN 1024 /* Save the length of the memory size */ +#define FAC_MEM_TEST_SIZE (1024*1024*32) /* Memory test size */ +#define FAC_MEM_AUTOTEST_SIZE (1024*1024*2048ULL) /* Memory test size */ +#define FAC_MEM_MAX_SIZE (1024*1024*4096ULL) /* Memory test size */ +#define FAC_MEM_TEST_PAGESIZE 8192 /* pagesize for memory tests */ +#define FAC_FILENAME_LEN 128 /* Device file name length */ +#define FAC_FILE_LINE_LEN 128 /* The length of each line of the file */ +#define FAC_FILE_SIZE_LEN 16 /* Length that represents size in a file */ +#define GRTD_SDRAM_ECC_ERR 1 /* ECC check error */ +#define GRTD_SDRAM_WR_ERR 2 /* Read/write erro */ +#define GRTD_SDRAM_GET_MEM_SIZE_ERR 3 /* Failed to obtain the memory capacity */ +#define GRTD_SDRAM_UNKNOW_ERR 4 /* Other unknown errors */ + +extern int platform_fac_dbg; +/* The production test module tracks debugging information */ +#define FAC_LOG_DBG(dbg, fmt, arg...) \ + do { \ + if (dbg <= platform_fac_dbg) { \ + printf("[FACTORY <%s>:<%d>] " fmt, \ + __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +#endif /* _FAC_AC_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/ft_ddr_test.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/ft_ddr_test.h new file mode 100644 index 0000000000..1381b4386c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/ft_ddr_test.h @@ -0,0 +1,104 @@ +#ifndef __FT_DDR_TEST_H__ +#define __FT_DDR_TEST_H__ + +#include + +#define FT_DDR_SUCCESS 0 +#define FT_DDR_ERR 1 +#define SPINSZ 0x800000 +#define MOD_SZ 20 +#define MAX_MEM_SEGMENTS 32 +#define BLK_SIZE_NUM_MAX 9 +#define BADRAM_MAXPATNS 10 +#define LOW_TEST_ADR 0x00002000 /* Final adrs for test code */ +#define HIGH_TEST_ADR 0x00180000 /* Relocation base address */ +#define USE_DMA +#define TETS_TOTAL_NUMBER 14 + +#define FT_SHOW_PROCESS +#ifdef FT_SHOW_PROCESS +#define FT_DDR_SHOW() do {printf("."); fflush(stdout);}while (0) +#define FT_DDR_SHOW_END() do {printf("\n"); fflush(stdout);}while (0) +#else +#define FT_DDR_SHOW() do {}while (0) +#define FT_DDR_SHOW_END() do {}while (0) +#endif + +typedef struct data_seg_s { + int seq; + ulong start_addr; + ulong end_addr; + ulong size; + int use_dma; +} data_seg_t; + +struct pair { + ulong adr; + ulong mask; +}; + +struct mmap { + ulong pbase_addr; + unsigned int *start; + unsigned int *end; +}; + +struct pmap { + ulong start; + ulong end; +}; + +/* Define common variables accross relocations of memtest86 */ +struct vars { + int test; + int pass; + unsigned long *eadr; + unsigned long exor; + int msg_line; + int ecount; + int ecc_ecount; + int msegs; /* The number of memory areas to test */ + int testsel; + int scroll_start; + int rdtsc; + int pae; + int pass_ticks; + int total_ticks; + int pptr; + int tptr; + struct pmap pmap[MAX_MEM_SEGMENTS]; + struct mmap map[MAX_MEM_SEGMENTS]; + ulong plim_lower; + ulong plim_upper; + ulong clks_msec; + ulong starth; + ulong startl; + ulong snaph; + ulong snapl; + int printmode; + int numpatn; + struct pair patn [BADRAM_MAXPATNS]; + ulong test_pages; + ulong selected_pages; + ulong reserved_pages; +}; + +struct tseq { + short cache; + short pat; + short iter; + short ticks; + short errors; + char *msg; +}; + +typedef struct ft_ddr_test_interface_s { + int always; /* Copy machine test 0: No test 1: test */ + int (*ddr_test)(char *desc); + char name[64]; +} ft_ddr_test_interface_t; + +extern void ft_ddr_test_init(void *start, size_t size); +extern ft_ddr_test_interface_t ft_ddr_test_fun[TETS_TOTAL_NUMBER]; + +#endif /* __FT_DDR_TEST_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/hw_dram.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/hw_dram.h new file mode 100644 index 0000000000..0d4e5349ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_dram/hw_dram.h @@ -0,0 +1,9 @@ +#ifndef _HW_DRAM_H +#define _HW_DRAM_H + +extern int dram_wr_main(int argc, char **argv); +extern int dram_rd_main(int argc, char **argv); +extern int dram_chk_main(int argc, char **argv); +extern int dram_test_main(int argc, char **argv); + +#endif /* _HW_DRAM_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_emmc/hw_emmc.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_emmc/hw_emmc.h new file mode 100644 index 0000000000..40b19ba4b7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_emmc/hw_emmc.h @@ -0,0 +1,6 @@ +#ifndef _HW_EMMC_H +#define _HW_EMMC_H + +extern int emmc_test_main(int argc, char **argv); + +#endif /* _HW_EMMC_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/hw_i2c.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/hw_i2c.h new file mode 100644 index 0000000000..62a31c6ae1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/hw_i2c.h @@ -0,0 +1,27 @@ +#ifndef _HW_I2C_H +#define _HW_I2C_H + +struct i2c_dev_priv { + int i2cbus; + int save_addr; + int offset; + int offset_len; + unsigned char data; + int data_len; + int times; + unsigned int check_test_errors; + unsigned char *buffer; +}; + +#define I2C_MAX_NAME_SIZE 128 + +extern int i2c_wr_main(int argc, char **argv); +extern int i2c_rd_main(int argc, char **argv); +extern int i2c_chk_main(int argc, char **argv); +extern int i2c_reset_main(int argc, char **argv); +extern int pca9548_rd_main(int argc, char **argv); +extern int pca9548_wr_main(int argc, char **argv); +extern int rtc_rd_main(int argc, char **argv); +extern int rtc_wr_main(int argc, char **argv); + +#endif /* _HW_I2C_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c-dev.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c-dev.h new file mode 100644 index 0000000000..2585944c77 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c-dev.h @@ -0,0 +1,69 @@ +/* + i2c-dev.h - i2c-bus driver, char device interface + + Copyright (C) 1995-97 Simon G. Vogl + Copyright (C) 1998-99 Frodo Looijaard + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. +*/ + +#ifndef _LINUX_I2C_DEV_H +#define _LINUX_I2C_DEV_H + +#include + +/* /dev/i2c-X ioctl commands. The ioctl's parameter is always an + * unsigned long, except for: + * - I2C_FUNCS, takes pointer to an unsigned long + * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data + * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data + */ +#define I2C_RETRIES 0x0701 /* number of times a device address should + be polled when not acknowledging */ +#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */ + +/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses + * are NOT supported! (due to code brokenness) + */ +#define I2C_SLAVE 0x0703 /* Use this slave address */ +#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it + is already in use by a driver! */ +#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ + +#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */ + +#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */ + +#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ +#define I2C_SMBUS 0x0720 /* SMBus transfer */ + +/* This is the structure as used in the I2C_SMBUS ioctl call */ +struct i2c_smbus_ioctl_data { + __u8 read_write; + __u8 command; + __u32 size; + union i2c_smbus_data *data; +}; + +/* This is the structure as used in the I2C_RDWR ioctl call */ +struct i2c_rdwr_ioctl_data { + struct i2c_msg *msgs; /* pointers to i2c_msgs */ + __u32 nmsgs; /* number of i2c_msgs */ +}; + +#define I2C_RDRW_IOCTL_MAX_MSGS 42 + +#endif /* _LINUX_I2C_DEV_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c.h new file mode 100644 index 0000000000..4498740ddc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/i2c.h @@ -0,0 +1,734 @@ +/* ------------------------------------------------------------------------- */ +/* */ +/* i2c.h - definitions for the i2c-bus interface */ +/* */ +/* ------------------------------------------------------------------------- */ +/* Copyright (C) 1995-2000 Simon G. Vogl + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* ------------------------------------------------------------------------- */ + +#ifndef _LINUX_I2C_H +#define _LINUX_I2C_H + +#include +#ifdef __KERNEL__ +#include +#include +#include +#include /* for struct device */ +#include /* for completion */ +#include + +extern struct bus_type i2c_bus_type; +extern struct device_type i2c_adapter_type; + +/* --- General options ------------------------------------------------ */ + +struct i2c_msg; +struct i2c_algorithm; +struct i2c_adapter; +struct i2c_client; +struct i2c_driver; +union i2c_smbus_data; +struct i2c_board_info; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +/* + * The master routines are the ones normally used to transmit data to devices + * on a bus (or read from them). Apart from two basic transfer functions to + * transmit one message at a time, a more complex version can be used to + * transmit an arbitrary number of messages without interruption. + */ +extern int i2c_master_send(struct i2c_client *client, const char *buf, + int count); +extern int i2c_master_recv(struct i2c_client *client, char *buf, int count); + +/* Transfer num messages. + */ +extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); + +/* This is the very generalized SMBus access routine. You probably do not + want to use this, though; one of the functions below may be much easier, + and probably just as fast. + Note that we use i2c_adapter here, because you do not need a specific + smbus adapter to call this function. */ +extern s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data); + +/* Now follow the 'nice' access routines. These also document the calling + conventions of i2c_smbus_xfer. */ + +extern s32 i2c_smbus_read_byte(struct i2c_client *client); +extern s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value); +extern s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command); +extern s32 i2c_smbus_write_byte_data(struct i2c_client *client, + u8 command, u8 value); +extern s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command); +extern s32 i2c_smbus_write_word_data(struct i2c_client *client, + u8 command, u16 value); +/* Returns the number of read bytes */ +extern s32 i2c_smbus_read_block_data(struct i2c_client *client, + u8 command, u8 *values); +extern s32 i2c_smbus_write_block_data(struct i2c_client *client, + u8 command, u8 length, const u8 *values); +/* Returns the number of read bytes */ +extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, + u8 command, u8 length, u8 *values); +extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, + u8 command, u8 length, + const u8 *values); +#endif /* I2C */ + +/** + * struct i2c_driver - represent an I2C device driver + * @class: What kind of i2c device we instantiate (for detect) + * @attach_adapter: Callback for bus addition (for legacy drivers) + * @detach_adapter: Callback for bus removal (for legacy drivers) + * @probe: Callback for device binding + * @remove: Callback for device unbinding + * @shutdown: Callback for device shutdown + * @suspend: Callback for device suspend + * @resume: Callback for device resume + * @command: Callback for bus-wide signaling (optional) + * @driver: Device driver model driver + * @id_table: List of I2C devices supported by this driver + * @detect: Callback for device detection + * @address_data: The I2C addresses to probe, ignore or force (for detect) + * @clients: List of detected clients we created (for i2c-core use only) + * + * The driver.owner field should be set to the module owner of this driver. + * The driver.name field should be set to the name of this driver. + * + * For automatic device detection, both @detect and @address_data must + * be defined. @class should also be set, otherwise only devices forced + * with module parameters will be created. The detect function must + * fill at least the name field of the i2c_board_info structure it is + * handed upon successful detection, and possibly also the flags field. + * + * If @detect is missing, the driver will still work fine for enumerated + * devices. Detected devices simply won't be supported. This is expected + * for the many I2C/SMBus devices which can't be detected reliably, and + * the ones which can always be enumerated in practice. + * + * The i2c_client structure which is handed to the @detect callback is + * not a real i2c_client. It is initialized just enough so that you can + * call i2c_smbus_read_byte_data and friends on it. Don't do anything + * else with it. In particular, calling dev_dbg and friends on it is + * not allowed. + */ +struct i2c_driver { + unsigned int class; + + /* Notifies the driver that a new bus has appeared or is about to be + * removed. You should avoid using this if you can, it will probably + * be removed in a near future. + */ + int (*attach_adapter)(struct i2c_adapter *); + int (*detach_adapter)(struct i2c_adapter *); + + /* Standard driver model interfaces */ + int (*probe)(struct i2c_client *, const struct i2c_device_id *); + int (*remove)(struct i2c_client *); + + /* driver model interfaces that don't relate to enumeration */ + void (*shutdown)(struct i2c_client *); + int (*suspend)(struct i2c_client *, pm_message_t mesg); + int (*resume)(struct i2c_client *); + + /* a ioctl like command that can be used to perform specific functions + * with the device. + */ + int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); + + struct device_driver driver; + const struct i2c_device_id *id_table; + + /* Device detection callback for automatic device creation */ + int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); + const struct i2c_client_address_data *address_data; + struct list_head clients; +}; +#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) + +/** + * struct i2c_client - represent an I2C slave device + * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address; + * I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking + * @addr: Address used on the I2C bus connected to the parent adapter. + * @name: Indicates the type of the device, usually a chip name that's + * generic enough to hide second-sourcing and compatible revisions. + * @adapter: manages the bus segment hosting this I2C device + * @driver: device's driver, hence pointer to access routines + * @dev: Driver model device node for the slave. + * @irq: indicates the IRQ generated by this device (if any) + * @detected: member of an i2c_driver.clients list or i2c-core's + * userspace_devices list + * + * An i2c_client identifies a single device (i.e. chip) connected to an + * i2c bus. The behaviour exposed to Linux is defined by the driver + * managing the device. + */ +struct i2c_client { + unsigned short flags; /* div., see below */ + unsigned short addr; /* chip address - NOTE: 7bit */ + /* addresses are stored in the */ + /* _LOWER_ 7 bits */ + char name[I2C_NAME_SIZE]; + struct i2c_adapter *adapter; /* the adapter we sit on */ + struct i2c_driver *driver; /* and our access routines */ + struct device dev; /* the device structure */ + int irq; /* irq issued by device */ + struct list_head detected; +}; +#define to_i2c_client(d) container_of(d, struct i2c_client, dev) + +extern struct i2c_client *i2c_verify_client(struct device *dev); + +static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) +{ + struct device * const dev = container_of(kobj, struct device, kobj); + return to_i2c_client(dev); +} + +static inline void *i2c_get_clientdata(const struct i2c_client *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +/** + * struct i2c_board_info - template for device creation + * @type: chip type, to initialize i2c_client.name + * @flags: to initialize i2c_client.flags + * @addr: stored in i2c_client.addr + * @platform_data: stored in i2c_client.dev.platform_data + * @archdata: copied into i2c_client.dev.archdata + * @irq: stored in i2c_client.irq + * + * I2C doesn't actually support hardware probing, although controllers and + * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's + * a device at a given address. Drivers commonly need more information than + * that, such as chip type, configuration, associated IRQ, and so on. + * + * i2c_board_info is used to build tables of information listing I2C devices + * that are present. This information is used to grow the driver model tree. + * For mainboards this is done statically using i2c_register_board_info(); + * bus numbers identify adapters that aren't yet available. For add-on boards, + * i2c_new_device() does this dynamically with the adapter already known. + */ +struct i2c_board_info { + char type[I2C_NAME_SIZE]; + unsigned short flags; + unsigned short addr; + void *platform_data; + struct dev_archdata *archdata; + struct device_node *of_node; + int irq; +}; + +/** + * I2C_BOARD_INFO - macro used to list an i2c device and its address + * @dev_type: identifies the device type + * @dev_addr: the device's address on the bus. + * + * This macro initializes essential fields of a struct i2c_board_info, + * declaring what has been provided on a particular board. Optional + * fields (such as associated irq, or device-specific platform_data) + * are provided using conventional syntax. + */ +#define I2C_BOARD_INFO(dev_type, dev_addr) \ + .type = dev_type, .addr = (dev_addr) + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +/* Add-on boards should register/unregister their devices; e.g. a board + * with integrated I2C, a config eeprom, sensors, and a codec that's + * used in conjunction with the primary hardware. + */ +extern struct i2c_client * +i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); + +/* If you don't know the exact address of an I2C device, use this variant + * instead, which can probe for device presence in a list of possible + * addresses. + */ +extern struct i2c_client * +i2c_new_probed_device(struct i2c_adapter *adap, + struct i2c_board_info *info, + unsigned short const *addr_list); + +/* For devices that use several addresses, use i2c_new_dummy() to make + * client handles for the extra addresses. + */ +extern struct i2c_client * +i2c_new_dummy(struct i2c_adapter *adap, u16 address); + +extern void i2c_unregister_device(struct i2c_client *); +#endif /* I2C */ + +/* Mainboard arch_initcall() code should register all its I2C devices. + * This is done at arch_initcall time, before declaring any i2c adapters. + * Modules for add-on boards must use other calls. + */ +#ifdef CONFIG_I2C_BOARDINFO +extern int +i2c_register_board_info(int busnum, struct i2c_board_info const *info, + unsigned n); +#else +static inline int +i2c_register_board_info(int busnum, struct i2c_board_info const *info, + unsigned n) +{ + return 0; +} +#endif /* I2C_BOARDINFO */ + +/* + * The following structs are for those who like to implement new bus drivers: + * i2c_algorithm is the interface to a class of hardware solutions which can + * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 + * to name two of the most common. + */ +struct i2c_algorithm { + /* If an adapter algorithm can't do I2C-level access, set master_xfer + to NULL. If an adapter algorithm can do SMBus access, set + smbus_xfer. If set to NULL, the SMBus protocol is simulated + using common I2C messages */ + /* master_xfer should return the number of messages successfully + processed, or a negative value on error */ + int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); + int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data); + + /* To determine what the adapter supports */ + u32 (*functionality) (struct i2c_adapter *); +}; + +/* + * i2c_adapter is the structure used to identify a physical i2c bus along + * with the access algorithms necessary to access it. + */ +struct i2c_adapter { + struct module *owner; + unsigned int id; + unsigned int class; /* classes to allow probing for */ + const struct i2c_algorithm *algo; /* the algorithm to access the bus */ + void *algo_data; + + /* data fields that are valid for all devices */ + u8 level; /* nesting level for lockdep */ + struct mutex bus_lock; + + int timeout; /* in jiffies */ + int retries; + struct device dev; /* the adapter device */ + + int nr; + char name[48]; + struct completion dev_released; +}; +#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) + +static inline void *i2c_get_adapdata(const struct i2c_adapter *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +static inline int i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter) +{ + return adapter->dev.parent != NULL + && adapter->dev.parent->bus == &i2c_bus_type + && adapter->dev.parent->type == &i2c_adapter_type; +} + +/* Adapter locking functions, exported for shared pin cases */ +void i2c_lock_adapter(struct i2c_adapter *); +void i2c_unlock_adapter(struct i2c_adapter *); + +/*flags for the client struct: */ +#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ +#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ + /* Must equal I2C_M_TEN below */ +#define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */ + +/* i2c adapter classes (bitmask) */ +#define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ +#define I2C_CLASS_TV_ANALOG (1<<1) /* bttv + friends */ +#define I2C_CLASS_TV_DIGITAL (1<<2) /* dvb cards */ +#define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ +#define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */ + +/* i2c_client_address_data is the struct for holding default client + * addresses for a driver and for the parameters supplied on the + * command line + */ +struct i2c_client_address_data { + const unsigned short *normal_i2c; + const unsigned short *probe; + const unsigned short *ignore; + const unsigned short * const *forces; +}; + +/* Internal numbers to terminate lists */ +#define I2C_CLIENT_END 0xfffeU + +/* The numbers to use to set I2C bus address */ +#define ANY_I2C_BUS 0xffff + +/* Construct an I2C_CLIENT_END-terminated array of i2c addresses */ +#define I2C_ADDRS(addr, addrs...) \ + ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END }) + +/* ----- functions exported by i2c.o */ + +/* administration... + */ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +extern int i2c_add_adapter(struct i2c_adapter *); +extern int i2c_del_adapter(struct i2c_adapter *); +extern int i2c_add_numbered_adapter(struct i2c_adapter *); + +extern int i2c_register_driver(struct module *, struct i2c_driver *); +extern void i2c_del_driver(struct i2c_driver *); + +static inline int i2c_add_driver(struct i2c_driver *driver) +{ + return i2c_register_driver(THIS_MODULE, driver); +} + +extern struct i2c_client *i2c_use_client(struct i2c_client *client); +extern void i2c_release_client(struct i2c_client *client); + +/* call the i2c_client->command() of all attached clients with + * the given arguments */ +extern void i2c_clients_command(struct i2c_adapter *adap, + unsigned int cmd, void *arg); + +extern struct i2c_adapter *i2c_get_adapter(int id); +extern void i2c_put_adapter(struct i2c_adapter *adap); + +/* Return the functionality mask */ +static inline u32 i2c_get_functionality(struct i2c_adapter *adap) +{ + return adap->algo->functionality(adap); +} + +/* Return 1 if adapter supports everything we need, 0 if not. */ +static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func) +{ + return (func & i2c_get_functionality(adap)) == func; +} + +/* Return the adapter number for a specific adapter */ +static inline int i2c_adapter_id(struct i2c_adapter *adap) +{ + return adap->nr; +} +#endif /* I2C */ +#endif /* __KERNEL__ */ + +/** + * struct i2c_msg - an I2C transaction segment beginning with START + * @addr: Slave address, either seven or ten bits. When this is a ten + * bit address, I2C_M_TEN must be set in @flags and the adapter + * must support I2C_FUNC_10BIT_ADDR. + * @flags: I2C_M_RD is handled by all adapters. No other flags may be + * provided unless the adapter exported the relevant I2C_FUNC_* + * flags through i2c_check_functionality(). + * @len: Number of data bytes in @buf being read from or written to the + * I2C slave address. For read transactions where I2C_M_RECV_LEN + * is set, the caller guarantees that this buffer can hold up to + * 32 bytes in addition to the initial length byte sent by the + * slave (plus, if used, the SMBus PEC); and this value will be + * incremented by the number of block data bytes received. + * @buf: The buffer into which data is read, or from which it's written. + * + * An i2c_msg is the low level representation of one segment of an I2C + * transaction. It is visible to drivers in the @i2c_transfer() procedure, + * to userspace from i2c-dev, and to I2C adapter drivers through the + * @i2c_adapter.@master_xfer() method. + * + * Except when I2C "protocol mangling" is used, all I2C adapters implement + * the standard rules for I2C transactions. Each transaction begins with a + * START. That is followed by the slave address, and a bit encoding read + * versus write. Then follow all the data bytes, possibly including a byte + * with SMBus PEC. The transfer terminates with a NAK, or when all those + * bytes have been transferred and ACKed. If this is the last message in a + * group, it is followed by a STOP. Otherwise it is followed by the next + * @i2c_msg transaction segment, beginning with a (repeated) START. + * + * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then + * passing certain @flags may have changed those standard protocol behaviors. + * Those flags are only for use with broken/nonconforming slaves, and with + * adapters which are known to support the specific mangling options they + * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR). + */ +struct i2c_msg { + __u16 addr; /* slave address */ + __u16 flags; +#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ +#define I2C_M_RD 0x0001 /* read data, from slave to master */ +#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ + __u16 len; /* msg length */ + __u8 *buf; /* pointer to msg data */ +}; + +/* To determine what functionality is present */ + +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */ +#define I2C_FUNC_SMBUS_PEC 0x00000008 +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_QUICK 0x00010000 +#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ + +#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE) +#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA) +#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA) +#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) +#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) + +#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_I2C_BLOCK | \ + I2C_FUNC_SMBUS_PEC) + +/* + * Data for SMBus Messages + */ +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +union i2c_smbus_data { + __u8 byte; + __u16 word; + __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ + /* and one more for user-space compatibility */ +}; + +/* i2c_smbus_xfer read or write markers */ +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +/* SMBus transaction types (size parameter in the above functions) + Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 8 + +#ifdef __KERNEL__ + +/* These defines are used for probing i2c client addresses */ +/* The length of the option lists */ +#define I2C_CLIENT_MAX_OPTS 48 + +/* Default fill of many variables */ +#define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END} + +/* I2C_CLIENT_MODULE_PARM creates a module parameter, and puts it in the + module header */ + +#define I2C_CLIENT_MODULE_PARM(var,desc) \ + static unsigned short var[I2C_CLIENT_MAX_OPTS] = I2C_CLIENT_DEFAULTS; \ + static unsigned int var##_num; \ + module_param_array(var, short, &var##_num, 0); \ + MODULE_PARM_DESC(var, desc) + +#define I2C_CLIENT_MODULE_PARM_FORCE(name) \ +I2C_CLIENT_MODULE_PARM(force_##name, \ + "List of adapter,address pairs which are " \ + "unquestionably assumed to contain a `" \ + # name "' chip") + +#define I2C_CLIENT_INSMOD_COMMON \ +I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \ + "additionally"); \ +I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ + "scan"); \ +static const struct i2c_client_address_data addr_data = { \ + .normal_i2c = normal_i2c, \ + .probe = probe, \ + .ignore = ignore, \ + .forces = forces, \ +} + +#define I2C_CLIENT_FORCE_TEXT \ + "List of adapter,address pairs to boldly assume to be present" + +/* These are the ones you want to use in your own drivers. Pick the one + which matches the number of devices the driver differenciates between. */ +#define I2C_CLIENT_INSMOD \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +static const unsigned short * const forces[] = { force, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_1(chip1) \ +enum chips { any_chip, chip1 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_2(chip1, chip2) \ +enum chips { any_chip, chip1, chip2 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ +enum chips { any_chip, chip1, chip2, chip3 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ +enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, NULL}; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ +enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ +enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, force_##chip6, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ +enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ + chip7 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, force_##chip6, \ + force_##chip7, NULL }; \ +I2C_CLIENT_INSMOD_COMMON + +#define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ +enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ + chip7, chip8 }; \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ +I2C_CLIENT_MODULE_PARM_FORCE(chip8); \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, force_##chip6, \ + force_##chip7, force_##chip8, NULL }; \ +I2C_CLIENT_INSMOD_COMMON +#endif /* __KERNEL__ */ +#endif /* _LINUX_I2C_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/rtc.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/rtc.h new file mode 100644 index 0000000000..1c2d08d690 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_i2c/rtc.h @@ -0,0 +1,100 @@ +/* + * Generic RTC interface. + * This version contains the part of the user interface to the Real Time Clock + * service. It is used with both the legacy mc146818 and also EFI + * Struct rtc_time and first 12 ioctl by Paul Gortmaker, 1996 - separated out + * from to this file for 2.4 kernels. + * + * Copyright (C) 1999 Hewlett-Packard Co. + * Copyright (C) 1999 Stephane Eranian + */ +#ifndef _LINUX_RTC_H_ +#define _LINUX_RTC_H_ + +/* + * The struct used to pass data via the following ioctl. Similar to the + * struct tm in , but it needs to be here so that the kernel + * source is self contained, allowing cross-compiles, etc. etc. + */ + +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +/* + * This data structure is inspired by the EFI (v0.92) wakeup + * alarm API. + */ +struct rtc_wkalrm { + unsigned char enabled; /* 0 = alarm disabled, 1 = alarm enabled */ + unsigned char pending; /* 0 = alarm not pending, 1 = alarm pending */ + struct rtc_time time; /* time the alarm is set to */ +}; + +/* + * Data structure to control PLL correction some better RTC feature + * pll_value is used to get or set current value of correction, + * the rest of the struct is used to query HW capabilities. + * This is modeled after the RTC used in Q40/Q60 computers but + * should be sufficiently flexible for other devices + * + * +ve pll_value means clock will run faster by + * pll_value*pll_posmult/pll_clock + * -ve pll_value means clock will run slower by + * pll_value*pll_negmult/pll_clock + */ + +struct rtc_pll_info { + int pll_ctrl; /* placeholder for fancier control */ + int pll_value; /* get/set correction value */ + int pll_max; /* max +ve (faster) adjustment value */ + int pll_min; /* max -ve (slower) adjustment value */ + int pll_posmult; /* factor for +ve correction */ + int pll_negmult; /* factor for -ve correction */ + long pll_clock; /* base PLL frequency */ +}; + +/* + * ioctl calls that are permitted to the /dev/rtc interface, if + * any of the RTC drivers are enabled. + */ + +#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */ +#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */ +#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */ +#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */ +#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */ +#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */ +#define RTC_WIE_ON _IO('p', 0x0f) /* Watchdog int. enable on */ +#define RTC_WIE_OFF _IO('p', 0x10) /* ... off */ + +#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */ +#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */ +#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */ +#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */ +#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */ +#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */ +#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */ +#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */ + +#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/ +#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/ + +#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ +#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ + +/* interrupt flags */ +#define RTC_IRQF 0x80 /* any of the following is active */ +#define RTC_PF 0x40 +#define RTC_AF 0x20 +#define RTC_UF 0x10 + +#endif /* _LINUX_RTC_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/dram_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/dram_driver.h new file mode 100644 index 0000000000..eaa34bfa5c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/dram_driver.h @@ -0,0 +1,28 @@ +#ifndef _LINUX_DRAM_DRIVER_H +#define _LINUX_DRAM_DRIVER_H + +#include +typedef unsigned int u32; + +struct phydev_user_info { + int phy_index; /* Indicates which phydev to operate on */ + u32 regnum; /* Register address */ + u32 regval; /* Register value */ +}; + +#define CMD_PHY_LIST _IOR('P', 0, struct phydev_user_info) +#define CMD_PHY_READ _IOR('P', 1, struct phydev_user_info) +#define CMD_PHY_WRITE _IOR('P', 2, struct phydev_user_info) + +struct mdio_dev_user_info { + int mdio_index; /* Indicates which mdio dev to operate on */ + int phyaddr; /* phy device address */ + u32 regnum; /* Register address */ + u32 regval; /* Register value */ +}; + +#define CMD_MDIO_LIST _IOR('M', 0, struct mdio_dev_user_info) +#define CMD_MDIO_READ _IOR('M', 1, struct mdio_dev_user_info) +#define CMD_MDIO_WRITE _IOR('M', 2, struct mdio_dev_user_info) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/hw_misc.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/hw_misc.h new file mode 100644 index 0000000000..ebbe912069 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_misc/hw_misc.h @@ -0,0 +1,26 @@ +#ifndef _HW_MISC_H +#define _HW_MISC_H + +typedef unsigned long long u64; +#define MAX_DATA_SIZE 16 + +extern int reload_main(int argc, char **argv); +extern int sys_info_main(int argc, char **argv); +extern int mem_dump_main(int argc, char **argv); +extern int cache_flush_main(int argc, char **argv); +extern int reg_wr64_main(int argc, char **argv); +extern int reg_rd64_main(int argc, char **argv); +extern int reg_wr32_main(int argc, char **argv); +extern int reg_rd32_main(int argc, char **argv); +extern int reg_wr16_main(int argc, char **argv); +extern int reg_rd16_main(int argc, char **argv); +extern int reg_wr8_main(int argc, char **argv); +extern int reg_rd8_main(int argc, char **argv); +extern int phydev_list_main(int argc, char **argv); +extern int phydev_rd_main(int argc, char **argv); +extern int phydev_wr_main(int argc, char **argv); +extern int mdiodev_list_main(int argc, char **argv); +extern int mdiodev_rd_main(int argc, char **argv); +extern int mdiodev_wr_main(int argc, char **argv); + +#endif /* _HW_MISC_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/hw_mtdflash.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/hw_mtdflash.h new file mode 100644 index 0000000000..2d5f7414cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/hw_mtdflash.h @@ -0,0 +1,25 @@ +#ifndef _HW_NANDFLASH_H +#define _HW_NANDFLASH_H + +struct mtd_dev_priv { + unsigned int start_addr; + unsigned int end_addr; + unsigned char data1; + unsigned char data2; + int times; + unsigned int check_test_errors; + unsigned char *buffer; +}; + +#define MAX_BUFFER_SIZE 128 +#define NAND_TEST_PARTITION "factory_test1" +#define NOR_TEST_PARTITION "factory_test0" + +extern int nand_wr_main(int argc, char **argv); +extern int nand_rd_main(int argc, char **argv); +extern int nand_chk_main(int argc, char **argv); +extern int nor_wr_main(int argc, char **argv); +extern int nor_rd_main(int argc, char **argv); +extern int nor_chk_main(int argc, char **argv); + +#endif /* _HW_NANDFLASH_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/mtd-abi.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/mtd-abi.h new file mode 100644 index 0000000000..afd0022396 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_mtd/mtd-abi.h @@ -0,0 +1,199 @@ +/* + * Portions of MTD ABI definition which are shared by kernel and user space + */ + +#ifndef __MTD_ABI_H__ +#define __MTD_ABI_H__ + +#include + +struct erase_info_user { + __u32 start; + __u32 length; +}; + +struct erase_info_user64 { + __u64 start; + __u64 length; +}; + +struct mtd_oob_buf { + __u32 start; + __u32 length; + unsigned char *ptr; +}; + +struct mtd_oob_buf64 { + __u64 start; + __u32 pad; + __u32 length; + __u64 usr_ptr; +}; + +/** + * struct mtd_write_req - data structure for requesting a write operation + * + * @start: start address + * @len: length of data buffer + * @ooblen: length of OOB buffer + * @usr_data: user-provided data buffer + * @usr_oob: user-provided OOB buffer + * @mode: MTD mode (see "MTD operation modes") + * @padding: reserved, must be set to 0 + * + * This structure supports ioctl(MEMWRITE) operations, allowing data and/or OOB + * writes in various modes. To write to OOB-only, set @usr_data == NULL, and to + * write data-only, set @usr_oob == NULL. However, setting both @usr_data and + * @usr_oob to NULL is not allowed. + */ +struct mtd_write_req { + __u64 start; + __u64 len; + __u64 ooblen; + __u64 usr_data; + __u64 usr_oob; + __u8 mode; + __u8 padding[7]; +}; + +#define MTD_ABSENT 0 +#define MTD_RAM 1 +#define MTD_ROM 2 +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_DATAFLASH 6 +#define MTD_UBIVOLUME 7 + +#define MTD_WRITEABLE 0x400 /* Device is writeable */ +#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ +#define MTD_NO_ERASE 0x1000 /* No erase necessary */ +#define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset */ + +// Some common devices / combinations of capabilities +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) +#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#define MTD_CAP_NANDFLASH (MTD_WRITEABLE) + +/* ECC byte placement */ +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default + +/* OTP mode selection */ +#define MTD_OTP_OFF 0 +#define MTD_OTP_FACTORY 1 +#define MTD_OTP_USER 2 + +struct mtd_info_user { + __u8 type; + __u32 flags; + __u32 size; // Total size of the MTD + __u32 erasesize; + __u32 writesize; + __u32 oobsize; // Amount of OOB data per block (e.g. 16) + /* The below two fields are obsolete and broken, do not use them + * (TODO: remove at some point) */ + __u32 ecctype; + __u32 eccsize; +}; + +struct region_info_user { + __u32 offset; /* At which this region starts, + * from the beginning of the MTD */ + __u32 erasesize; /* For this region */ + __u32 numblocks; /* Number of blocks in this region */ + __u32 regionindex; +}; + +struct otp_info { + __u32 start; + __u32 length; + __u32 locked; +}; + +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +#define MEMERASE _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +#define MEMGETREGIONCOUNT _IOR('M', 7, int) +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) +#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) +#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) +#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t) +#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) +#define OTPSELECT _IOR('M', 13, int) +#define OTPGETREGIONCOUNT _IOW('M', 14, int) +#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) +#define OTPLOCK _IOR('M', 16, struct otp_info) +#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) +#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) +#define MTDFILEMODE _IO('M', 19) +#define MEMERASE64 _IOW('M', 20, struct erase_info_user64) +#define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64) +#define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64) +/* Check if chip is locked (for MTD that supports it) */ +#define MEMISLOCKED _IOR('M', 23, struct erase_info_user) +/* + * Most generic write interface; can write in-band and/or out-of-band in various + * modes (see "struct mtd_write_req") + */ +#define MEMWRITE _IOWR('M', 24, struct mtd_write_req) +/* + * Obsolete legacy interface. Keep it in order not to break userspace + * interfaces + */ +struct nand_oobinfo { + __u32 useecc; + __u32 eccbytes; + __u32 oobfree[8][2]; + __u32 eccpos[32]; +}; + +struct nand_oobfree { + __u32 offset; + __u32 length; +}; + +#define MTD_MAX_OOBFREE_ENTRIES 8 +/* + * ECC layout control structure. Exported to userspace for + * diagnosis and to allow creation of raw images + */ +struct nand_ecclayout { + __u32 eccbytes; + __u32 eccpos[64]; + __u32 oobavail; + struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; +}; + +/** + * struct mtd_ecc_stats - error correction stats + * + * @corrected: number of corrected bits + * @failed: number of uncorrectable errors + * @badblocks: number of bad blocks in this partition + * @bbtblocks: number of blocks reserved for bad block tables + */ +struct mtd_ecc_stats { + __u32 corrected; + __u32 failed; + __u32 badblocks; + __u32 bbtblocks; +}; + +/* + * Read/write file modes for access to MTD + */ +enum mtd_file_modes { + MTD_MODE_NORMAL = MTD_OTP_OFF, + MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY, + MTD_MODE_OTP_USER = MTD_OTP_USER, + MTD_MODE_RAW, +}; + +#endif /* __MTD_ABI_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_pci/hw_pci.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_pci/hw_pci.h new file mode 100644 index 0000000000..27a2ff15b6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_pci/hw_pci.h @@ -0,0 +1,24 @@ +#ifndef _HW_PCI_H +#define _HW_PCI_H + +struct pci_dev_priv { + int pcibus; + int slot; + int fn; + int bar; + int offset; + unsigned int data; + int times; + unsigned int check_test_errors; +}; + +#define PCI_MAX_NAME_SIZE 256 + +extern int pci_wr_main(int argc, char **argv); +extern int pci_rd_main(int argc, char **argv); +extern int pci_dump_main(int argc, char **argv); +extern int pci_cfg_wr_main(int argc, char **argv); +extern int pci_cfg_rd_main(int argc, char **argv); +extern int pci_chk_main(int argc, char **argv); + +#endif /* _HW_PCI_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_test.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_test.h new file mode 100644 index 0000000000..97378e7663 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_test.h @@ -0,0 +1,14 @@ +#ifndef _HW_TEST_H +#define _HW_TEST_H + +struct hw_applet { + const char *name; + const char *help; + int (*main) (int argc, char **argv); +}; + +#define HWTEST_APPLET(a, b) {#a, b, a##_main} + +extern int hw_help_main(int argc, char **argv); + +#endif /* _HW_TEST_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_usb/hw_usb.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_usb/hw_usb.h new file mode 100644 index 0000000000..8666fca923 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_app/include/hw_usb/hw_usb.h @@ -0,0 +1,8 @@ +#ifndef _HW_USB_H +#define _HW_USB_H + +extern int usb_write_main(int argc, char **argv); +extern int usb_read_main(int argc, char **argv); +extern int usb_check_main(int argc, char **argv); + +#endif /* _HW_USB_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/Makefile new file mode 100644 index 0000000000..975987f87f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/Makefile @@ -0,0 +1,17 @@ +PWD = $(shell pwd) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +KVERSION ?= $(shell uname -r) +KERNEL_SRC ?= /lib/modules/$(KVERSION) + +obj-m += hw_test.o + +all : + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(common_module_dir) ]; then mkdir -p $(common_module_dir) ;fi + cp -p $(PWD)/*.ko $(common_module_dir) + +clean : + rm -f ${PWD}/*.o ${PWD}/*.ko ${PWD}/*.mod.c ${PWD}/.*.cmd ${PWD}/.*.o.d + rm -f ${PWD}/Module.markers ${PWD}/Module.symvers ${PWD}/modules.order + rm -rf ${PWD}/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.c b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.c new file mode 100644 index 0000000000..35e7bde743 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.c @@ -0,0 +1,728 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hw_test.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0) +extern const struct bus_type mdio_bus_type; +typedef const struct class *mdio_bus_class_t; +#define mdio_class_find_device(_class, _start, _data, _match) \ + class_find_device((struct class *)(_class), (_start), (_data), (_match)) +#else +extern struct bus_type mdio_bus_type; +typedef struct class *mdio_bus_class_t; +#define mdio_class_find_device(_class, _start, _data, _match) \ + class_find_device((_class), (_start), (_data), (_match)) +#endif + +#ifndef MII_ADDR_C45 +#define MII_ADDR_C45 (1U << 30) +#endif + +struct board_mdio_dev { + struct list_head list; + struct mii_bus *mdio_bus; + int mdio_index; +}; + +struct board_phy_dev { + struct list_head list; + struct phy_device *phydev; + int phy_index; +}; + +static LIST_HEAD(mdio_dev_list); /* All mdio devices are managed through a linked list */ +static LIST_HEAD(phydev_list); /* All phy devices are managed through a linked list */ +static mdio_bus_class_t class_mdio_bus = NULL; /* The address used to temporarily store the mdio_bus_class global in the kernel */ +static dev_t dram_devno; +static struct cdev dram_cdev; +static struct class *dram_class; +static struct device *dram_device; + +#define PRINT_BUF_SIZE (256) +#define INVALID_PHY_ADDR (0xFF) +#define MAX_MDIO_DEVICE_NUMS (1000) +#define MAX_PHY_DEVICE_NUMS (1000) +#define DRAM_DEV_NAME "dram_test" +#define DRAM_CLASS_NAME "hw_test" + +#define dram_debug(fmt, ...) \ + printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) + +static ssize_t dram_dev_read (struct file *file, char __user *buf, size_t count, + loff_t *offset) +{ + u8 value8; + u16 value16; + u32 value32; + u64 value64; + + if (file->private_data != NULL) { + return -EINVAL; + } + + file->private_data = ioremap(file->f_pos, count); + + if (!file->private_data) { + pr_notice("%s, %d\r\n", __FUNCTION__, __LINE__); + return -ENODEV; + } + + rmb(); + switch (count) { + case 1: + value8 = readb(file->private_data); + if (copy_to_user(buf, &value8, sizeof(u8))) { + return -EFAULT; + } + break; + case 2: + value16 = readw(file->private_data); + if (copy_to_user(buf, &value16, sizeof(u16))) { + return -EFAULT; + } + break; + case 4: + value32 = readl(file->private_data); + if (copy_to_user(buf, &value32, sizeof(u32))) { + return -EFAULT; + } + break; + case 8: +#ifdef CONFIG_64BIT + value64 = readq(file->private_data); + if (copy_to_user(buf, &value64, sizeof(u64))) { + return -EFAULT; + } +#else + return -EOPNOTSUPP; +#endif + break; + default: + return -EINVAL; + } + + iounmap(file->private_data); + file->private_data = NULL; + return count; + +} + +static ssize_t dram_dev_write (struct file *file, const char __user *buf, size_t count, + loff_t *offset) +{ + u8 value8; + u16 value16; + u32 value32; + u64 value64; + + if (file->private_data != NULL) { + return -EINVAL; + } + + file->private_data = ioremap(file->f_pos, count); + + if (!file->private_data) { + pr_err("%s, %d\r\n", __FUNCTION__, __LINE__); + return -ENODEV; + } + + switch (count) { + case 1: + if (copy_from_user(&value8, buf, sizeof(u8))) { + return -EFAULT; + } + writeb(value8, file->private_data); + break; + case 2: + if (copy_from_user(&value16, buf, sizeof(u16))) { + return -EFAULT; + } + writew(value16, file->private_data); + break; + case 4: + if (copy_from_user(&value32, buf, sizeof(u32))) { + return -EFAULT; + } + writel(value32, file->private_data); + break; + case 8: +#ifdef CONFIG_64BIT + if (copy_from_user(&value64, buf, sizeof(u64))) { + return -EFAULT; + } + writeq(value64, file->private_data); +#else + return -EOPNOTSUPP; +#endif + break; + default: + return -EINVAL; + } + + wmb(); + iounmap(file->private_data); + file->private_data = NULL; + return count; +} + +static loff_t dram_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret; + + switch (origin) { + case 0: + file->f_pos = offset; + ret = file->f_pos; + break; + case 1: + file->f_pos += offset; + ret = file->f_pos; + break; + default: + ret = -EINVAL; + } + return ret; +} + +static int temp_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) +{ + return 0; +} + +static int temp_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value) +{ + return 0; +} + +static int init_class_mdio_bus(void) +{ + struct mii_bus *bus; + int err = 0; + + bus = mdiobus_alloc(); + + bus->name = "temp_mdio_bus"; + snprintf(bus->id, MII_BUS_ID_SIZE, "temp_mdio_bus0"); + bus->read = temp_mdiobus_read; + bus->write = temp_mdiobus_write; + + err = mdiobus_register(bus); + if (err) { + printk(KERN_ERR "temp mdio bus register fail\n"); + return -1; + } + + class_mdio_bus = bus->dev.class; + mdiobus_unregister(bus); + + return 0; +} + +static int mdio_match_success(struct device *dev, const void * data) +{ + /* Returns a non-0 number, which guarantees that the match succeeds.*/ + return 1; +} + +/* Traverse the bus class, find all the mdio devs, and attach the found mdio devs to the linked list for management.*/ +static int add_all_mdio_devices_to_list(void) +{ + struct device *dev, *dev_start = NULL; + struct board_mdio_dev *mdio_dev = NULL; + int i = 0; + mdio_bus_class_t bus_class = class_mdio_bus; + + for (i = 0; i < MAX_MDIO_DEVICE_NUMS; i++) { + dev = mdio_class_find_device(bus_class, dev_start, NULL, mdio_match_success); + if (dev != NULL) { + mdio_dev = kzalloc(sizeof(struct board_mdio_dev), GFP_KERNEL); + if (mdio_dev == NULL) { + printk(KERN_ERR "%s: alloc fail\n", __func__); + return -EFAULT; + } + + mdio_dev->mdio_index = i; + mdio_dev->mdio_bus = to_mii_bus(dev); + list_add_tail(&mdio_dev->list, &mdio_dev_list); + + dev_start = dev; + } else { + break; + } + } + + printk(KERN_INFO "mdio dev numbers = %d\n", i); + + return 0; +} + +/* Remove the attached mdio dev from the linked list.*/ +static void delete_all_mdio_devices_from_list(void) +{ + struct list_head *n, *pos; + struct board_mdio_dev *mdio_dev; + + list_for_each_safe(pos, n, &mdio_dev_list) { + list_del(pos); + mdio_dev = list_entry(pos, struct board_mdio_dev, list); + kfree(mdio_dev); + } + + return; +} + +/* Lists information about all mdio devices */ +static void list_all_mdio_devices_info(void) +{ + struct board_mdio_dev *mdio_dev; + unsigned char phyaddr[PHY_MAX_ADDR]; + int i = 0, j = 0; + int phydev_num = 0; + char buf[PRINT_BUF_SIZE]; + int len = 0; + + printk(KERN_INFO "all the mdio devs info:\n"); + printk(KERN_INFO "index busid name phy_num phyaddr \n"); + list_for_each_entry(mdio_dev, &mdio_dev_list, list) { + i = 0; + j = 0; + phydev_num = 0; + memset(phyaddr, INVALID_PHY_ADDR, sizeof(phyaddr)); + memset(buf, 0, sizeof(buf)); + + for (i = 0; i < PHY_MAX_ADDR; i++) { + if (mdio_dev->mdio_bus->mdio_map[i]) { + phydev_num++; + phyaddr[j] = (unsigned char)i; + j++; + } + } + + len = snprintf(buf, sizeof(buf), " %-10d %-20s %-20s %-10d ", mdio_dev->mdio_index, + mdio_dev->mdio_bus->id, mdio_dev->mdio_bus->name, phydev_num); + + for (i = 0; i < PHY_MAX_ADDR; i++) { + if (phyaddr[i] == INVALID_PHY_ADDR) { + break; + } + + len += snprintf(&buf[len], sizeof(buf) - len, " %#x", phyaddr[i]); + } + + printk(KERN_INFO "%s\n", buf); + } + + return; +} + +/* Find the corresponding mdio according to the mdio dev index */ +static struct mii_bus *get_mdio_dev_according_to_index(int mdio_index) +{ + struct board_mdio_dev *mdio_dev; + list_for_each_entry(mdio_dev, &mdio_dev_list, list) { + if (mdio_dev->mdio_index == mdio_index) { + return mdio_dev->mdio_bus; + } + } + + printk(KERN_ERR "no exist the mdio dev it's mdio_index = %d, please exec cmd [hw_test.bin mdiodev_list] to view mdiodev info\n", + mdio_index); + + return NULL; +} + +static int board_mdio_read(int mdio_index, int phyaddr, u32 regnum) +{ + struct mii_bus *bus; + int reg_val; + int devad; + + bus = get_mdio_dev_according_to_index(mdio_index); + if (bus == NULL) { + return -1; + } + + if ((regnum & MII_ADDR_C45)) { + devad = (regnum >> 16) & 0x1F; + regnum = regnum & 0xFFFF; + reg_val = mdiobus_c45_read(bus, phyaddr, devad, regnum); + } else { + reg_val = mdiobus_read(bus, phyaddr, regnum); + } + + return reg_val; +} + +static int board_mdio_write(int mdio_index, int phyaddr, u32 regnum, u16 val) +{ + struct mii_bus *bus; + int ret; + int devad; + + bus = get_mdio_dev_according_to_index(mdio_index); + if (bus == NULL) { + return -1; + } + + if ((regnum & MII_ADDR_C45)) { + devad = (regnum >> 16) & 0x1F; + regnum = regnum & 0xFFFF; + ret = mdiobus_c45_write(bus, phyaddr, devad, regnum, val); + } else { + ret = mdiobus_write(bus, phyaddr, regnum, val); + } + + return ret; +} + +static int phy_match_success(struct device *dev, const void * data) +{ + /* Returns a non-0 number, which guarantees that the match succeeds.*/ + return 1; +} + +/* Traverse the mdio bus, find all the phydev, and manage the found phydev by attaching it to the linked list.*/ +static int add_all_phydevs_to_list(void) +{ + struct device *dev, *dev_start = NULL; + struct board_phy_dev *board_phydev = NULL; + int i = 0; + + for (i = 0; i < MAX_PHY_DEVICE_NUMS; i++) { + dev = bus_find_device(&mdio_bus_type, dev_start, NULL, phy_match_success); + if (dev != NULL) { + board_phydev = kzalloc(sizeof(struct board_phy_dev), GFP_KERNEL); + if (board_phydev == NULL) { + printk(KERN_ERR "%s: alloc fail\n", __func__); + return -EFAULT; + } + + board_phydev->phy_index = i; + board_phydev->phydev = to_phy_device(dev); + list_add_tail(&board_phydev->list, &phydev_list); + + dev_start = dev; + } else { + break; + } + } + + printk(KERN_INFO "phydev num = %d\n", i); + + return 0; +} + +/* Removes the attached phydev from the linked list.*/ +static void delete_all_phydevs_from_list(void) +{ + struct list_head *n, *pos; + struct board_phy_dev *board_phydev; + + list_for_each_safe(pos, n, &phydev_list) { + list_del(pos); + board_phydev = list_entry(pos, struct board_phy_dev, list); + kfree(board_phydev); + } + + return; +} + +/* Lists information about all phy devices */ +static void list_all_phydevs_info(void) +{ + struct board_phy_dev *board_phydev; + + printk(KERN_INFO "all the phydevs info:\n"); + printk(KERN_INFO "index phyaddr phyId phydev_name\n"); + list_for_each_entry(board_phydev, &phydev_list, list) { + printk(KERN_INFO " %-10d %#-10x %#-10x %-20s\n", board_phydev->phy_index, board_phydev->phydev->mdio.addr,\ + board_phydev->phydev->phy_id, dev_name(&board_phydev->phydev->mdio.dev)); + } + + return; +} + +/* Find the corresponding phydev based on the phy index */ +static struct phy_device *get_phy_dev_according_to_index(int phy_index) +{ + struct board_phy_dev *board_phydev; + list_for_each_entry(board_phydev, &phydev_list, list) { + if (board_phydev->phy_index == phy_index) { + return board_phydev->phydev; + } + } + + printk(KERN_ERR "no exist the phydev it's phy_index = %d, please exec cmd [hw_test.bin phydev_list] to view phydev info\n", phy_index); + + return NULL; +} + +/* Read regnum, the phydev register whose phy index is phy_index.*/ +static int board_phy_read(int phy_index, u32 regnum) +{ + struct phy_device *phydev; + int reg_val; + + phydev = get_phy_dev_according_to_index(phy_index); + if (phydev == NULL) { + return -1; + } + + reg_val = phy_read(phydev, regnum); + + return reg_val; +} + +/* Write the register value val to the phydev register regnum whose phy index is phy_index.*/ +static int board_phy_write(int phy_index, u32 regnum, u16 val) +{ + struct phy_device *phydev; + int ret; + + phydev = get_phy_dev_according_to_index(phy_index); + if (phydev == NULL) { + return -1; + } + + ret = phy_write(phydev, regnum, val); + + return ret; +} + +/* The ioctl. Implement phydev enumeration and read and write */ +static long dram_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int ret = 0; + struct phydev_user_info phy_user_info; + struct mdio_dev_user_info mdio_user_info; + + switch (cmd) { + case CMD_PHY_LIST: + list_all_phydevs_info(); + break; + + case CMD_PHY_READ: + if (copy_from_user(&phy_user_info, argp, sizeof(struct phydev_user_info))) + return -EFAULT; + + ret = board_phy_read(phy_user_info.phy_index, phy_user_info.regnum); + if (ret < 0) { + return -EFAULT; + } + + phy_user_info.regval = (u32)ret; + + if (copy_to_user(argp, &phy_user_info, sizeof(struct phydev_user_info))) + return -EFAULT; + + break; + + case CMD_PHY_WRITE: + if (copy_from_user(&phy_user_info, argp, sizeof(struct phydev_user_info))) + return -EFAULT; + + ret = board_phy_write(phy_user_info.phy_index, phy_user_info.regnum, (u16)phy_user_info.regval); + if (ret < 0) { + return -EFAULT; + } + + break; + + case CMD_MDIO_LIST: + list_all_mdio_devices_info(); + break; + + case CMD_MDIO_READ: + if (copy_from_user(&mdio_user_info, argp, sizeof(struct mdio_dev_user_info))) + return -EFAULT; + + ret = board_mdio_read(mdio_user_info.mdio_index, mdio_user_info.phyaddr, mdio_user_info.regnum); + if (ret < 0) { + return -EFAULT; + } + + mdio_user_info.regval = (u32)ret; + + if (copy_to_user(argp, &mdio_user_info, sizeof(struct mdio_dev_user_info))) + return -EFAULT; + + break; + + case CMD_MDIO_WRITE: + if (copy_from_user(&mdio_user_info, argp, sizeof(struct mdio_dev_user_info))) + return -EFAULT; + + ret = board_mdio_write(mdio_user_info.mdio_index, mdio_user_info.phyaddr, mdio_user_info.regnum, (u16)mdio_user_info.regval); + if (ret < 0) { + return -EFAULT; + } + + break; + + default: + printk("unknown ioctl cmd\n"); + break; + } + + return 0; +} + +static int dram_dev_open(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + file->f_pos = 0; + return 0; + +} + +static int dram_dev_release(struct inode *inode, struct file *file) +{ + if (file->private_data) { + iounmap(file->private_data); + } + return 0; +} + +static const struct file_operations dram_dev_fops = { + .owner = THIS_MODULE, + .llseek = dram_dev_llseek, + .read = dram_dev_read, + .write = dram_dev_write, + .unlocked_ioctl = dram_dev_ioctl, + .open = dram_dev_open, + .release = dram_dev_release, +}; + +static int register_dram_cdev(void) +{ + int ret; + + ret = alloc_chrdev_region(&dram_devno, 0, 1, DRAM_DEV_NAME); + if (ret < 0) { + return ret; + } + + cdev_init(&dram_cdev, &dram_dev_fops); + dram_cdev.owner = THIS_MODULE; + + ret = cdev_add(&dram_cdev, dram_devno, 1); + if (ret < 0) { + goto err_unregister_chrdev; + } + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) + dram_class = class_create(DRAM_CLASS_NAME); + #else + dram_class = class_create(THIS_MODULE, DRAM_CLASS_NAME); + #endif + if (IS_ERR(dram_class)) { + ret = PTR_ERR(dram_class); + dram_class = NULL; + goto err_del_cdev; + } + + dram_device = device_create(dram_class, NULL, dram_devno, NULL, DRAM_DEV_NAME); + if (IS_ERR(dram_device)) { + ret = PTR_ERR(dram_device); + dram_device = NULL; + goto err_destroy_class; + } + + return 0; + +err_destroy_class: + class_destroy(dram_class); + dram_class = NULL; +err_del_cdev: + cdev_del(&dram_cdev); +err_unregister_chrdev: + unregister_chrdev_region(dram_devno, 1); + dram_devno = 0; + return ret; +} + +static void unregister_dram_cdev(void) +{ + if (dram_device != NULL) { + device_destroy(dram_class, dram_devno); + dram_device = NULL; + } + + if (dram_class != NULL) { + class_destroy(dram_class); + dram_class = NULL; + } + + cdev_del(&dram_cdev); + unregister_chrdev_region(dram_devno, 1); + dram_devno = 0; +} + +static int __init dram_init(void) +{ + int ret; + + if (add_all_phydevs_to_list() != 0) { + printk(KERN_ERR "add all phydev to list fail\n"); + delete_all_phydevs_from_list(); + return -ENXIO; + } + + if (init_class_mdio_bus() == 0) { + if (add_all_mdio_devices_to_list() == -EFAULT) { + printk(KERN_ERR "add all mdiodev to list fail\n"); + delete_all_mdio_devices_from_list(); + delete_all_phydevs_from_list(); + return -ENXIO; + } + } + + ret = register_dram_cdev(); + if (ret != 0) { + pr_notice("Register %s failed, ret=%d.\r\n", DRAM_DEV_NAME, ret); + delete_all_mdio_devices_from_list(); + delete_all_phydevs_from_list(); + return ret; + } + + return 0; +} + +static void __exit dram_exit(void) +{ + unregister_dram_cdev(); + + delete_all_mdio_devices_from_list(); + delete_all_phydevs_from_list(); +} + +module_init(dram_init); +module_exit(dram_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.h b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.h new file mode 100644 index 0000000000..270a65c348 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/hw_test/hw_test_driver/hw_test.h @@ -0,0 +1,28 @@ +#ifndef _LINUX_DRAM_DRIVER_H +#define _LINUX_DRAM_DRIVER_H + +#include +#include + +struct phydev_user_info { + int phy_index; /* Indicates which phydev to operate on */ + u32 regnum; /* Register address */ + u32 regval; /* Register value */ +}; + +#define CMD_PHY_LIST _IOR('P', 0, struct phydev_user_info) +#define CMD_PHY_READ _IOR('P', 1, struct phydev_user_info) +#define CMD_PHY_WRITE _IOR('P', 2, struct phydev_user_info) + +struct mdio_dev_user_info { + int mdio_index; /* Indicates which mdio dev to operate on */ + int phyaddr; /* phy device address */ + u32 regnum; /* Register address */ + u32 regval; /* Register value */ +}; + +#define CMD_MDIO_LIST _IOR('M', 0, struct mdio_dev_user_info) +#define CMD_MDIO_READ _IOR('M', 1, struct mdio_dev_user_info) +#define CMD_MDIO_WRITE _IOR('M', 2, struct mdio_dev_user_info) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py index ea1ef4930a..9c90b31734 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py @@ -36,6 +36,8 @@ class chassisbase(object): __card_list = [] __sensor_list = [] __dcdc_list = [] + __dcdc_vol_list = [] + __dcdc_curr_list = [] __cpld_list = [] __comp_list = [] __bios_list = [] @@ -154,12 +156,17 @@ def __init__(self, conftype=0, conf=None): self.fan_list = fantemp # dcdc - dcdctemp = [] dcdcconfig = __confTemp.get('dcdc', []) for item in dcdcconfig: - dcdc1 = dcdc(item) - dcdctemp.append(dcdc1) - self.dcdc_list = dcdctemp + Unit = item.get("Unit", None) + if Unit == "V" or Unit == "mV": + dcdc1 = dcdc(item) + self.dcdc_vol_list.append(dcdc1) + elif Unit == "A" or Unit == "mA": + dcdc1 = dcdc(item) + self.dcdc_curr_list.append(dcdc1) + self.dcdc_list = self.dcdc_vol_list + self.dcdc_curr_list + # dcdc_data_source. the following is example: ''' @@ -204,10 +211,14 @@ def __init__(self, conftype=0, conf=None): s3ip_conf = item.copy() s3ip_conf["sensor_dir"] = sensor_dir dcdc_obj = dcdc(s3ip_conf = s3ip_conf) - tmp_list.append(dcdc_obj) + Unit = item.get("Unit", None) + if Unit == "V" or Unit == "mV": + self.dcdc_vol_list.append(dcdc_obj) + elif Unit == "A" or Unit == "mA": + self.dcdc_curr_list.append(dcdc_obj) except Exception: pass - self.dcdc_list.extend(tmp_list) + self.dcdc_list = self.dcdc_vol_list + self.dcdc_curr_list # cpld cpldtemp = [] @@ -249,6 +260,24 @@ def dcdc_list(self): def dcdc_list(self, val): self.__dcdc_list = val + # vol dcdc + @property + def dcdc_vol_list(self): + return self.__dcdc_vol_list + + @dcdc_vol_list.setter + def dcdc_vol_list(self, val): + self.__dcdc_vol_list = val + + # curr dcdc + @property + def dcdc_curr_list(self): + return self.__dcdc_curr_list + + @dcdc_curr_list.setter + def dcdc_curr_list(self, val): + self.__dcdc_curr_list = val + # sensor @property def sensor_list(self): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py index 719680f878..6045ef8ede 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py @@ -27,4 +27,10 @@ def __init__(self, conf = None, s3ip_conf = None): if s3ip_conf is not None: self.sensor = sensor_s3ip(s3ip_conf) self.name = self.sensor.name - self.dcdc_id = self.sensor.sensor_id + self.dcdc_type = s3ip_conf.get("type", None) + if self.dcdc_type == "vol": + dcdc_index = s3ip_conf["sensor_dir"][3:] + self.dcdc_id = "DCDC" + str(dcdc_index) + if self.dcdc_type == "curr": + dcdc_index = int(s3ip_conf["sensor_dir"][4:]) + int(self.sensor.vol_num) + self.dcdc_id = "DCDC" + str(dcdc_index) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py index e12c469e61..8fbe164314 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py @@ -863,24 +863,42 @@ def get_dcdc_by_id(self, dcdc_id): dic["Unit"] = dcdctmp.sensor.Unit return dic - def get_dcdc_all_info(self): - val_list = collections.OrderedDict() + def get_dcdc_unit_by_id(self, dcdc_id): dcdclist = self.chas.dcdc_list + dcdctmp = None + for dcdc in dcdclist: + if dcdc.dcdc_id == dcdc_id: + dcdctmp = dcdc + dic = collections.OrderedDict() + if dcdctmp is None: + return self.na_ret + return dcdctmp.sensor.Unit + + + def get_dcdc_all_info(self, dcdc_type=""): + val_list = collections.OrderedDict() + if dcdc_type == "vol": + dcdclist = self.chas.dcdc_vol_list + elif dcdc_type == "curr": + dcdclist = self.chas.dcdc_curr_list + else: + dcdclist = self.chas.dcdc_list for dcdc in dcdclist: dicttmp = {} sensorname = "%s" % (dcdc.name) dicttmp['Min'] = dcdc.sensor.Min dicttmp['Max'] = dcdc.sensor.Max tmp = dcdc.sensor.Value + if tmp is None: + dicttmp['Value'] = self.error_ret + dicttmp["Status"] = "NOT OK" + continue if tmp is not None: dicttmp['Value'] = tmp if tmp > float(dicttmp['Max']) or tmp < float(dicttmp['Min']): dicttmp["Status"] = "NOT OK" else: dicttmp["Status"] = "OK" - else: - dicttmp['Value'] = self.error_ret - dicttmp["Status"] = "NOT OK" dicttmp['Unit'] = dcdc.sensor.Unit val_list[sensorname] = dicttmp return val_list @@ -1373,4 +1391,3 @@ def get_sensor_print_src(self): @return string of sensor data source """ return self.chas.sensor_print_src - diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py index 99396923c4..7d47d46254 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py @@ -299,13 +299,18 @@ def __init__(self, s3ip_conf): self.max_path = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "max") self.alias = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "alias") self.sensor_id = self.s3ip_conf.get("type").upper() + self.vol_num_path = "/sys/s3ip/vol_sensor/number" + self.Unit = self.s3ip_conf.get("Unit") @property def Min(self): try: ret, val = self.get_sysfs(self.min_path) if ret is True: - return val + self.__Min = val + if self.format is not None: + self.__Min = self.get_format_value(self.format % self.__Min) + return self.__Min except Exception: pass return None @@ -322,7 +327,10 @@ def Max(self): try: ret, val = self.get_sysfs(self.max_path) if ret is True: - return val + self.__Max = val + if self.format is not None: + self.__Max = self.get_format_value(self.format % self.__Max) + return self.__Max except Exception: pass return None @@ -343,4 +351,13 @@ def name(self): except Exception: pass return None - + + @property + def vol_num(self): + try: + ret, val = self.get_sysfs(self.vol_num_path) + if ret is True: + return val + except Exception: + pass + return None diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile index 0b3ed8b66f..bfbf31393f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile @@ -9,6 +9,10 @@ export module_out_put_dir PLAT_SYSFS_DIR = $(PWD)/plat_sysfs S3IP_SYSFS_DIR = $(PWD)/s3ip_sysfs +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +BSP_KERNEL_DEBUG_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../public/include) + +EXTRA_CFLAGS+= -I$(BSP_KERNEL_DEBUG_PATH) export PLAT_SYSFS_DIR export S3IP_SYSFS_DIR @@ -33,7 +37,6 @@ obj-m += wb_wdt.o obj-m += wb_spi_gpio_device.o obj-m += wb_xdpe132g5c.o obj-m += wb_uio_irq.o -obj-m += hw_test.o obj-m += wb_mdio_gpio_device.o obj-m += wb_csu550.o obj-m += wb_i2c_mux_pca9641.o @@ -43,6 +46,13 @@ obj-m += wb_i2c_gpio_device.o obj-m += ct7148.o obj-m += wb_ucd9081.o obj-m += wb_indirect_dev.o +obj-m += wb_spi_master.o +obj-m += wb_rc32312.o +obj-m += wb_logic_dev_common.o +obj-m += ixgbe/ +obj-m += i2c-designware/ +obj-m += wb_mdio_dev.o +obj-m += wb_switch_dev.o all : $(MAKE) -C $(PLAT_SYSFS_DIR) @@ -50,6 +60,8 @@ all : $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi cp -p $(PWD)/*.ko $(module_out_put_dir) + cp -p $(PWD)/ixgbe/*.ko $(module_out_put_dir) + cp -p $(PWD)/i2c-designware/*.ko $(module_out_put_dir) clean : rm -rf $(module_out_put_dir) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/Makefile new file mode 100644 index 0000000000..9ee82ebe0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/Makefile @@ -0,0 +1,19 @@ +PWD = $(shell pwd) + +obj-m += wb_i2c_designware_core.o +wb_i2c_designware_core-y := i2c-designware-common.o +wb_i2c_designware_core-y += i2c-designware-master.o +wb_i2c_designware_core-$(CONFIG_I2C_DESIGNWARE_SLAVE) += i2c-designware-slave.o +obj-m += wb_i2c_designware_platform.o +wb_i2c_designware_platform-y := i2c-designware-platdrv.o +wb_i2c_designware_platform-$(CONFIG_I2C_DESIGNWARE_AMDPSP) += i2c-designware-amdpsp.o +wb_i2c_designware_platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o +obj-$(CONFIG_I2C_DESIGNWARE_PCI) += wb_i2c_designware_pci.o +wb_i2c_designware_pci-y := i2c-designware-pcidrv.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/*.order $(PWD)/*.symvers $(PWD)/*.mod diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-ccgx-ucsi.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-ccgx-ucsi.h new file mode 100644 index 0000000000..739ac7a4b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-ccgx-ucsi.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __I2C_CCGX_UCSI_H_ +#define __I2C_CCGX_UCSI_H_ + +struct i2c_adapter; +struct i2c_client; +struct software_node; + +struct i2c_client *i2c_new_ccgx_ucsi(struct i2c_adapter *adapter, int irq, + const struct software_node *swnode); +#endif /* __I2C_CCGX_UCSI_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-amdpsp.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-amdpsp.c new file mode 100644 index 0000000000..63454b06e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-amdpsp.c @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#include "i2c-designware-core.h" + +#define PSP_I2C_RESERVATION_TIME_MS 100 + +#define PSP_I2C_REQ_RETRY_CNT 400 +#define PSP_I2C_REQ_RETRY_DELAY_US (25 * USEC_PER_MSEC) +#define PSP_I2C_REQ_STS_OK 0x0 +#define PSP_I2C_REQ_STS_BUS_BUSY 0x1 +#define PSP_I2C_REQ_STS_INV_PARAM 0x3 + +enum psp_i2c_req_type { + PSP_I2C_REQ_ACQUIRE, + PSP_I2C_REQ_RELEASE, + PSP_I2C_REQ_MAX +}; + +struct psp_i2c_req { + struct psp_req_buffer_hdr hdr; + enum psp_i2c_req_type type; +}; + +static DEFINE_MUTEX(psp_i2c_access_mutex); +static unsigned long psp_i2c_sem_acquired; +static u32 psp_i2c_access_count; +static bool psp_i2c_mbox_fail; +static struct device *psp_i2c_dev; + +static int (*_psp_send_i2c_req)(struct psp_i2c_req *req); + +/* Helper to verify status returned by PSP */ +static int check_i2c_req_sts(struct psp_i2c_req *req) +{ + u32 status; + + /* Status field in command-response buffer is updated by PSP */ + status = READ_ONCE(req->hdr.status); + + switch (status) { + case PSP_I2C_REQ_STS_OK: + return 0; + case PSP_I2C_REQ_STS_BUS_BUSY: + return -EBUSY; + case PSP_I2C_REQ_STS_INV_PARAM: + default: + return -EIO; + } +} + +/* + * Errors in x86-PSP i2c-arbitration protocol may occur at two levels: + * 1. mailbox communication - PSP is not operational or some IO errors with + * basic communication had happened. + * 2. i2c-requests - PSP refuses to grant i2c arbitration to x86 for too long. + * + * In order to distinguish between these in error handling code all mailbox + * communication errors on the first level (from CCP symbols) will be passed + * up and if -EIO is returned the second level will be checked. + */ +static int psp_send_i2c_req_cezanne(struct psp_i2c_req *req) +{ + int ret; + + ret = psp_send_platform_access_msg(PSP_I2C_REQ_BUS_CMD, (struct psp_request *)req); + if (ret == -EIO) + return check_i2c_req_sts(req); + + return ret; +} + +static int psp_send_i2c_req_doorbell(struct psp_i2c_req *req) +{ + int ret; + + ret = psp_ring_platform_doorbell(req->type, &req->hdr.status); + if (ret == -EIO) + return check_i2c_req_sts(req); + + return ret; +} + +static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) +{ + struct psp_i2c_req *req; + unsigned long start; + int status, ret; + + /* Allocate command-response buffer */ + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) + return -ENOMEM; + + req->hdr.payload_size = sizeof(*req); + req->type = i2c_req_type; + + start = jiffies; + ret = read_poll_timeout(_psp_send_i2c_req, status, + (status != -EBUSY), + PSP_I2C_REQ_RETRY_DELAY_US, + PSP_I2C_REQ_RETRY_CNT * PSP_I2C_REQ_RETRY_DELAY_US, + 0, req); + if (ret) { + dev_err(psp_i2c_dev, "Timed out waiting for PSP to %s I2C bus\n", + (i2c_req_type == PSP_I2C_REQ_ACQUIRE) ? + "release" : "acquire"); + goto cleanup; + } + + ret = status; + if (ret) { + dev_err(psp_i2c_dev, "PSP communication error\n"); + goto cleanup; + } + + dev_dbg(psp_i2c_dev, "Request accepted by PSP after %ums\n", + jiffies_to_msecs(jiffies - start)); + +cleanup: + if (ret) { + dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); + psp_i2c_mbox_fail = true; + } + + kfree(req); + return ret; +} + +static void release_bus(void) +{ + int status; + + if (!psp_i2c_sem_acquired) + return; + + status = psp_send_i2c_req(PSP_I2C_REQ_RELEASE); + if (status) + return; + + dev_dbg(psp_i2c_dev, "PSP semaphore held for %ums\n", + jiffies_to_msecs(jiffies - psp_i2c_sem_acquired)); + + psp_i2c_sem_acquired = 0; +} + +static void psp_release_i2c_bus_deferred(struct work_struct *work) +{ + mutex_lock(&psp_i2c_access_mutex); + + /* + * If there is any pending transaction, cannot release the bus here. + * psp_release_i2c_bus will take care of this later. + */ + if (psp_i2c_access_count) + goto cleanup; + + release_bus(); + +cleanup: + mutex_unlock(&psp_i2c_access_mutex); +} +static DECLARE_DELAYED_WORK(release_queue, psp_release_i2c_bus_deferred); + +static int psp_acquire_i2c_bus(void) +{ + int status; + + mutex_lock(&psp_i2c_access_mutex); + + /* Return early if mailbox malfunctioned */ + if (psp_i2c_mbox_fail) + goto cleanup; + + psp_i2c_access_count++; + + /* + * No need to request bus arbitration once we are inside semaphore + * reservation period. + */ + if (psp_i2c_sem_acquired) + goto cleanup; + + status = psp_send_i2c_req(PSP_I2C_REQ_ACQUIRE); + if (status) + goto cleanup; + + psp_i2c_sem_acquired = jiffies; + + schedule_delayed_work(&release_queue, + msecs_to_jiffies(PSP_I2C_RESERVATION_TIME_MS)); + + /* + * In case of errors with PSP arbitrator psp_i2c_mbox_fail variable is + * set above. As a consequence consecutive calls to acquire will bypass + * communication with PSP. At any case i2c bus is granted to the caller, + * thus always return success. + */ +cleanup: + mutex_unlock(&psp_i2c_access_mutex); + return 0; +} + +static void psp_release_i2c_bus(void) +{ + mutex_lock(&psp_i2c_access_mutex); + + /* Return early if mailbox was malfunctional */ + if (psp_i2c_mbox_fail) + goto cleanup; + + /* + * If we are last owner of PSP semaphore, need to release aribtration + * via mailbox. + */ + psp_i2c_access_count--; + if (psp_i2c_access_count) + goto cleanup; + + /* + * Send a release command to PSP if the semaphore reservation timeout + * elapsed but x86 still owns the controller. + */ + if (!delayed_work_pending(&release_queue)) + release_bus(); + +cleanup: + mutex_unlock(&psp_i2c_access_mutex); +} + +/* + * Locking methods are based on the default implementation from + * drivers/i2c/i2c-core-base.c, but with psp acquire and release operations + * added. With this in place we can ensure that i2c clients on the bus shared + * with psp are able to lock HW access to the bus for arbitrary number of + * operations - that is e.g. write-wait-read. + */ +static void i2c_adapter_dw_psp_lock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + psp_acquire_i2c_bus(); + rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter)); +} + +static int i2c_adapter_dw_psp_trylock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + int ret; + + ret = rt_mutex_trylock(&adapter->bus_lock); + if (ret) + return ret; + + psp_acquire_i2c_bus(); + + return ret; +} + +static void i2c_adapter_dw_psp_unlock_bus(struct i2c_adapter *adapter, + unsigned int flags) +{ + psp_release_i2c_bus(); + rt_mutex_unlock(&adapter->bus_lock); +} + +static const struct i2c_lock_operations i2c_dw_psp_lock_ops = { + .lock_bus = i2c_adapter_dw_psp_lock_bus, + .trylock_bus = i2c_adapter_dw_psp_trylock_bus, + .unlock_bus = i2c_adapter_dw_psp_unlock_bus, +}; + +int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev) +{ + struct pci_dev *rdev; + + if (!IS_REACHABLE(CONFIG_CRYPTO_DEV_CCP_DD)) + return -ENODEV; + + if (!dev) + return -ENODEV; + + if (!(dev->flags & ARBITRATION_SEMAPHORE)) + return -ENODEV; + + /* Allow to bind only one instance of a driver */ + if (psp_i2c_dev) + return -EEXIST; + + /* Cezanne uses platform mailbox, Mendocino and later use doorbell */ + rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); + if (rdev->device == 0x1630) + _psp_send_i2c_req = psp_send_i2c_req_cezanne; + else + _psp_send_i2c_req = psp_send_i2c_req_doorbell; + pci_dev_put(rdev); + + if (psp_check_platform_access_status()) + return -EPROBE_DEFER; + + psp_i2c_dev = dev->dev; + + dev_info(psp_i2c_dev, "I2C bus managed by AMD PSP\n"); + + /* + * Install global locking callbacks for adapter as well as internal i2c + * controller locks. + */ + dev->adapter.lock_ops = &i2c_dw_psp_lock_ops; + dev->acquire_lock = psp_acquire_i2c_bus; + dev->release_lock = psp_release_i2c_bus; + + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-baytrail.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-baytrail.c new file mode 100644 index 0000000000..45774aa47c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-baytrail.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel BayTrail PMIC I2C bus semaphore implementation + * Copyright (c) 2014, Intel Corporation. + */ +#include +#include +#include +#include + +#include + +#include "i2c-designware-core.h" + +int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev) +{ + acpi_status status; + unsigned long long shared_host = 0; + acpi_handle handle; + + if (!dev) + return -ENODEV; + + handle = ACPI_HANDLE(dev->dev); + if (!handle) + return -ENODEV; + + status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host); + if (ACPI_FAILURE(status)) + return -ENODEV; + + if (!shared_host) + return -ENODEV; + + if (!iosf_mbi_available()) + return -EPROBE_DEFER; + + dev_info(dev->dev, "I2C bus managed by PUNIT\n"); + dev->acquire_lock = iosf_mbi_block_punit_i2c_access; + dev->release_lock = iosf_mbi_unblock_punit_i2c_access; + dev->shared_with_punit = true; + + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-common.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-common.c new file mode 100644 index 0000000000..b328278552 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-common.c @@ -0,0 +1,835 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Synopsys DesignWare I2C adapter driver. + * + * Based on the TI DAVINCI I2C adapter driver. + * + * Copyright (C) 2006 Texas Instruments. + * Copyright (C) 2007 MontaVista Software Inc. + * Copyright (C) 2009 Provigent Ltd. + */ + +#define DEFAULT_SYMBOL_NAMESPACE "I2C_DW_COMMON" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-designware-core.h" + +static char *abort_sources[] = { + [ABRT_7B_ADDR_NOACK] = + "slave address not acknowledged (7bit mode)", + [ABRT_10ADDR1_NOACK] = + "first address byte not acknowledged (10bit mode)", + [ABRT_10ADDR2_NOACK] = + "second address byte not acknowledged (10bit mode)", + [ABRT_TXDATA_NOACK] = + "data not acknowledged", + [ABRT_GCALL_NOACK] = + "no acknowledgement for a general call", + [ABRT_GCALL_READ] = + "read after general call", + [ABRT_SBYTE_ACKDET] = + "start byte acknowledged", + [ABRT_SBYTE_NORSTRT] = + "trying to send start byte when restart is disabled", + [ABRT_10B_RD_NORSTRT] = + "trying to read when restart is disabled (10bit mode)", + [ABRT_MASTER_DIS] = + "trying to use disabled adapter", + [ARB_LOST] = + "lost arbitration", + [ABRT_SLAVE_FLUSH_TXFIFO] = + "read command so flush old data in the TX FIFO", + [ABRT_SLAVE_ARBLOST] = + "slave lost the bus while transmitting data to a remote master", + [ABRT_SLAVE_RD_INTX] = + "incorrect slave-transmitter mode configuration", +}; + +static int dw_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct dw_i2c_dev *dev = context; + + *val = readl(dev->base + reg); + + return 0; +} + +static int dw_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct dw_i2c_dev *dev = context; + + writel(val, dev->base + reg); + + return 0; +} + +static int dw_reg_read_swab(void *context, unsigned int reg, unsigned int *val) +{ + struct dw_i2c_dev *dev = context; + + *val = swab32(readl(dev->base + reg)); + + return 0; +} + +static int dw_reg_write_swab(void *context, unsigned int reg, unsigned int val) +{ + struct dw_i2c_dev *dev = context; + + writel(swab32(val), dev->base + reg); + + return 0; +} + +static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val) +{ + struct dw_i2c_dev *dev = context; + + *val = readw(dev->base + reg) | + (readw(dev->base + reg + 2) << 16); + + return 0; +} + +static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val) +{ + struct dw_i2c_dev *dev = context; + + writew(val, dev->base + reg); + writew(val >> 16, dev->base + reg + 2); + + return 0; +} + +/** + * i2c_dw_init_regmap() - Initialize registers map + * @dev: device private data + * + * Autodetects needed register access mode and creates the regmap with + * corresponding read/write callbacks. This must be called before doing any + * other register access. + */ +int i2c_dw_init_regmap(struct dw_i2c_dev *dev) +{ + struct regmap_config map_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .disable_locking = true, + .reg_read = dw_reg_read, + .reg_write = dw_reg_write, + .max_register = DW_IC_COMP_TYPE, + }; + u32 reg; + int ret; + + /* + * Skip detecting the registers map configuration if the regmap has + * already been provided by a higher code. + */ + if (dev->map) + return 0; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + reg = readl(dev->base + DW_IC_COMP_TYPE); + i2c_dw_release_lock(dev); + + if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) + map_cfg.max_register = AMD_UCSI_INTR_REG; + + if (reg == swab32(DW_IC_COMP_TYPE_VALUE)) { + map_cfg.reg_read = dw_reg_read_swab; + map_cfg.reg_write = dw_reg_write_swab; + } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) { + map_cfg.reg_read = dw_reg_read_word; + map_cfg.reg_write = dw_reg_write_word; + } else if (reg != DW_IC_COMP_TYPE_VALUE) { + dev_err(dev->dev, + "Unknown Synopsys component type: 0x%08x\n", reg); + return -ENODEV; + } + + /* + * Note we'll check the return value of the regmap IO accessors only + * at the probe stage. The rest of the code won't do this because + * basically we have MMIO-based regmap so non of the read/write methods + * can fail. + */ + dev->map = devm_regmap_init(dev->dev, NULL, dev, &map_cfg); + if (IS_ERR(dev->map)) { + dev_err(dev->dev, "Failed to init the registers map\n"); + return PTR_ERR(dev->map); + } + + return 0; +} + +static const u32 supported_speeds[] = { + I2C_MAX_HIGH_SPEED_MODE_FREQ, + I2C_MAX_FAST_MODE_PLUS_FREQ, + I2C_MAX_FAST_MODE_FREQ, + I2C_MAX_STANDARD_MODE_FREQ, +}; + +static int i2c_dw_validate_speed(struct dw_i2c_dev *dev) +{ + struct i2c_timings *t = &dev->timings; + unsigned int i; + + /* + * Only standard mode at 100kHz, fast mode at 400kHz, + * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported. + */ + for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) { + if (t->bus_freq_hz == supported_speeds[i]) + return 0; + } + + dev_err(dev->dev, + "%d Hz is unsupported, only 100kHz, 400kHz, 1MHz and 3.4MHz are supported\n", + t->bus_freq_hz); + + return -EINVAL; +} + +#ifdef CONFIG_OF + +#include + +#define MSCC_ICPU_CFG_TWI_DELAY 0x0 +#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0) +#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4 + +static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev) +{ + writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE, + dev->ext + MSCC_ICPU_CFG_TWI_DELAY); + + return 0; +} + +static void i2c_dw_of_configure(struct device *device) +{ + struct platform_device *pdev = to_platform_device(device); + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + switch (dev->flags & MODEL_MASK) { + case MODEL_MSCC_OCELOT: + dev->ext = devm_platform_ioremap_resource(pdev, 1); + if (!IS_ERR(dev->ext)) + dev->set_sda_hold_time = mscc_twi_set_sda_hold_time; + break; + default: + break; + } +} + +#else /* CONFIG_OF */ + +static inline void i2c_dw_of_configure(struct device *device) { } + +#endif /* CONFIG_OF */ + +#ifdef CONFIG_ACPI + +#include + +/* + * The HCNT/LCNT information coming from ACPI should be the most accurate + * for given platform. However, some systems get it wrong. On such systems + * we get better results by calculating those based on the input clock. + */ +static const struct dmi_system_id i2c_dw_no_acpi_params[] = { + { + .ident = "Dell Inspiron 7348", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"), + }, + }, + {} +}; + +static void i2c_dw_acpi_params(struct device *device, char method[], + u16 *hcnt, u16 *lcnt, u32 *sda_hold) +{ + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; + acpi_handle handle = ACPI_HANDLE(device); + union acpi_object *obj; + + if (dmi_check_system(i2c_dw_no_acpi_params)) + return; + + if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf))) + return; + + obj = (union acpi_object *)buf.pointer; + if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) { + const union acpi_object *objs = obj->package.elements; + + *hcnt = (u16)objs[0].integer.value; + *lcnt = (u16)objs[1].integer.value; + *sda_hold = (u32)objs[2].integer.value; + } + + kfree(buf.pointer); +} + +static void i2c_dw_acpi_configure(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + struct i2c_timings *t = &dev->timings; + u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0; + + /* + * Try to get SDA hold time and *CNT values from an ACPI method for + * selected speed modes. + */ + i2c_dw_acpi_params(device, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht); + i2c_dw_acpi_params(device, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht); + i2c_dw_acpi_params(device, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht); + i2c_dw_acpi_params(device, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht); + + switch (t->bus_freq_hz) { + case I2C_MAX_STANDARD_MODE_FREQ: + dev->sda_hold_time = ss_ht; + break; + case I2C_MAX_FAST_MODE_PLUS_FREQ: + dev->sda_hold_time = fp_ht; + break; + case I2C_MAX_HIGH_SPEED_MODE_FREQ: + dev->sda_hold_time = hs_ht; + break; + case I2C_MAX_FAST_MODE_FREQ: + default: + dev->sda_hold_time = fs_ht; + break; + } +} + +static u32 i2c_dw_acpi_round_bus_speed(struct device *device) +{ + u32 acpi_speed; + int i; + + acpi_speed = i2c_acpi_find_bus_speed(device); + /* + * Some DSTDs use a non standard speed, round down to the lowest + * standard speed. + */ + for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) { + if (acpi_speed >= supported_speeds[i]) + return supported_speeds[i]; + } + + return 0; +} + +#else /* CONFIG_ACPI */ + +static inline void i2c_dw_acpi_configure(struct device *device) { } + +static inline u32 i2c_dw_acpi_round_bus_speed(struct device *device) { return 0; } + +#endif /* CONFIG_ACPI */ + +static void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev) +{ + u32 acpi_speed = i2c_dw_acpi_round_bus_speed(dev->dev); + struct i2c_timings *t = &dev->timings; + + /* + * Find bus speed from the "clock-frequency" device property, ACPI + * or by using fast mode if neither is set. + */ + if (acpi_speed && t->bus_freq_hz) + t->bus_freq_hz = min(t->bus_freq_hz, acpi_speed); + else if (acpi_speed || t->bus_freq_hz) + t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed); + else + t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; +} + +int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev) +{ + struct i2c_timings *t = &dev->timings; + struct device *device = dev->dev; + struct fwnode_handle *fwnode = dev_fwnode(device); + + i2c_parse_fw_timings(device, t, false); + + i2c_dw_adjust_bus_speed(dev); + + if (is_of_node(fwnode)) + i2c_dw_of_configure(device); + else if (is_acpi_node(fwnode)) + i2c_dw_acpi_configure(device); + + return i2c_dw_validate_speed(dev); +} +EXPORT_SYMBOL_GPL(i2c_dw_fw_parse_and_configure); + +static u32 i2c_dw_read_scl_reg(struct dw_i2c_dev *dev, u32 reg) +{ + u32 val; + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return 0; + + ret = regmap_read(dev->map, reg, &val); + i2c_dw_release_lock(dev); + + return ret ? 0 : val; +} + +u32 i2c_dw_scl_hcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tSYMBOL, u32 tf, int cond, int offset) +{ + if (!ic_clk) + return i2c_dw_read_scl_reg(dev, reg); + + /* + * DesignWare I2C core doesn't seem to have solid strategy to meet + * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec + * will result in violation of the tHD;STA spec. + */ + if (cond) + /* + * Conditional expression: + * + * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH + * + * This is based on the DW manuals, and represents an ideal + * configuration. The resulting I2C bus speed will be + * faster than any of the others. + * + * If your hardware is free from tHD;STA issue, try this one. + */ + return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * tSYMBOL, MICRO) - + 8 + offset; + else + /* + * Conditional expression: + * + * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) + * + * This is just experimental rule; the tHD;STA period turned + * out to be proportinal to (_HCNT + 3). With this setting, + * we could meet both tHIGH and tHD;STA timing specs. + * + * If unsure, you'd better to take this alternative. + * + * The reason why we need to take into account "tf" here, + * is the same as described in i2c_dw_scl_lcnt(). + */ + return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tSYMBOL + tf), MICRO) - + 3 + offset; +} + +u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tLOW, u32 tf, int offset) +{ + if (!ic_clk) + return i2c_dw_read_scl_reg(dev, reg); + + /* + * Conditional expression: + * + * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) + * + * DW I2C core starts counting the SCL CNTs for the LOW period + * of the SCL clock (tLOW) as soon as it pulls the SCL line. + * In order to meet the tLOW timing spec, we need to take into + * account the fall time of SCL signal (tf). Default tf value + * should be 0.3 us, for safety. + */ + return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) - + 1 + offset; +} + +int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) +{ + unsigned int reg; + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + /* Configure SDA Hold Time if required */ + ret = regmap_read(dev->map, DW_IC_COMP_VERSION, ®); + if (ret) + goto err_release_lock; + + if (reg >= DW_IC_SDA_HOLD_MIN_VERS) { + if (!dev->sda_hold_time) { + /* Keep previous hold time setting if no one set it */ + ret = regmap_read(dev->map, DW_IC_SDA_HOLD, + &dev->sda_hold_time); + if (ret) + goto err_release_lock; + } + + /* + * Workaround for avoiding TX arbitration lost in case I2C + * slave pulls SDA down "too quickly" after falling edge of + * SCL by enabling non-zero SDA RX hold. Specification says it + * extends incoming SDA low to high transition while SCL is + * high but it appears to help also above issue. + */ + if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK)) + dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT; + + dev_dbg(dev->dev, "SDA Hold Time TX:RX = %d:%d\n", + dev->sda_hold_time & ~(u32)DW_IC_SDA_HOLD_RX_MASK, + dev->sda_hold_time >> DW_IC_SDA_HOLD_RX_SHIFT); + } else if (dev->set_sda_hold_time) { + dev->set_sda_hold_time(dev); + } else if (dev->sda_hold_time) { + dev_warn(dev->dev, + "Hardware too old to adjust SDA hold time.\n"); + dev->sda_hold_time = 0; + } + +err_release_lock: + i2c_dw_release_lock(dev); + + return ret; +} + +void __i2c_dw_disable(struct dw_i2c_dev *dev) +{ + struct i2c_timings *t = &dev->timings; + unsigned int raw_intr_stats, ic_stats; + unsigned int enable; + int timeout = 100; + bool abort_needed; + unsigned int status; + int ret; + + regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats); + regmap_read(dev->map, DW_IC_STATUS, &ic_stats); + regmap_read(dev->map, DW_IC_ENABLE, &enable); + + abort_needed = (raw_intr_stats & DW_IC_INTR_MST_ON_HOLD) || + (ic_stats & DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY); + if (abort_needed) { + if (!(enable & DW_IC_ENABLE_ENABLE)) { + regmap_write(dev->map, DW_IC_ENABLE, DW_IC_ENABLE_ENABLE); + /* + * Wait 10 times the signaling period of the highest I2C + * transfer supported by the driver (for 400KHz this is + * 25us) to ensure the I2C ENABLE bit is already set + * as described in the DesignWare I2C databook. + */ + fsleep(DIV_ROUND_CLOSEST_ULL(10 * MICRO, t->bus_freq_hz)); + /* Set ENABLE bit before setting ABORT */ + enable |= DW_IC_ENABLE_ENABLE; + } + + regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); + ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable, + !(enable & DW_IC_ENABLE_ABORT), 10, + 100); + if (ret) + dev_err(dev->dev, "timeout while trying to abort current transfer\n"); + } + + do { + __i2c_dw_disable_nowait(dev); + /* + * The enable status register may be unimplemented, but + * in that case this test reads zero and exits the loop. + */ + regmap_read(dev->map, DW_IC_ENABLE_STATUS, &status); + if ((status & 1) == 0) + return; + + /* + * Wait 10 times the signaling period of the highest I2C + * transfer supported by the driver (for 400KHz this is + * 25us) as described in the DesignWare I2C databook. + */ + usleep_range(25, 250); + } while (timeout--); + + dev_warn(dev->dev, "timeout in disabling adapter\n"); +} + +u32 i2c_dw_clk_rate(struct dw_i2c_dev *dev) +{ + /* + * Clock is not necessary if we got LCNT/HCNT values directly from + * the platform code. + */ + if (WARN_ON_ONCE(!dev->get_clk_rate_khz)) + return 0; + return dev->get_clk_rate_khz(dev); +} + +int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare) +{ + int ret; + + if (prepare) { + /* Optional interface clock */ + ret = clk_prepare_enable(dev->pclk); + if (ret) + return ret; + + ret = clk_prepare_enable(dev->clk); + if (ret) + clk_disable_unprepare(dev->pclk); + + return ret; + } + + clk_disable_unprepare(dev->clk); + clk_disable_unprepare(dev->pclk); + + return 0; +} +EXPORT_SYMBOL_GPL(i2c_dw_prepare_clk); + +int i2c_dw_acquire_lock(struct dw_i2c_dev *dev) +{ + int ret; + + if (!dev->acquire_lock) + return 0; + + ret = dev->acquire_lock(); + if (!ret) + return 0; + + dev_err(dev->dev, "couldn't acquire bus ownership\n"); + + return ret; +} + +void i2c_dw_release_lock(struct dw_i2c_dev *dev) +{ + if (dev->release_lock) + dev->release_lock(); +} + +/* + * Waiting for bus not busy + */ +int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) +{ + unsigned int status; + int ret; + + ret = regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status, + !(status & DW_IC_STATUS_ACTIVITY), + 1100, 20000); + if (ret) { + dev_warn(dev->dev, "timeout waiting for bus ready\n"); + + i2c_recover_bus(&dev->adapter); + + regmap_read(dev->map, DW_IC_STATUS, &status); + if (!(status & DW_IC_STATUS_ACTIVITY)) + ret = 0; + } + + return ret; +} + +int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) +{ + unsigned long abort_source = dev->abort_source; + int i; + + if (abort_source & DW_IC_TX_ABRT_NOACK) { + for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) + dev_dbg(dev->dev, + "%s: %s\n", __func__, abort_sources[i]); + return -EREMOTEIO; + } + + for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) + dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); + + if (abort_source & DW_IC_TX_ARB_LOST) + return -EAGAIN; + else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) + return -EINVAL; /* wrong msgs[] data */ + else + return -EIO; +} + +int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) +{ + u32 tx_fifo_depth, rx_fifo_depth; + unsigned int param; + int ret; + + /* DW_IC_COMP_PARAM_1 not implement for IP issue */ + if ((dev->flags & MODEL_MASK) == MODEL_WANGXUN_SP) { + dev->tx_fifo_depth = TXGBE_TX_FIFO_DEPTH; + dev->rx_fifo_depth = TXGBE_RX_FIFO_DEPTH; + + return 0; + } + + /* + * Try to detect the FIFO depth if not set by interface driver, + * the depth could be from 2 to 256 from HW spec. + */ + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, ¶m); + i2c_dw_release_lock(dev); + if (ret) + return ret; + + tx_fifo_depth = ((param >> 16) & 0xff) + 1; + rx_fifo_depth = ((param >> 8) & 0xff) + 1; + if (!dev->tx_fifo_depth) { + dev->tx_fifo_depth = tx_fifo_depth; + dev->rx_fifo_depth = rx_fifo_depth; + } else if (tx_fifo_depth >= 2) { + dev->tx_fifo_depth = min_t(u32, dev->tx_fifo_depth, + tx_fifo_depth); + dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth, + rx_fifo_depth); + } + + return 0; +} + +u32 i2c_dw_func(struct i2c_adapter *adap) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + + return dev->functionality; +} + +void i2c_dw_disable(struct dw_i2c_dev *dev) +{ + unsigned int dummy; + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return; + + /* Disable controller */ + __i2c_dw_disable(dev); + + /* Disable all interrupts */ + __i2c_dw_write_intr_mask(dev, 0); + regmap_read(dev->map, DW_IC_CLR_INTR, &dummy); + + i2c_dw_release_lock(dev); +} +EXPORT_SYMBOL_GPL(i2c_dw_disable); + +int i2c_dw_probe(struct dw_i2c_dev *dev) +{ + device_set_node(&dev->adapter.dev, dev_fwnode(dev->dev)); + + switch (dev->mode) { + case DW_IC_SLAVE: + return i2c_dw_probe_slave(dev); + case DW_IC_MASTER: + return i2c_dw_probe_master(dev); + default: + dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(i2c_dw_probe); + +static int i2c_dw_prepare(struct device *device) +{ + /* + * If the ACPI companion device object is present for this device, + * it may be accessed during suspend and resume of other devices via + * I2C operation regions, so tell the PM core and middle layers to + * avoid skipping system suspend/resume callbacks for it in that case. + */ + return !has_acpi_companion(device); +} + +static int i2c_dw_runtime_suspend(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + if (dev->shared_with_punit) + return 0; + + i2c_dw_disable(dev); + i2c_dw_prepare_clk(dev, false); + + return 0; +} + +static int i2c_dw_suspend(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + i2c_mark_adapter_suspended(&dev->adapter); + + return i2c_dw_runtime_suspend(device); +} + +static int i2c_dw_runtime_resume(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + if (!dev->shared_with_punit) + i2c_dw_prepare_clk(dev, true); + + dev->init(dev); + + return 0; +} + +static int i2c_dw_resume(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + i2c_dw_runtime_resume(device); + i2c_mark_adapter_resumed(&dev->adapter); + + return 0; +} + +EXPORT_GPL_DEV_PM_OPS(i2c_dw_dev_pm_ops) = { + .prepare = pm_sleep_ptr(i2c_dw_prepare), + LATE_SYSTEM_SLEEP_PM_OPS(i2c_dw_suspend, i2c_dw_resume) + RUNTIME_PM_OPS(i2c_dw_runtime_suspend, i2c_dw_runtime_resume, NULL) +}; + +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-core.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-core.h new file mode 100644 index 0000000000..2d32896d06 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-core.h @@ -0,0 +1,409 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Synopsys DesignWare I2C adapter driver. + * + * Based on the TI DAVINCI I2C adapter driver. + * + * Copyright (C) 2006 Texas Instruments. + * Copyright (C) 2007 MontaVista Software Inc. + * Copyright (C) 2009 Provigent Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_BLOCK_DATA | \ + I2C_FUNC_SMBUS_I2C_BLOCK) + +#define DW_IC_CON_MASTER BIT(0) +#define DW_IC_CON_SPEED_STD (1 << 1) +#define DW_IC_CON_SPEED_FAST (2 << 1) +#define DW_IC_CON_SPEED_HIGH (3 << 1) +#define DW_IC_CON_SPEED_MASK GENMASK(2, 1) +#define DW_IC_CON_10BITADDR_SLAVE BIT(3) +#define DW_IC_CON_10BITADDR_MASTER BIT(4) +#define DW_IC_CON_RESTART_EN BIT(5) +#define DW_IC_CON_SLAVE_DISABLE BIT(6) +#define DW_IC_CON_STOP_DET_IFADDRESSED BIT(7) +#define DW_IC_CON_TX_EMPTY_CTRL BIT(8) +#define DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9) +#define DW_IC_CON_BUS_CLEAR_CTRL BIT(11) + +#define DW_IC_DATA_CMD_DAT GENMASK(7, 0) +#define DW_IC_DATA_CMD_FIRST_DATA_BYTE BIT(11) + +/* + * Registers offset + */ +#define DW_IC_CON 0x00 +#define DW_IC_TAR 0x04 +#define DW_IC_SAR 0x08 +#define DW_IC_DATA_CMD 0x10 +#define DW_IC_SS_SCL_HCNT 0x14 +#define DW_IC_SS_SCL_LCNT 0x18 +#define DW_IC_FS_SCL_HCNT 0x1c +#define DW_IC_FS_SCL_LCNT 0x20 +#define DW_IC_HS_SCL_HCNT 0x24 +#define DW_IC_HS_SCL_LCNT 0x28 +#define DW_IC_INTR_STAT 0x2c +#define DW_IC_INTR_MASK 0x30 +#define DW_IC_RAW_INTR_STAT 0x34 +#define DW_IC_RX_TL 0x38 +#define DW_IC_TX_TL 0x3c +#define DW_IC_CLR_INTR 0x40 +#define DW_IC_CLR_RX_UNDER 0x44 +#define DW_IC_CLR_RX_OVER 0x48 +#define DW_IC_CLR_TX_OVER 0x4c +#define DW_IC_CLR_RD_REQ 0x50 +#define DW_IC_CLR_TX_ABRT 0x54 +#define DW_IC_CLR_RX_DONE 0x58 +#define DW_IC_CLR_ACTIVITY 0x5c +#define DW_IC_CLR_STOP_DET 0x60 +#define DW_IC_CLR_START_DET 0x64 +#define DW_IC_CLR_GEN_CALL 0x68 +#define DW_IC_ENABLE 0x6c +#define DW_IC_STATUS 0x70 +#define DW_IC_TXFLR 0x74 +#define DW_IC_RXFLR 0x78 +#define DW_IC_SDA_HOLD 0x7c +#define DW_IC_TX_ABRT_SOURCE 0x80 +#define DW_IC_ENABLE_STATUS 0x9c +#define DW_IC_CLR_RESTART_DET 0xa8 +#define DW_IC_COMP_PARAM_1 0xf4 +#define DW_IC_COMP_VERSION 0xf8 +#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */ +#define DW_IC_COMP_TYPE 0xfc +#define DW_IC_COMP_TYPE_VALUE 0x44570140 /* "DW" + 0x0140 */ + +#define DW_IC_INTR_RX_UNDER BIT(0) +#define DW_IC_INTR_RX_OVER BIT(1) +#define DW_IC_INTR_RX_FULL BIT(2) +#define DW_IC_INTR_TX_OVER BIT(3) +#define DW_IC_INTR_TX_EMPTY BIT(4) +#define DW_IC_INTR_RD_REQ BIT(5) +#define DW_IC_INTR_TX_ABRT BIT(6) +#define DW_IC_INTR_RX_DONE BIT(7) +#define DW_IC_INTR_ACTIVITY BIT(8) +#define DW_IC_INTR_STOP_DET BIT(9) +#define DW_IC_INTR_START_DET BIT(10) +#define DW_IC_INTR_GEN_CALL BIT(11) +#define DW_IC_INTR_RESTART_DET BIT(12) +#define DW_IC_INTR_MST_ON_HOLD BIT(13) + +#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ + DW_IC_INTR_TX_ABRT | \ + DW_IC_INTR_STOP_DET) +#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MASK | \ + DW_IC_INTR_TX_EMPTY) +#define DW_IC_INTR_SLAVE_MASK (DW_IC_INTR_DEFAULT_MASK | \ + DW_IC_INTR_RX_UNDER | \ + DW_IC_INTR_RD_REQ) + +#define DW_IC_ENABLE_ENABLE BIT(0) +#define DW_IC_ENABLE_ABORT BIT(1) + +#define DW_IC_STATUS_ACTIVITY BIT(0) +#define DW_IC_STATUS_TFE BIT(2) +#define DW_IC_STATUS_RFNE BIT(3) +#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) +#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) +#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7) + +#define DW_IC_SDA_HOLD_RX_SHIFT 16 +#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16) + +#define DW_IC_ERR_TX_ABRT 0x1 + +#define DW_IC_TAR_10BITADDR_MASTER BIT(12) + +#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) +#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) + +/* + * Sofware status flags + */ +#define STATUS_ACTIVE BIT(0) +#define STATUS_WRITE_IN_PROGRESS BIT(1) +#define STATUS_READ_IN_PROGRESS BIT(2) +#define STATUS_MASK GENMASK(2, 0) + +/* + * operation modes + */ +#define DW_IC_MASTER 0 +#define DW_IC_SLAVE 1 + +/* + * Hardware abort codes from the DW_IC_TX_ABRT_SOURCE register + * + * Only expected abort codes are listed here + * refer to the datasheet for the full list + */ +#define ABRT_7B_ADDR_NOACK 0 +#define ABRT_10ADDR1_NOACK 1 +#define ABRT_10ADDR2_NOACK 2 +#define ABRT_TXDATA_NOACK 3 +#define ABRT_GCALL_NOACK 4 +#define ABRT_GCALL_READ 5 +#define ABRT_SBYTE_ACKDET 7 +#define ABRT_SBYTE_NORSTRT 9 +#define ABRT_10B_RD_NORSTRT 10 +#define ABRT_MASTER_DIS 11 +#define ARB_LOST 12 +#define ABRT_SLAVE_FLUSH_TXFIFO 13 +#define ABRT_SLAVE_ARBLOST 14 +#define ABRT_SLAVE_RD_INTX 15 + +#define DW_IC_TX_ABRT_7B_ADDR_NOACK BIT(ABRT_7B_ADDR_NOACK) +#define DW_IC_TX_ABRT_10ADDR1_NOACK BIT(ABRT_10ADDR1_NOACK) +#define DW_IC_TX_ABRT_10ADDR2_NOACK BIT(ABRT_10ADDR2_NOACK) +#define DW_IC_TX_ABRT_TXDATA_NOACK BIT(ABRT_TXDATA_NOACK) +#define DW_IC_TX_ABRT_GCALL_NOACK BIT(ABRT_GCALL_NOACK) +#define DW_IC_TX_ABRT_GCALL_READ BIT(ABRT_GCALL_READ) +#define DW_IC_TX_ABRT_SBYTE_ACKDET BIT(ABRT_SBYTE_ACKDET) +#define DW_IC_TX_ABRT_SBYTE_NORSTRT BIT(ABRT_SBYTE_NORSTRT) +#define DW_IC_TX_ABRT_10B_RD_NORSTRT BIT(ABRT_10B_RD_NORSTRT) +#define DW_IC_TX_ABRT_MASTER_DIS BIT(ABRT_MASTER_DIS) +#define DW_IC_TX_ARB_LOST BIT(ARB_LOST) +#define DW_IC_RX_ABRT_SLAVE_RD_INTX BIT(ABRT_SLAVE_RD_INTX) +#define DW_IC_RX_ABRT_SLAVE_ARBLOST BIT(ABRT_SLAVE_ARBLOST) +#define DW_IC_RX_ABRT_SLAVE_FLUSH_TXFIFO BIT(ABRT_SLAVE_FLUSH_TXFIFO) + +#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ + DW_IC_TX_ABRT_10ADDR1_NOACK | \ + DW_IC_TX_ABRT_10ADDR2_NOACK | \ + DW_IC_TX_ABRT_TXDATA_NOACK | \ + DW_IC_TX_ABRT_GCALL_NOACK) + +struct clk; +struct device; +struct reset_control; + +/** + * struct dw_i2c_dev - private i2c-designware data + * @dev: driver model device node + * @map: IO registers map + * @sysmap: System controller registers map + * @base: IO registers pointer + * @ext: Extended IO registers pointer + * @cmd_complete: tx completion indicator + * @clk: input reference clock + * @pclk: clock required to access the registers + * @rst: optional reset for the controller + * @slave: represent an I2C slave device + * @get_clk_rate_khz: callback to retrieve IP specific bus speed + * @cmd_err: run time hadware error code + * @msgs: points to an array of messages currently being transferred + * @msgs_num: the number of elements in msgs + * @msg_write_idx: the element index of the current tx message in the msgs array + * @tx_buf_len: the length of the current tx buffer + * @tx_buf: the current tx buffer + * @msg_read_idx: the element index of the current rx message in the msgs array + * @rx_buf_len: the length of the current rx buffer + * @rx_buf: the current rx buffer + * @msg_err: error status of the current transfer + * @status: i2c master status, one of STATUS_* + * @abort_source: copy of the TX_ABRT_SOURCE register + * @sw_mask: SW mask of DW_IC_INTR_MASK used in polling mode + * @irq: interrupt number for the i2c master + * @flags: platform specific flags like type of IO accessors or model + * @adapter: i2c subsystem adapter node + * @functionality: I2C_FUNC_* ORed bits to reflect what controller does support + * @master_cfg: configuration for the master device + * @slave_cfg: configuration for the slave device + * @tx_fifo_depth: depth of the hardware tx fifo + * @rx_fifo_depth: depth of the hardware rx fifo + * @rx_outstanding: current master-rx elements in tx fifo + * @timings: bus clock frequency, SDA hold and other timings + * @sda_hold_time: SDA hold value + * @ss_hcnt: standard speed HCNT value + * @ss_lcnt: standard speed LCNT value + * @fs_hcnt: fast speed HCNT value + * @fs_lcnt: fast speed LCNT value + * @fp_hcnt: fast plus HCNT value + * @fp_lcnt: fast plus LCNT value + * @hs_hcnt: high speed HCNT value + * @hs_lcnt: high speed LCNT value + * @acquire_lock: function to acquire a hardware lock on the bus + * @release_lock: function to release a hardware lock on the bus + * @semaphore_idx: Index of table with semaphore type attached to the bus. It's + * -1 if there is no semaphore. + * @shared_with_punit: true if this bus is shared with the SoCs PUNIT + * @init: function to initialize the I2C hardware + * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing + * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE + * @rinfo: I²C GPIO recovery information + * + * HCNT and LCNT parameters can be used if the platform knows more accurate + * values than the one computed based only on the input clock frequency. + * Leave them to be %0 if not used. + */ +struct dw_i2c_dev { + struct device *dev; + struct regmap *map; + struct regmap *sysmap; + void __iomem *base; + void __iomem *ext; + struct completion cmd_complete; + struct clk *clk; + struct clk *pclk; + struct reset_control *rst; + struct i2c_client *slave; + u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev); + int cmd_err; + struct i2c_msg *msgs; + int msgs_num; + int msg_write_idx; + u32 tx_buf_len; + u8 *tx_buf; + int msg_read_idx; + u32 rx_buf_len; + u8 *rx_buf; + int msg_err; + unsigned int status; + unsigned int abort_source; + unsigned int sw_mask; + int irq; + u32 flags; + struct i2c_adapter adapter; + u32 functionality; + u32 master_cfg; + u32 slave_cfg; + unsigned int tx_fifo_depth; + unsigned int rx_fifo_depth; + int rx_outstanding; + struct i2c_timings timings; + u32 sda_hold_time; + u16 ss_hcnt; + u16 ss_lcnt; + u16 fs_hcnt; + u16 fs_lcnt; + u16 fp_hcnt; + u16 fp_lcnt; + u16 hs_hcnt; + u16 hs_lcnt; + int (*acquire_lock)(void); + void (*release_lock)(void); + int semaphore_idx; + bool shared_with_punit; + int (*init)(struct dw_i2c_dev *dev); + int (*set_sda_hold_time)(struct dw_i2c_dev *dev); + int mode; + struct i2c_bus_recovery_info rinfo; +}; + +#define ACCESS_INTR_MASK BIT(0) +#define ACCESS_NO_IRQ_SUSPEND BIT(1) +#define ARBITRATION_SEMAPHORE BIT(2) +#define ACCESS_POLLING BIT(3) + +#define MODEL_MSCC_OCELOT BIT(8) +#define MODEL_BAIKAL_BT1 BIT(9) +#define MODEL_AMD_NAVI_GPU BIT(10) +#define MODEL_WANGXUN_SP BIT(11) +#define MODEL_MASK GENMASK(11, 8) + +/* + * Enable UCSI interrupt by writing 0xd at register + * offset 0x474 specified in hardware specification. + */ +#define AMD_UCSI_INTR_REG 0x474 +#define AMD_UCSI_INTR_EN 0xd + +#define TXGBE_TX_FIFO_DEPTH 4 +#define TXGBE_RX_FIFO_DEPTH 1 + +struct i2c_dw_semaphore_callbacks { + int (*probe)(struct dw_i2c_dev *dev); + void (*remove)(struct dw_i2c_dev *dev); +}; + +int i2c_dw_init_regmap(struct dw_i2c_dev *dev); +u32 i2c_dw_scl_hcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tSYMBOL, u32 tf, int cond, int offset); +u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tLOW, u32 tf, int offset); +int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev); +u32 i2c_dw_clk_rate(struct dw_i2c_dev *dev); +int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare); +int i2c_dw_acquire_lock(struct dw_i2c_dev *dev); +void i2c_dw_release_lock(struct dw_i2c_dev *dev); +int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); +int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); +int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); +u32 i2c_dw_func(struct i2c_adapter *adap); + +extern const struct dev_pm_ops i2c_dw_dev_pm_ops; + +static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) +{ + dev->status |= STATUS_ACTIVE; + regmap_write(dev->map, DW_IC_ENABLE, 1); +} + +static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev) +{ + regmap_write(dev->map, DW_IC_ENABLE, 0); + dev->status &= ~STATUS_ACTIVE; +} + +static inline void __i2c_dw_write_intr_mask(struct dw_i2c_dev *dev, + unsigned int intr_mask) +{ + unsigned int val = dev->flags & ACCESS_POLLING ? 0 : intr_mask; + + regmap_write(dev->map, DW_IC_INTR_MASK, val); + dev->sw_mask = intr_mask; +} + +static inline void __i2c_dw_read_intr_mask(struct dw_i2c_dev *dev, + unsigned int *intr_mask) +{ + if (!(dev->flags & ACCESS_POLLING)) + regmap_read(dev->map, DW_IC_INTR_MASK, intr_mask); + else + *intr_mask = dev->sw_mask; +} + +void __i2c_dw_disable(struct dw_i2c_dev *dev); +void i2c_dw_disable(struct dw_i2c_dev *dev); + +extern void i2c_dw_configure_master(struct dw_i2c_dev *dev); +extern int i2c_dw_probe_master(struct dw_i2c_dev *dev); + +#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_SLAVE) +extern void i2c_dw_configure_slave(struct dw_i2c_dev *dev); +extern int i2c_dw_probe_slave(struct dw_i2c_dev *dev); +#else +static inline void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { } +static inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; } +#endif + +static inline void i2c_dw_configure(struct dw_i2c_dev *dev) +{ + if (i2c_detect_slave_mode(dev->dev)) + i2c_dw_configure_slave(dev); + else + i2c_dw_configure_master(dev); +} + +int i2c_dw_probe(struct dw_i2c_dev *dev); + +#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL) +int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev); +#endif + +#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_AMDPSP) +int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev); +#endif + +int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-master.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-master.c new file mode 100644 index 0000000000..52dc666c3e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-master.c @@ -0,0 +1,1081 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Synopsys DesignWare I2C adapter driver (master only). + * + * Based on the TI DAVINCI I2C adapter driver. + * + * Copyright (C) 2006 Texas Instruments. + * Copyright (C) 2007 MontaVista Software Inc. + * Copyright (C) 2009 Provigent Ltd. + */ + +#define DEFAULT_SYMBOL_NAMESPACE "I2C_DW" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-designware-core.h" + +#define AMD_TIMEOUT_MIN_US 25 +#define AMD_TIMEOUT_MAX_US 250 +#define AMD_MASTERCFG_MASK GENMASK(15, 0) + +static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev) +{ + /* Configure Tx/Rx FIFO threshold levels */ + regmap_write(dev->map, DW_IC_TX_TL, dev->tx_fifo_depth / 2); + regmap_write(dev->map, DW_IC_RX_TL, 0); + + /* Configure the I2C master */ + regmap_write(dev->map, DW_IC_CON, dev->master_cfg); +} + +static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) +{ + unsigned int comp_param1; + u32 sda_falling_time, scl_falling_time; + struct i2c_timings *t = &dev->timings; + const char *fp_str = ""; + u32 ic_clk; + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &comp_param1); + i2c_dw_release_lock(dev); + if (ret) + return ret; + + /* Set standard and fast speed dividers for high/low periods */ + sda_falling_time = t->sda_fall_ns ?: 300; /* ns */ + scl_falling_time = t->scl_fall_ns ?: 300; /* ns */ + + /* Calculate SCL timing parameters for standard mode if not set */ + if (!dev->ss_hcnt || !dev->ss_lcnt) { + ic_clk = i2c_dw_clk_rate(dev); + dev->ss_hcnt = + i2c_dw_scl_hcnt(dev, + DW_IC_SS_SCL_HCNT, + ic_clk, + 4000, /* tHD;STA = tHIGH = 4.0 us */ + sda_falling_time, + 0, /* 0: DW default, 1: Ideal */ + 0); /* No offset */ + dev->ss_lcnt = + i2c_dw_scl_lcnt(dev, + DW_IC_SS_SCL_LCNT, + ic_clk, + 4700, /* tLOW = 4.7 us */ + scl_falling_time, + 0); /* No offset */ + } + dev_dbg(dev->dev, "Standard Mode HCNT:LCNT = %d:%d\n", + dev->ss_hcnt, dev->ss_lcnt); + + /* + * Set SCL timing parameters for fast mode or fast mode plus. Only + * difference is the timing parameter values since the registers are + * the same. + */ + if (t->bus_freq_hz == I2C_MAX_FAST_MODE_PLUS_FREQ) { + /* + * Check are Fast Mode Plus parameters available. Calculate + * SCL timing parameters for Fast Mode Plus if not set. + */ + if (dev->fp_hcnt && dev->fp_lcnt) { + dev->fs_hcnt = dev->fp_hcnt; + dev->fs_lcnt = dev->fp_lcnt; + } else { + ic_clk = i2c_dw_clk_rate(dev); + dev->fs_hcnt = + i2c_dw_scl_hcnt(dev, + DW_IC_FS_SCL_HCNT, + ic_clk, + 260, /* tHIGH = 260 ns */ + sda_falling_time, + 0, /* DW default */ + 0); /* No offset */ + dev->fs_lcnt = + i2c_dw_scl_lcnt(dev, + DW_IC_FS_SCL_LCNT, + ic_clk, + 500, /* tLOW = 500 ns */ + scl_falling_time, + 0); /* No offset */ + } + fp_str = " Plus"; + } + /* + * Calculate SCL timing parameters for fast mode if not set. They are + * needed also in high speed mode. + */ + if (!dev->fs_hcnt || !dev->fs_lcnt) { + ic_clk = i2c_dw_clk_rate(dev); + dev->fs_hcnt = + i2c_dw_scl_hcnt(dev, + DW_IC_FS_SCL_HCNT, + ic_clk, + 600, /* tHD;STA = tHIGH = 0.6 us */ + sda_falling_time, + 0, /* 0: DW default, 1: Ideal */ + 0); /* No offset */ + dev->fs_lcnt = + i2c_dw_scl_lcnt(dev, + DW_IC_FS_SCL_LCNT, + ic_clk, + 1300, /* tLOW = 1.3 us */ + scl_falling_time, + 0); /* No offset */ + } + dev_dbg(dev->dev, "Fast Mode%s HCNT:LCNT = %d:%d\n", + fp_str, dev->fs_hcnt, dev->fs_lcnt); + + /* Check is high speed possible and fall back to fast mode if not */ + if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) == + DW_IC_CON_SPEED_HIGH) { + if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK) + != DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH) { + dev_err(dev->dev, "High Speed not supported!\n"); + t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; + dev->master_cfg &= ~DW_IC_CON_SPEED_MASK; + dev->master_cfg |= DW_IC_CON_SPEED_FAST; + dev->hs_hcnt = 0; + dev->hs_lcnt = 0; + } else if (!dev->hs_hcnt || !dev->hs_lcnt) { + ic_clk = i2c_dw_clk_rate(dev); + dev->hs_hcnt = + i2c_dw_scl_hcnt(dev, + DW_IC_HS_SCL_HCNT, + ic_clk, + 160, /* tHIGH = 160 ns */ + sda_falling_time, + 0, /* DW default */ + 0); /* No offset */ + dev->hs_lcnt = + i2c_dw_scl_lcnt(dev, + DW_IC_HS_SCL_LCNT, + ic_clk, + 320, /* tLOW = 320 ns */ + scl_falling_time, + 0); /* No offset */ + } + dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n", + dev->hs_hcnt, dev->hs_lcnt); + } + + ret = i2c_dw_set_sda_hold(dev); + if (ret) + return ret; + + dev_dbg(dev->dev, "Bus speed: %s\n", i2c_freq_mode_string(t->bus_freq_hz)); + return 0; +} + +/** + * i2c_dw_init_master() - Initialize the designware I2C master hardware + * @dev: device private data + * + * This functions configures and enables the I2C master. + * This function is called during I2C init function, and in case of timeout at + * run time. + */ +static int i2c_dw_init_master(struct dw_i2c_dev *dev) +{ + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + /* Disable the adapter */ + __i2c_dw_disable(dev); + + /* Write standard speed timing parameters */ + regmap_write(dev->map, DW_IC_SS_SCL_HCNT, dev->ss_hcnt); + regmap_write(dev->map, DW_IC_SS_SCL_LCNT, dev->ss_lcnt); + + /* Write fast mode/fast mode plus timing parameters */ + regmap_write(dev->map, DW_IC_FS_SCL_HCNT, dev->fs_hcnt); + regmap_write(dev->map, DW_IC_FS_SCL_LCNT, dev->fs_lcnt); + + /* Write high speed timing parameters if supported */ + if (dev->hs_hcnt && dev->hs_lcnt) { + regmap_write(dev->map, DW_IC_HS_SCL_HCNT, dev->hs_hcnt); + regmap_write(dev->map, DW_IC_HS_SCL_LCNT, dev->hs_lcnt); + } + + /* Write SDA hold time if supported */ + if (dev->sda_hold_time) + regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time); + + i2c_dw_configure_fifo_master(dev); + i2c_dw_release_lock(dev); + + return 0; +} + +static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) +{ + struct i2c_msg *msgs = dev->msgs; + u32 ic_con = 0, ic_tar = 0; + unsigned int dummy; + + /* Disable the adapter */ + __i2c_dw_disable(dev); + + /* If the slave address is ten bit address, enable 10BITADDR */ + if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { + ic_con = DW_IC_CON_10BITADDR_MASTER; + /* + * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing + * mode has to be enabled via bit 12 of IC_TAR register. + * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be + * detected from registers. + */ + ic_tar = DW_IC_TAR_10BITADDR_MASTER; + } + + regmap_update_bits(dev->map, DW_IC_CON, DW_IC_CON_10BITADDR_MASTER, + ic_con); + + /* + * Set the slave (target) address and enable 10-bit addressing mode + * if applicable. + */ + regmap_write(dev->map, DW_IC_TAR, + msgs[dev->msg_write_idx].addr | ic_tar); + + /* Enforce disabled interrupts (due to HW issues) */ + __i2c_dw_write_intr_mask(dev, 0); + + /* Enable the adapter */ + __i2c_dw_enable(dev); + + /* Dummy read to avoid the register getting stuck on Bay Trail */ + regmap_read(dev->map, DW_IC_ENABLE_STATUS, &dummy); + + /* Clear and enable interrupts */ + regmap_read(dev->map, DW_IC_CLR_INTR, &dummy); + __i2c_dw_write_intr_mask(dev, DW_IC_INTR_MASTER_MASK); +} + +/* + * This function waits for the controller to be idle before disabling I2C + * When the controller is not in the IDLE state, the MST_ACTIVITY bit + * (IC_STATUS[5]) is set. + * + * Values: + * 0x1 (ACTIVE): Controller not idle + * 0x0 (IDLE): Controller is idle + * + * The function is called after completing the current transfer. + * + * Returns: + * False when the controller is in the IDLE state. + * True when the controller is in the ACTIVE state. + */ +static bool i2c_dw_is_controller_active(struct dw_i2c_dev *dev) +{ + u32 status; + + regmap_read(dev->map, DW_IC_STATUS, &status); + if (!(status & DW_IC_STATUS_MASTER_ACTIVITY)) + return false; + + return regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status, + !(status & DW_IC_STATUS_MASTER_ACTIVITY), + 1100, 20000) != 0; +} + +static int i2c_dw_check_stopbit(struct dw_i2c_dev *dev) +{ + u32 val; + int ret; + + ret = regmap_read_poll_timeout(dev->map, DW_IC_INTR_STAT, val, + !(val & DW_IC_INTR_STOP_DET), + 1100, 20000); + if (ret) + dev_err(dev->dev, "i2c timeout error %d\n", ret); + + return ret; +} + +static int i2c_dw_status(struct dw_i2c_dev *dev) +{ + int status; + + status = i2c_dw_wait_bus_not_busy(dev); + if (status) + return status; + + return i2c_dw_check_stopbit(dev); +} + +/* + * Initiate and continue master read/write transaction with polling + * based transfer routine afterward write messages into the Tx buffer. + */ +static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, int num_msgs) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + int msg_wrt_idx, msg_itr_lmt, buf_len, data_idx; + int cmd = 0, status; + u8 *tx_buf; + unsigned int val; + + /* + * In order to enable the interrupt for UCSI i.e. AMD NAVI GPU card, + * it is mandatory to set the right value in specific register + * (offset:0x474) as per the hardware IP specification. + */ + regmap_write(dev->map, AMD_UCSI_INTR_REG, AMD_UCSI_INTR_EN); + + dev->msgs = msgs; + dev->msgs_num = num_msgs; + dev->msg_write_idx = 0; + i2c_dw_xfer_init(dev); + + /* Initiate messages read/write transaction */ + for (msg_wrt_idx = 0; msg_wrt_idx < num_msgs; msg_wrt_idx++) { + tx_buf = msgs[msg_wrt_idx].buf; + buf_len = msgs[msg_wrt_idx].len; + + if (!(msgs[msg_wrt_idx].flags & I2C_M_RD)) + regmap_write(dev->map, DW_IC_TX_TL, buf_len - 1); + /* + * Initiate the i2c read/write transaction of buffer length, + * and poll for bus busy status. For the last message transfer, + * update the command with stopbit enable. + */ + for (msg_itr_lmt = buf_len; msg_itr_lmt > 0; msg_itr_lmt--) { + if (msg_wrt_idx == num_msgs - 1 && msg_itr_lmt == 1) + cmd |= BIT(9); + + if (msgs[msg_wrt_idx].flags & I2C_M_RD) { + /* Due to hardware bug, need to write the same command twice. */ + regmap_write(dev->map, DW_IC_DATA_CMD, 0x100); + regmap_write(dev->map, DW_IC_DATA_CMD, 0x100 | cmd); + if (cmd) { + regmap_write(dev->map, DW_IC_TX_TL, 2 * (buf_len - 1)); + regmap_write(dev->map, DW_IC_RX_TL, 2 * (buf_len - 1)); + /* + * Need to check the stop bit. However, it cannot be + * detected from the registers so we check it always + * when read/write the last byte. + */ + status = i2c_dw_status(dev); + if (status) + return status; + + for (data_idx = 0; data_idx < buf_len; data_idx++) { + regmap_read(dev->map, DW_IC_DATA_CMD, &val); + tx_buf[data_idx] = val; + } + status = i2c_dw_check_stopbit(dev); + if (status) + return status; + } + } else { + regmap_write(dev->map, DW_IC_DATA_CMD, *tx_buf++ | cmd); + usleep_range(AMD_TIMEOUT_MIN_US, AMD_TIMEOUT_MAX_US); + } + } + status = i2c_dw_check_stopbit(dev); + if (status) + return status; + } + + return 0; +} + +/* + * Initiate (and continue) low level master read/write transaction. + * This function is only called from i2c_dw_isr, and pumping i2c_msg + * messages into the tx buffer. Even if the size of i2c_msg data is + * longer than the size of the tx buffer, it handles everything. + */ +static void +i2c_dw_xfer_msg(struct dw_i2c_dev *dev) +{ + struct i2c_msg *msgs = dev->msgs; + u32 intr_mask; + int tx_limit, rx_limit; + u32 addr = msgs[dev->msg_write_idx].addr; + u32 buf_len = dev->tx_buf_len; + u8 *buf = dev->tx_buf; + bool need_restart = false; + unsigned int flr; + + intr_mask = DW_IC_INTR_MASTER_MASK; + + for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { + u32 flags = msgs[dev->msg_write_idx].flags; + + /* + * If target address has changed, we need to + * reprogram the target address in the I2C + * adapter when we are done with this transfer. + */ + if (msgs[dev->msg_write_idx].addr != addr) { + dev_err(dev->dev, + "%s: invalid target address\n", __func__); + dev->msg_err = -EINVAL; + break; + } + + if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { + /* new i2c_msg */ + buf = msgs[dev->msg_write_idx].buf; + buf_len = msgs[dev->msg_write_idx].len; + + /* If both IC_EMPTYFIFO_HOLD_MASTER_EN and + * IC_RESTART_EN are set, we must manually + * set restart bit between messages. + */ + if ((dev->master_cfg & DW_IC_CON_RESTART_EN) && + (dev->msg_write_idx > 0)) + need_restart = true; + } + + regmap_read(dev->map, DW_IC_TXFLR, &flr); + tx_limit = dev->tx_fifo_depth - flr; + + regmap_read(dev->map, DW_IC_RXFLR, &flr); + rx_limit = dev->rx_fifo_depth - flr; + + while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { + u32 cmd = 0; + + /* + * If IC_EMPTYFIFO_HOLD_MASTER_EN is set we must + * manually set the stop bit. However, it cannot be + * detected from the registers so we set it always + * when writing/reading the last byte. + */ + + /* + * i2c-core always sets the buffer length of + * I2C_FUNC_SMBUS_BLOCK_DATA to 1. The length will + * be adjusted when receiving the first byte. + * Thus we can't stop the transaction here. + */ + if (dev->msg_write_idx == dev->msgs_num - 1 && + buf_len == 1 && !(flags & I2C_M_RECV_LEN)) + cmd |= BIT(9); + + if (need_restart) { + cmd |= BIT(10); + need_restart = false; + } + + if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { + + /* Avoid rx buffer overrun */ + if (dev->rx_outstanding >= dev->rx_fifo_depth) + break; + + regmap_write(dev->map, DW_IC_DATA_CMD, + cmd | 0x100); + rx_limit--; + dev->rx_outstanding++; + } else { + regmap_write(dev->map, DW_IC_DATA_CMD, + cmd | *buf++); + } + tx_limit--; buf_len--; + } + + dev->tx_buf = buf; + dev->tx_buf_len = buf_len; + + /* + * Because we don't know the buffer length in the + * I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop the + * transaction here. Also disable the TX_EMPTY IRQ + * while waiting for the data length byte to avoid the + * bogus interrupts flood. + */ + if (flags & I2C_M_RECV_LEN) { + dev->status |= STATUS_WRITE_IN_PROGRESS; + intr_mask &= ~DW_IC_INTR_TX_EMPTY; + break; + } else if (buf_len > 0) { + /* more bytes to be written */ + dev->status |= STATUS_WRITE_IN_PROGRESS; + break; + } else + dev->status &= ~STATUS_WRITE_IN_PROGRESS; + } + + /* + * If i2c_msg index search is completed, we don't need TX_EMPTY + * interrupt any more. + */ + if (dev->msg_write_idx == dev->msgs_num) + intr_mask &= ~DW_IC_INTR_TX_EMPTY; + + if (dev->msg_err) + intr_mask = 0; + + __i2c_dw_write_intr_mask(dev, intr_mask); +} + +static u8 +i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len) +{ + struct i2c_msg *msgs = dev->msgs; + u32 flags = msgs[dev->msg_read_idx].flags; + unsigned int intr_mask; + + /* + * Adjust the buffer length and mask the flag + * after receiving the first byte. + */ + len += (flags & I2C_CLIENT_PEC) ? 2 : 1; + dev->tx_buf_len = len - min_t(u8, len, dev->rx_outstanding); + msgs[dev->msg_read_idx].len = len; + msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN; + + /* + * Received buffer length, re-enable TX_EMPTY interrupt + * to resume the SMBUS transaction. + */ + __i2c_dw_read_intr_mask(dev, &intr_mask); + intr_mask |= DW_IC_INTR_TX_EMPTY; + __i2c_dw_write_intr_mask(dev, intr_mask); + + return len; +} + +static void +i2c_dw_read(struct dw_i2c_dev *dev) +{ + struct i2c_msg *msgs = dev->msgs; + unsigned int rx_valid; + + for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { + unsigned int tmp; + u32 len; + u8 *buf; + + if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) + continue; + + if (!(dev->status & STATUS_READ_IN_PROGRESS)) { + len = msgs[dev->msg_read_idx].len; + buf = msgs[dev->msg_read_idx].buf; + } else { + len = dev->rx_buf_len; + buf = dev->rx_buf; + } + + regmap_read(dev->map, DW_IC_RXFLR, &rx_valid); + + for (; len > 0 && rx_valid > 0; len--, rx_valid--) { + u32 flags = msgs[dev->msg_read_idx].flags; + + regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); + tmp &= DW_IC_DATA_CMD_DAT; + /* Ensure length byte is a valid value */ + if (flags & I2C_M_RECV_LEN) { + /* + * if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be + * detected from the registers, the controller can be + * disabled if the STOP bit is set. But it is only set + * after receiving block data response length in + * I2C_FUNC_SMBUS_BLOCK_DATA case. That needs to read + * another byte with STOP bit set when the block data + * response length is invalid to complete the transaction. + */ + if (!tmp || tmp > I2C_SMBUS_BLOCK_MAX) + tmp = 1; + + len = i2c_dw_recv_len(dev, tmp); + } + *buf++ = tmp; + dev->rx_outstanding--; + } + + if (len > 0) { + dev->status |= STATUS_READ_IN_PROGRESS; + dev->rx_buf_len = len; + dev->rx_buf = buf; + return; + } else + dev->status &= ~STATUS_READ_IN_PROGRESS; + } +} + +static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) +{ + unsigned int stat, dummy; + + /* + * The IC_INTR_STAT register just indicates "enabled" interrupts. + * The unmasked raw version of interrupt status bits is available + * in the IC_RAW_INTR_STAT register. + * + * That is, + * stat = readl(IC_INTR_STAT); + * equals to, + * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK); + * + * The raw version might be useful for debugging purposes. + */ + if (!(dev->flags & ACCESS_POLLING)) { + regmap_read(dev->map, DW_IC_INTR_STAT, &stat); + } else { + regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat); + stat &= dev->sw_mask; + } + + /* + * Do not use the IC_CLR_INTR register to clear interrupts, or + * you'll miss some interrupts, triggered during the period from + * readl(IC_INTR_STAT) to readl(IC_CLR_INTR). + * + * Instead, use the separately-prepared IC_CLR_* registers. + */ + if (stat & DW_IC_INTR_RX_UNDER) + regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &dummy); + if (stat & DW_IC_INTR_RX_OVER) + regmap_read(dev->map, DW_IC_CLR_RX_OVER, &dummy); + if (stat & DW_IC_INTR_TX_OVER) + regmap_read(dev->map, DW_IC_CLR_TX_OVER, &dummy); + if (stat & DW_IC_INTR_RD_REQ) + regmap_read(dev->map, DW_IC_CLR_RD_REQ, &dummy); + if (stat & DW_IC_INTR_TX_ABRT) { + /* + * The IC_TX_ABRT_SOURCE register is cleared whenever + * the IC_CLR_TX_ABRT is read. Preserve it beforehand. + */ + regmap_read(dev->map, DW_IC_TX_ABRT_SOURCE, &dev->abort_source); + regmap_read(dev->map, DW_IC_CLR_TX_ABRT, &dummy); + } + if (stat & DW_IC_INTR_RX_DONE) + regmap_read(dev->map, DW_IC_CLR_RX_DONE, &dummy); + if (stat & DW_IC_INTR_ACTIVITY) + regmap_read(dev->map, DW_IC_CLR_ACTIVITY, &dummy); + if ((stat & DW_IC_INTR_STOP_DET) && + ((dev->rx_outstanding == 0) || (stat & DW_IC_INTR_RX_FULL))) + regmap_read(dev->map, DW_IC_CLR_STOP_DET, &dummy); + if (stat & DW_IC_INTR_START_DET) + regmap_read(dev->map, DW_IC_CLR_START_DET, &dummy); + if (stat & DW_IC_INTR_GEN_CALL) + regmap_read(dev->map, DW_IC_CLR_GEN_CALL, &dummy); + + return stat; +} + +static void i2c_dw_process_transfer(struct dw_i2c_dev *dev, unsigned int stat) +{ + if (stat & DW_IC_INTR_TX_ABRT) { + dev->cmd_err |= DW_IC_ERR_TX_ABRT; + dev->status &= ~STATUS_MASK; + dev->rx_outstanding = 0; + + /* + * Anytime TX_ABRT is set, the contents of the tx/rx + * buffers are flushed. Make sure to skip them. + */ + __i2c_dw_write_intr_mask(dev, 0); + goto tx_aborted; + } + + if (stat & DW_IC_INTR_RX_FULL) + i2c_dw_read(dev); + + if (stat & DW_IC_INTR_TX_EMPTY) + i2c_dw_xfer_msg(dev); + + /* + * No need to modify or disable the interrupt mask here. + * i2c_dw_xfer_msg() will take care of it according to + * the current transmit status. + */ + +tx_aborted: + if (((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) && + (dev->rx_outstanding == 0)) + complete(&dev->cmd_complete); + else if (unlikely(dev->flags & ACCESS_INTR_MASK)) { + /* Workaround to trigger pending interrupt */ + __i2c_dw_read_intr_mask(dev, &stat); + __i2c_dw_write_intr_mask(dev, 0); + __i2c_dw_write_intr_mask(dev, stat); + } +} + +/* + * Interrupt service routine. This gets called whenever an I2C master interrupt + * occurs. + */ +static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) +{ + struct dw_i2c_dev *dev = dev_id; + unsigned int stat, enabled; + + regmap_read(dev->map, DW_IC_ENABLE, &enabled); + regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat); + if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) + return IRQ_NONE; + if (pm_runtime_suspended(dev->dev) || stat == GENMASK(31, 0)) + return IRQ_NONE; + dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat); + + stat = i2c_dw_read_clear_intrbits(dev); + + if (!(dev->status & STATUS_ACTIVE)) { + /* + * Unexpected interrupt in driver point of view. State + * variables are either unset or stale so acknowledge and + * disable interrupts for suppressing further interrupts if + * interrupt really came from this HW (E.g. firmware has left + * the HW active). + */ + __i2c_dw_write_intr_mask(dev, 0); + return IRQ_HANDLED; + } + + i2c_dw_process_transfer(dev, stat); + + return IRQ_HANDLED; +} + +static int i2c_dw_wait_transfer(struct dw_i2c_dev *dev) +{ + unsigned long timeout = dev->adapter.timeout; + unsigned int stat; + int ret; + + if (!(dev->flags & ACCESS_POLLING)) { + ret = wait_for_completion_timeout(&dev->cmd_complete, timeout); + } else { + timeout += jiffies; + do { + ret = try_wait_for_completion(&dev->cmd_complete); + if (ret) + break; + + stat = i2c_dw_read_clear_intrbits(dev); + if (stat) + i2c_dw_process_transfer(dev, stat); + else + /* Try save some power */ + usleep_range(3, 25); + } while (time_before(jiffies, timeout)); + } + + return ret ? 0 : -ETIMEDOUT; +} + +/* + * Prepare controller for a transaction and call i2c_dw_xfer_msg. + */ +static int +i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + int ret; + + dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); + + pm_runtime_get_sync(dev->dev); + + switch (dev->flags & MODEL_MASK) { + case MODEL_AMD_NAVI_GPU: + ret = amd_i2c_dw_xfer_quirk(adap, msgs, num); + goto done_nolock; + default: + break; + } + + reinit_completion(&dev->cmd_complete); + dev->msgs = msgs; + dev->msgs_num = num; + dev->cmd_err = 0; + dev->msg_write_idx = 0; + dev->msg_read_idx = 0; + dev->msg_err = 0; + dev->status = 0; + dev->abort_source = 0; + dev->rx_outstanding = 0; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + goto done_nolock; + + ret = i2c_dw_wait_bus_not_busy(dev); + if (ret < 0) + goto done; + + /* Start the transfers */ + i2c_dw_xfer_init(dev); + + /* Wait for tx to complete */ + ret = i2c_dw_wait_transfer(dev); + if (ret) { + dev_err(dev->dev, "controller timed out\n"); + /* i2c_dw_init_master() implicitly disables the adapter */ + i2c_recover_bus(&dev->adapter); + i2c_dw_init_master(dev); + goto done; + } + + /* + * This happens rarely (~1:500) and is hard to reproduce. Debug trace + * showed that IC_STATUS had value of 0x23 when STOP_DET occurred, + * if disable IC_ENABLE.ENABLE immediately that can result in + * IC_RAW_INTR_STAT.MASTER_ON_HOLD holding SCL low. Check if + * controller is still ACTIVE before disabling I2C. + */ + if (i2c_dw_is_controller_active(dev)) + dev_err(dev->dev, "controller active\n"); + + /* + * We must disable the adapter before returning and signaling the end + * of the current transfer. Otherwise the hardware might continue + * generating interrupts which in turn causes a race condition with + * the following transfer. Needs some more investigation if the + * additional interrupts are a hardware bug or this driver doesn't + * handle them correctly yet. + */ + __i2c_dw_disable_nowait(dev); + + if (dev->msg_err) { + ret = dev->msg_err; + goto done; + } + + /* No error */ + if (likely(!dev->cmd_err && !dev->status)) { + ret = num; + goto done; + } + + /* We have an error */ + if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { + ret = i2c_dw_handle_tx_abort(dev); + goto done; + } + + if (dev->status) + dev_err(dev->dev, + "transfer terminated early - interrupt latency too high?\n"); + + ret = -EIO; + +done: + i2c_dw_release_lock(dev); + +done_nolock: + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + + return ret; +} + +static const struct i2c_algorithm i2c_dw_algo = { + .master_xfer = i2c_dw_xfer, + .functionality = i2c_dw_func, +}; + +static const struct i2c_adapter_quirks i2c_dw_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN, +}; + +void i2c_dw_configure_master(struct dw_i2c_dev *dev) +{ + struct i2c_timings *t = &dev->timings; + + dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; + + dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | + DW_IC_CON_RESTART_EN; + + dev->mode = DW_IC_MASTER; + + switch (t->bus_freq_hz) { + case I2C_MAX_STANDARD_MODE_FREQ: + dev->master_cfg |= DW_IC_CON_SPEED_STD; + break; + case I2C_MAX_HIGH_SPEED_MODE_FREQ: + dev->master_cfg |= DW_IC_CON_SPEED_HIGH; + break; + default: + dev->master_cfg |= DW_IC_CON_SPEED_FAST; + } +} +EXPORT_SYMBOL_GPL(i2c_dw_configure_master); + +static void i2c_dw_prepare_recovery(struct i2c_adapter *adap) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + + i2c_dw_disable(dev); + reset_control_assert(dev->rst); + i2c_dw_prepare_clk(dev, false); +} + +static void i2c_dw_unprepare_recovery(struct i2c_adapter *adap) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + + i2c_dw_prepare_clk(dev, true); + reset_control_deassert(dev->rst); + i2c_dw_init_master(dev); +} + +static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) +{ + struct i2c_bus_recovery_info *rinfo = &dev->rinfo; + struct i2c_adapter *adap = &dev->adapter; + struct gpio_desc *gpio; + + gpio = devm_gpiod_get_optional(dev->dev, "scl", GPIOD_OUT_HIGH); + if (IS_ERR_OR_NULL(gpio)) + return PTR_ERR_OR_ZERO(gpio); + + rinfo->scl_gpiod = gpio; + + gpio = devm_gpiod_get_optional(dev->dev, "sda", GPIOD_IN); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + rinfo->sda_gpiod = gpio; + + rinfo->pinctrl = devm_pinctrl_get(dev->dev); + if (IS_ERR(rinfo->pinctrl)) { + if (PTR_ERR(rinfo->pinctrl) == -EPROBE_DEFER) + return PTR_ERR(rinfo->pinctrl); + + rinfo->pinctrl = NULL; + dev_err(dev->dev, "getting pinctrl info failed: bus recovery might not work\n"); + } else if (!rinfo->pinctrl) { + dev_dbg(dev->dev, "pinctrl is disabled, bus recovery might not work\n"); + } + + rinfo->recover_bus = i2c_generic_scl_recovery; + rinfo->prepare_recovery = i2c_dw_prepare_recovery; + rinfo->unprepare_recovery = i2c_dw_unprepare_recovery; + adap->bus_recovery_info = rinfo; + + dev_info(dev->dev, "running with gpio recovery mode! scl%s", + rinfo->sda_gpiod ? ",sda" : ""); + + return 0; +} + +int i2c_dw_probe_master(struct dw_i2c_dev *dev) +{ + struct i2c_adapter *adap = &dev->adapter; + unsigned long irq_flags; + unsigned int ic_con; + int ret; + + init_completion(&dev->cmd_complete); + + dev->init = i2c_dw_init_master; + + ret = i2c_dw_init_regmap(dev); + if (ret) + return ret; + + ret = i2c_dw_set_timings_master(dev); + if (ret) + return ret; + + ret = i2c_dw_set_fifo_size(dev); + if (ret) + return ret; + + /* Lock the bus for accessing DW_IC_CON */ + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + /* + * On AMD platforms BIOS advertises the bus clear feature + * and enables the SCL/SDA stuck low. SMU FW does the + * bus recovery process. Driver should not ignore this BIOS + * advertisement of bus clear feature. + */ + ret = regmap_read(dev->map, DW_IC_CON, &ic_con); + i2c_dw_release_lock(dev); + if (ret) + return ret; + + if (ic_con & DW_IC_CON_BUS_CLEAR_CTRL) + dev->master_cfg |= DW_IC_CON_BUS_CLEAR_CTRL; + + ret = dev->init(dev); + if (ret) + return ret; + + snprintf(adap->name, sizeof(adap->name), + "Synopsys DesignWare I2C adapter"); + adap->retries = 3; + adap->algo = &i2c_dw_algo; + adap->quirks = &i2c_dw_quirks; + adap->dev.parent = dev->dev; + i2c_set_adapdata(adap, dev); + + if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { + irq_flags = IRQF_NO_SUSPEND; + } else { + irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; + } + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + __i2c_dw_write_intr_mask(dev, 0); + i2c_dw_release_lock(dev); + + if (!(dev->flags & ACCESS_POLLING)) { + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, + irq_flags, dev_name(dev->dev), dev); + if (ret) { + dev_err(dev->dev, "failure requesting irq %i: %d\n", + dev->irq, ret); + return ret; + } + } + + ret = i2c_dw_init_recovery_info(dev); + if (ret) + return ret; + + /* + * Increment PM usage count during adapter registration in order to + * avoid possible spurious runtime suspend when adapter device is + * registered to the device core and immediate resume in case bus has + * registered I2C slaves that do I2C transfers in their probe. + */ + pm_runtime_get_noresume(dev->dev); + ret = i2c_add_numbered_adapter(adap); + if (ret) + dev_err(dev->dev, "failure adding adapter: %d\n", ret); + pm_runtime_put_noidle(dev->dev); + + return ret; +} +EXPORT_SYMBOL_GPL(i2c_dw_probe_master); + +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus master adapter"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-pcidrv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-pcidrv.c new file mode 100644 index 0000000000..5ea6d40373 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-pcidrv.c @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Synopsys DesignWare I2C adapter driver (master only). + * + * Based on the TI DAVINCI I2C adapter driver. + * + * Copyright (C) 2006 Texas Instruments. + * Copyright (C) 2007 MontaVista Software Inc. + * Copyright (C) 2009 Provigent Ltd. + * Copyright (C) 2011, 2015, 2016 Intel Corporation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-designware-core.h" +#include "i2c-ccgx-ucsi.h" + +#define DRIVER_NAME "i2c-designware-pci" + +enum dw_pci_ctl_id_t { + medfield, + merrifield, + baytrail, + cherrytrail, + haswell, + elkhartlake, + navi_amd, +}; + +/* + * This is a legacy structure to describe the hardware counters + * to configure signal timings on the bus. For Device Tree platforms + * one should use the respective properties and for ACPI there is + * a set of ACPI methods that provide these counters. No new + * platform should use this structure. + */ +struct dw_scl_sda_cfg { + u16 ss_hcnt; + u16 fs_hcnt; + u16 ss_lcnt; + u16 fs_lcnt; + u32 sda_hold; +}; + +struct dw_pci_controller { + u32 bus_num; + u32 flags; + struct dw_scl_sda_cfg *scl_sda_cfg; + int (*setup)(struct pci_dev *pdev, struct dw_pci_controller *c); + u32 (*get_clk_rate_khz)(struct dw_i2c_dev *dev); +}; + +/* Merrifield HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg mrfld_config = { + .ss_hcnt = 0x2f8, + .fs_hcnt = 0x87, + .ss_lcnt = 0x37b, + .fs_lcnt = 0x10a, +}; + +/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = { + .ss_hcnt = 0x200, + .fs_hcnt = 0x55, + .ss_lcnt = 0x200, + .fs_lcnt = 0x99, + .sda_hold = 0x6, +}; + +/* Haswell HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg hsw_config = { + .ss_hcnt = 0x01b0, + .fs_hcnt = 0x48, + .ss_lcnt = 0x01fb, + .fs_lcnt = 0xa0, + .sda_hold = 0x9, +}; + +/* NAVI-AMD HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg navi_amd_config = { + .ss_hcnt = 0x1ae, + .ss_lcnt = 0x23a, + .sda_hold = 0x9, +}; + +static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev) +{ + return 25000; +} + +static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c) +{ + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); + + switch (pdev->device) { + case 0x0817: + dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; + fallthrough; + case 0x0818: + case 0x0819: + c->bus_num = pdev->device - 0x817 + 3; + return 0; + case 0x082C: + case 0x082D: + case 0x082E: + c->bus_num = pdev->device - 0x82C + 0; + return 0; + } + return -ENODEV; +} + +static int mrfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c) +{ + /* + * On Intel Merrifield the user visible i2c buses are enumerated + * [1..7]. So, we add 1 to shift the default range. Besides that the + * first PCI slot provides 4 functions, that's why we have to add 0 to + * the first slot and 4 to the next one. + */ + switch (PCI_SLOT(pdev->devfn)) { + case 8: + c->bus_num = PCI_FUNC(pdev->devfn) + 0 + 1; + return 0; + case 9: + c->bus_num = PCI_FUNC(pdev->devfn) + 4 + 1; + return 0; + } + return -ENODEV; +} + +static u32 ehl_get_clk_rate_khz(struct dw_i2c_dev *dev) +{ + return 100000; +} + +static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev) +{ + return 100000; +} + +static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c) +{ + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); + + dev->flags |= MODEL_AMD_NAVI_GPU | ACCESS_POLLING; + dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; + return 0; +} + +static struct dw_pci_controller dw_pci_controllers[] = { + [medfield] = { + .bus_num = -1, + .setup = mfld_setup, + .get_clk_rate_khz = mfld_get_clk_rate_khz, + }, + [merrifield] = { + .bus_num = -1, + .scl_sda_cfg = &mrfld_config, + .setup = mrfld_setup, + }, + [baytrail] = { + .bus_num = -1, + .scl_sda_cfg = &byt_config, + }, + [haswell] = { + .bus_num = -1, + .scl_sda_cfg = &hsw_config, + }, + [cherrytrail] = { + .bus_num = -1, + .scl_sda_cfg = &byt_config, + }, + [elkhartlake] = { + .bus_num = -1, + .get_clk_rate_khz = ehl_get_clk_rate_khz, + }, + [navi_amd] = { + .bus_num = -1, + .scl_sda_cfg = &navi_amd_config, + .setup = navi_amd_setup, + .get_clk_rate_khz = navi_amd_get_clk_rate_khz, + }, +}; + +static const struct property_entry dgpu_properties[] = { + /* USB-C doesn't power the system */ + PROPERTY_ENTRY_U8("scope", POWER_SUPPLY_SCOPE_DEVICE), + {} +}; + +static const struct software_node dgpu_node = { + .properties = dgpu_properties, +}; + +static int i2c_dw_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct device *device = &pdev->dev; + struct dw_i2c_dev *dev; + struct i2c_adapter *adap; + int r; + struct dw_pci_controller *controller; + struct dw_scl_sda_cfg *cfg; + + if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) + return dev_err_probe(device, -EINVAL, "Invalid driver data %ld\n", + id->driver_data); + + controller = &dw_pci_controllers[id->driver_data]; + + r = pcim_enable_device(pdev); + if (r) + return dev_err_probe(device, r, "Failed to enable I2C PCI device\n"); + + pci_set_master(pdev); + + r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); + if (r) + return dev_err_probe(device, r, "I/O memory remapping failed\n"); + + dev = devm_kzalloc(device, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + r = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (r < 0) + return r; + + dev->get_clk_rate_khz = controller->get_clk_rate_khz; + dev->base = pcim_iomap_table(pdev)[0]; + dev->dev = device; + dev->irq = pci_irq_vector(pdev, 0); + dev->flags |= controller->flags; + + pci_set_drvdata(pdev, dev); + + if (controller->setup) { + r = controller->setup(pdev, controller); + if (r) + return r; + } + + r = i2c_dw_fw_parse_and_configure(dev); + if (r) + return r; + + i2c_dw_configure(dev); + + if (controller->scl_sda_cfg) { + cfg = controller->scl_sda_cfg; + dev->ss_hcnt = cfg->ss_hcnt; + dev->fs_hcnt = cfg->fs_hcnt; + dev->ss_lcnt = cfg->ss_lcnt; + dev->fs_lcnt = cfg->fs_lcnt; + dev->sda_hold_time = cfg->sda_hold; + } + + adap = &dev->adapter; + adap->owner = THIS_MODULE; + adap->class = 0; + adap->nr = controller->bus_num; + + r = i2c_dw_probe(dev); + if (r) + return r; + + if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { + dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, &dgpu_node); + if (IS_ERR(dev->slave)) { + i2c_del_adapter(&dev->adapter); + return dev_err_probe(device, PTR_ERR(dev->slave), + "register UCSI failed\n"); + } + } + + pm_runtime_set_autosuspend_delay(device, 1000); + pm_runtime_use_autosuspend(device); + pm_runtime_put_autosuspend(device); + pm_runtime_allow(device); + + return 0; +} + +static void i2c_dw_pci_remove(struct pci_dev *pdev) +{ + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); + struct device *device = &pdev->dev; + + i2c_dw_disable(dev); + + pm_runtime_forbid(device); + pm_runtime_get_noresume(device); + + i2c_del_adapter(&dev->adapter); +} + +static const struct pci_device_id i2c_designware_pci_ids[] = { + /* Medfield */ + { PCI_VDEVICE(INTEL, 0x0817), medfield }, + { PCI_VDEVICE(INTEL, 0x0818), medfield }, + { PCI_VDEVICE(INTEL, 0x0819), medfield }, + { PCI_VDEVICE(INTEL, 0x082C), medfield }, + { PCI_VDEVICE(INTEL, 0x082D), medfield }, + { PCI_VDEVICE(INTEL, 0x082E), medfield }, + /* Merrifield */ + { PCI_VDEVICE(INTEL, 0x1195), merrifield }, + { PCI_VDEVICE(INTEL, 0x1196), merrifield }, + /* Baytrail */ + { PCI_VDEVICE(INTEL, 0x0F41), baytrail }, + { PCI_VDEVICE(INTEL, 0x0F42), baytrail }, + { PCI_VDEVICE(INTEL, 0x0F43), baytrail }, + { PCI_VDEVICE(INTEL, 0x0F44), baytrail }, + { PCI_VDEVICE(INTEL, 0x0F45), baytrail }, + { PCI_VDEVICE(INTEL, 0x0F46), baytrail }, + { PCI_VDEVICE(INTEL, 0x0F47), baytrail }, + /* Haswell */ + { PCI_VDEVICE(INTEL, 0x9c61), haswell }, + { PCI_VDEVICE(INTEL, 0x9c62), haswell }, + /* Braswell / Cherrytrail */ + { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail }, + { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail }, + { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail }, + { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail }, + { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail }, + { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail }, + { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail }, + /* Elkhart Lake (PSE I2C) */ + { PCI_VDEVICE(INTEL, 0x4bb9), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bba), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bbb), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bbc), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bbd), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bbe), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bbf), elkhartlake }, + { PCI_VDEVICE(INTEL, 0x4bc0), elkhartlake }, + /* AMD NAVI */ + { PCI_VDEVICE(ATI, 0x7314), navi_amd }, + { PCI_VDEVICE(ATI, 0x73a4), navi_amd }, + { PCI_VDEVICE(ATI, 0x73e4), navi_amd }, + { PCI_VDEVICE(ATI, 0x73c4), navi_amd }, + { PCI_VDEVICE(ATI, 0x7444), navi_amd }, + { PCI_VDEVICE(ATI, 0x7464), navi_amd }, + {} +}; +MODULE_DEVICE_TABLE(pci, i2c_designware_pci_ids); + +static struct pci_driver dw_i2c_driver = { + .name = DRIVER_NAME, + .probe = i2c_dw_pci_probe, + .remove = i2c_dw_pci_remove, + .driver = { + .pm = pm_ptr(&i2c_dw_dev_pm_ops), + }, + .id_table = i2c_designware_pci_ids, +}; +module_pci_driver(dw_i2c_driver); + +MODULE_AUTHOR("Baruch Siach "); +MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(I2C_DW); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-platdrv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-platdrv.c new file mode 100644 index 0000000000..afa4d729db --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-platdrv.c @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Synopsys DesignWare I2C adapter driver. + * + * Based on the TI DAVINCI I2C adapter driver. + * + * Copyright (C) 2006 Texas Instruments. + * Copyright (C) 2007 MontaVista Software Inc. + * Copyright (C) 2009 Provigent Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-designware-core.h" + +static int sda_fall_ns = 0; +module_param(sda_fall_ns, int, S_IRUGO); +static int scl_fall_ns = 0; +module_param(scl_fall_ns, int, S_IRUGO); +static int bus_freq_hz = 0; +module_param(bus_freq_hz, int, S_IRUGO); + +static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) +{ + return clk_get_rate(dev->clk) / KILO; +} + +#ifdef CONFIG_OF +#define BT1_I2C_CTL 0x100 +#define BT1_I2C_CTL_ADDR_MASK GENMASK(7, 0) +#define BT1_I2C_CTL_WR BIT(8) +#define BT1_I2C_CTL_GO BIT(31) +#define BT1_I2C_DI 0x104 +#define BT1_I2C_DO 0x108 + +static int bt1_i2c_read(void *context, unsigned int reg, unsigned int *val) +{ + struct dw_i2c_dev *dev = context; + int ret; + + /* + * Note these methods shouldn't ever fail because the system controller + * registers are memory mapped. We check the return value just in case. + */ + ret = regmap_write(dev->sysmap, BT1_I2C_CTL, + BT1_I2C_CTL_GO | (reg & BT1_I2C_CTL_ADDR_MASK)); + if (ret) + return ret; + + return regmap_read(dev->sysmap, BT1_I2C_DO, val); +} + +static int bt1_i2c_write(void *context, unsigned int reg, unsigned int val) +{ + struct dw_i2c_dev *dev = context; + int ret; + + ret = regmap_write(dev->sysmap, BT1_I2C_DI, val); + if (ret) + return ret; + + return regmap_write(dev->sysmap, BT1_I2C_CTL, + BT1_I2C_CTL_GO | BT1_I2C_CTL_WR | (reg & BT1_I2C_CTL_ADDR_MASK)); +} + +static const struct regmap_config bt1_i2c_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .fast_io = true, + .reg_read = bt1_i2c_read, + .reg_write = bt1_i2c_write, + .max_register = DW_IC_COMP_TYPE, +}; + +static int bt1_i2c_request_regs(struct dw_i2c_dev *dev) +{ + dev->sysmap = syscon_node_to_regmap(dev->dev->of_node->parent); + if (IS_ERR(dev->sysmap)) + return PTR_ERR(dev->sysmap); + + dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg); + return PTR_ERR_OR_ZERO(dev->map); +} +#else +static int bt1_i2c_request_regs(struct dw_i2c_dev *dev) +{ + return -ENODEV; +} +#endif + +static int txgbe_i2c_request_regs(struct dw_i2c_dev *dev) +{ + dev->map = dev_get_regmap(dev->dev->parent, NULL); + if (!dev->map) + return -ENODEV; + + return 0; +} + +static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev) +{ + pm_runtime_disable(dev->dev); + + if (dev->shared_with_punit) + pm_runtime_put_noidle(dev->dev); +} + +static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev) +{ + struct platform_device *pdev = to_platform_device(dev->dev); + int ret; + + switch (dev->flags & MODEL_MASK) { + case MODEL_BAIKAL_BT1: + ret = bt1_i2c_request_regs(dev); + break; + case MODEL_WANGXUN_SP: + ret = txgbe_i2c_request_regs(dev); + break; + default: + dev->base = devm_platform_ioremap_resource(pdev, 0); + ret = PTR_ERR_OR_ZERO(dev->base); + break; + } + + return ret; +} + +static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = { + { + .ident = "Qtechnology QT5222", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Qtechnology"), + DMI_MATCH(DMI_PRODUCT_NAME, "QT5222"), + }, + }, + { } /* terminate list */ +}; + +static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = { +#if 0//def CONFIG_I2C_DESIGNWARE_BAYTRAIL + { + .probe = i2c_dw_baytrail_probe_lock_support, + }, +#endif +#ifdef CONFIG_I2C_DESIGNWARE_AMDPSP + { + .probe = i2c_dw_amdpsp_probe_lock_support, + }, +#endif + {} +}; + +static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) +{ + const struct i2c_dw_semaphore_callbacks *ptr; + int i = 0; + int ret; + + dev->semaphore_idx = -1; + + for (ptr = i2c_dw_semaphore_cb_table; ptr->probe; ptr++) { + ret = ptr->probe(dev); + if (ret) { + /* + * If there is no semaphore device attached to this + * controller, we shouldn't abort general i2c_controller + * probe. + */ + if (ret != -ENODEV) + return ret; + + i++; + continue; + } + + dev->semaphore_idx = i; + break; + } + + return 0; +} + +static void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) +{ + if (dev->semaphore_idx < 0) + return; + + if (i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove) + i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove(dev); +} + +static int dw_i2c_plat_probe(struct platform_device *pdev) +{ + struct device *device = &pdev->dev; + struct i2c_adapter *adap; + struct dw_i2c_dev *dev; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + dev = devm_kzalloc(device, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->flags = (uintptr_t)device_get_match_data(device); + if (device_property_present(device, "wx,i2c-snps-model")) + dev->flags = MODEL_WANGXUN_SP | ACCESS_POLLING; + + dev->dev = device; + dev->irq = irq; + platform_set_drvdata(pdev, dev); + + ret = dw_i2c_plat_request_regs(dev); + if (ret) + return ret; + + dev->rst = devm_reset_control_get_optional_exclusive(device, NULL); + if (IS_ERR(dev->rst)) + return PTR_ERR(dev->rst); + + reset_control_deassert(dev->rst); + + ret = i2c_dw_fw_parse_and_configure(dev); + if (ret) + goto exit_reset; + + ret = i2c_dw_probe_lock_support(dev); + if (ret) + goto exit_reset; + + if (bus_freq_hz) { + struct i2c_timings *t = &dev->timings; + t->bus_freq_hz = bus_freq_hz; + } + + i2c_dw_configure(dev); + + /* Optional interface clock */ + dev->pclk = devm_clk_get_optional(device, "pclk"); + if (IS_ERR(dev->pclk)) { + ret = PTR_ERR(dev->pclk); + goto exit_reset; + } + + dev->clk = devm_clk_get_optional(device, NULL); + if (IS_ERR(dev->clk)) { + ret = PTR_ERR(dev->clk); + goto exit_reset; + } + + ret = i2c_dw_prepare_clk(dev, true); + if (ret) + goto exit_reset; + + if (dev->clk) { + struct i2c_timings *t = &dev->timings; + u64 clk_khz; + + dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; + clk_khz = dev->get_clk_rate_khz(dev); + + if (!dev->sda_hold_time && t->sda_hold_ns) + dev->sda_hold_time = + DIV_S64_ROUND_CLOSEST(clk_khz * t->sda_hold_ns, MICRO); + } + + adap = &dev->adapter; + adap->owner = THIS_MODULE; + adap->class = dmi_check_system(dw_i2c_hwmon_class_dmi) ? + I2C_CLASS_HWMON : I2C_CLASS_DEPRECATED; + adap->nr = -1; + + if (dev->flags & ACCESS_NO_IRQ_SUSPEND) + dev_pm_set_driver_flags(device, DPM_FLAG_SMART_PREPARE); + else + dev_pm_set_driver_flags(device, DPM_FLAG_SMART_PREPARE | DPM_FLAG_SMART_SUSPEND); + + device_enable_async_suspend(device); + + /* The code below assumes runtime PM to be disabled. */ + WARN_ON(pm_runtime_enabled(device)); + + pm_runtime_set_autosuspend_delay(device, 1000); + pm_runtime_use_autosuspend(device); + pm_runtime_set_active(device); + + if (dev->shared_with_punit) + pm_runtime_get_noresume(device); + + pm_runtime_enable(device); + + /* Override default fall timeouts if specified by platform data or device tree */ + if (sda_fall_ns || scl_fall_ns) { + struct i2c_timings *t = &dev->timings; + t->sda_fall_ns = sda_fall_ns; + t->scl_fall_ns = scl_fall_ns; + } + + ret = i2c_dw_probe(dev); + if (ret) + goto exit_probe; + + return ret; + +exit_probe: + dw_i2c_plat_pm_cleanup(dev); +exit_reset: + reset_control_assert(dev->rst); + return ret; +} + +static void dw_i2c_plat_remove(struct platform_device *pdev) +{ + struct dw_i2c_dev *dev = platform_get_drvdata(pdev); + struct device *device = &pdev->dev; + + pm_runtime_get_sync(device); + + i2c_del_adapter(&dev->adapter); + + i2c_dw_disable(dev); + + pm_runtime_dont_use_autosuspend(device); + pm_runtime_put_sync(device); + dw_i2c_plat_pm_cleanup(dev); + + i2c_dw_remove_lock_support(dev); + + reset_control_assert(dev->rst); +} + +static const struct of_device_id dw_i2c_of_match[] = { + { .compatible = "snps,designware-i2c", }, + { .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT }, + { .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 }, + {} +}; +MODULE_DEVICE_TABLE(of, dw_i2c_of_match); + +static const struct acpi_device_id dw_i2c_acpi_match[] = { + { "80860F41", ACCESS_NO_IRQ_SUSPEND }, + { "808622C1", ACCESS_NO_IRQ_SUSPEND }, + { "AMD0010", ACCESS_INTR_MASK }, + { "AMDI0010", ACCESS_INTR_MASK }, + { "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE }, + { "AMDI0510", 0 }, + { "APMC0D0F", 0 }, + { "HISI02A1", 0 }, + { "HISI02A2", 0 }, + { "HISI02A3", 0 }, + { "HYGO0010", ACCESS_INTR_MASK }, + { "INT33C2", 0 }, + { "INT33C3", 0 }, + { "INT3432", 0 }, + { "INT3433", 0 }, + { "INTC10EF", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); + +static const struct platform_device_id dw_i2c_platform_ids[] = { + { "i2c_designware" }, + {} +}; +MODULE_DEVICE_TABLE(platform, dw_i2c_platform_ids); + +static struct platform_driver dw_i2c_driver = { + .probe = dw_i2c_plat_probe, + .remove_new = dw_i2c_plat_remove, + .driver = { + .name = "i2c_designware", + .of_match_table = dw_i2c_of_match, + .acpi_match_table = dw_i2c_acpi_match, + .pm = pm_ptr(&i2c_dw_dev_pm_ops), + }, + .id_table = dw_i2c_platform_ids, +}; + +static int __init dw_i2c_init_driver(void) +{ + return platform_driver_register(&dw_i2c_driver); +} +subsys_initcall(dw_i2c_init_driver); + +static void __exit dw_i2c_exit_driver(void) +{ + platform_driver_unregister(&dw_i2c_driver); +} +module_exit(dw_i2c_exit_driver); + +MODULE_AUTHOR("Baruch Siach "); +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(I2C_DW); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-slave.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-slave.c new file mode 100644 index 0000000000..602e98e61c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/i2c-designware-slave.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Synopsys DesignWare I2C adapter driver (slave only). + * + * Based on the Synopsys DesignWare I2C adapter driver (master). + * + * Copyright (C) 2016 Synopsys Inc. + */ + +#define DEFAULT_SYMBOL_NAMESPACE "I2C_DW" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i2c-designware-core.h" + +static void i2c_dw_configure_fifo_slave(struct dw_i2c_dev *dev) +{ + /* Configure Tx/Rx FIFO threshold levels. */ + regmap_write(dev->map, DW_IC_TX_TL, 0); + regmap_write(dev->map, DW_IC_RX_TL, 0); + + /* Configure the I2C slave. */ + regmap_write(dev->map, DW_IC_CON, dev->slave_cfg); + regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_SLAVE_MASK); +} + +/** + * i2c_dw_init_slave() - Initialize the designware i2c slave hardware + * @dev: device private data + * + * This function configures and enables the I2C in slave mode. + * This function is called during I2C init function, and in case of timeout at + * run time. + */ +static int i2c_dw_init_slave(struct dw_i2c_dev *dev) +{ + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + /* Disable the adapter. */ + __i2c_dw_disable(dev); + + /* Write SDA hold time if supported */ + if (dev->sda_hold_time) + regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time); + + i2c_dw_configure_fifo_slave(dev); + i2c_dw_release_lock(dev); + + return 0; +} + +static int i2c_dw_reg_slave(struct i2c_client *slave) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); + + if (dev->slave) + return -EBUSY; + if (slave->flags & I2C_CLIENT_TEN) + return -EAFNOSUPPORT; + pm_runtime_get_sync(dev->dev); + + /* + * Set slave address in the IC_SAR register, + * the address to which the DW_apb_i2c responds. + */ + __i2c_dw_disable_nowait(dev); + regmap_write(dev->map, DW_IC_SAR, slave->addr); + dev->slave = slave; + + __i2c_dw_enable(dev); + + dev->status = 0; + + return 0; +} + +static int i2c_dw_unreg_slave(struct i2c_client *slave) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); + + regmap_write(dev->map, DW_IC_INTR_MASK, 0); + i2c_dw_disable(dev); + synchronize_irq(dev->irq); + dev->slave = NULL; + pm_runtime_put_sync_suspend(dev->dev); + + return 0; +} + +static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev) +{ + unsigned int stat, dummy; + + /* + * The IC_INTR_STAT register just indicates "enabled" interrupts. + * The unmasked raw version of interrupt status bits is available + * in the IC_RAW_INTR_STAT register. + * + * That is, + * stat = readl(IC_INTR_STAT); + * equals to, + * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK); + * + * The raw version might be useful for debugging purposes. + */ + regmap_read(dev->map, DW_IC_INTR_STAT, &stat); + + /* + * Do not use the IC_CLR_INTR register to clear interrupts, or + * you'll miss some interrupts, triggered during the period from + * readl(IC_INTR_STAT) to readl(IC_CLR_INTR). + * + * Instead, use the separately-prepared IC_CLR_* registers. + */ + if (stat & DW_IC_INTR_TX_ABRT) + regmap_read(dev->map, DW_IC_CLR_TX_ABRT, &dummy); + if (stat & DW_IC_INTR_RX_UNDER) + regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &dummy); + if (stat & DW_IC_INTR_RX_OVER) + regmap_read(dev->map, DW_IC_CLR_RX_OVER, &dummy); + if (stat & DW_IC_INTR_TX_OVER) + regmap_read(dev->map, DW_IC_CLR_TX_OVER, &dummy); + if (stat & DW_IC_INTR_RX_DONE) + regmap_read(dev->map, DW_IC_CLR_RX_DONE, &dummy); + if (stat & DW_IC_INTR_ACTIVITY) + regmap_read(dev->map, DW_IC_CLR_ACTIVITY, &dummy); + if (stat & DW_IC_INTR_STOP_DET) + regmap_read(dev->map, DW_IC_CLR_STOP_DET, &dummy); + if (stat & DW_IC_INTR_START_DET) + regmap_read(dev->map, DW_IC_CLR_START_DET, &dummy); + if (stat & DW_IC_INTR_GEN_CALL) + regmap_read(dev->map, DW_IC_CLR_GEN_CALL, &dummy); + + return stat; +} + +/* + * Interrupt service routine. This gets called whenever an I2C slave interrupt + * occurs. + */ +static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) +{ + struct dw_i2c_dev *dev = dev_id; + unsigned int raw_stat, stat, enabled, tmp; + u8 val = 0, slave_activity; + + regmap_read(dev->map, DW_IC_ENABLE, &enabled); + regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_stat); + regmap_read(dev->map, DW_IC_STATUS, &tmp); + slave_activity = ((tmp & DW_IC_STATUS_SLAVE_ACTIVITY) >> 6); + + if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave) + return IRQ_NONE; + + stat = i2c_dw_read_clear_intrbits_slave(dev); + dev_dbg(dev->dev, + "%#x STATUS SLAVE_ACTIVITY=%#x : RAW_INTR_STAT=%#x : INTR_STAT=%#x\n", + enabled, slave_activity, raw_stat, stat); + + if (stat & DW_IC_INTR_RX_FULL) { + if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { + dev->status |= STATUS_WRITE_IN_PROGRESS; + dev->status &= ~STATUS_READ_IN_PROGRESS; + i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_REQUESTED, + &val); + } + + do { + regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); + if (tmp & DW_IC_DATA_CMD_FIRST_DATA_BYTE) + i2c_slave_event(dev->slave, + I2C_SLAVE_WRITE_REQUESTED, + &val); + val = tmp; + i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED, + &val); + regmap_read(dev->map, DW_IC_STATUS, &tmp); + } while (tmp & DW_IC_STATUS_RFNE); + } + + if (stat & DW_IC_INTR_RD_REQ) { + if (slave_activity) { + regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp); + + if (!(dev->status & STATUS_READ_IN_PROGRESS)) { + i2c_slave_event(dev->slave, + I2C_SLAVE_READ_REQUESTED, + &val); + dev->status |= STATUS_READ_IN_PROGRESS; + dev->status &= ~STATUS_WRITE_IN_PROGRESS; + } else { + i2c_slave_event(dev->slave, + I2C_SLAVE_READ_PROCESSED, + &val); + } + regmap_write(dev->map, DW_IC_DATA_CMD, val); + } + } + + if (stat & DW_IC_INTR_STOP_DET) + i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val); + + return IRQ_HANDLED; +} + +static const struct i2c_algorithm i2c_dw_algo = { + .functionality = i2c_dw_func, + .reg_slave = i2c_dw_reg_slave, + .unreg_slave = i2c_dw_unreg_slave, +}; + +void i2c_dw_configure_slave(struct dw_i2c_dev *dev) +{ + dev->functionality = I2C_FUNC_SLAVE; + + dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL | + DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED; + + dev->mode = DW_IC_SLAVE; +} +EXPORT_SYMBOL_GPL(i2c_dw_configure_slave); + +int i2c_dw_probe_slave(struct dw_i2c_dev *dev) +{ + struct i2c_adapter *adap = &dev->adapter; + int ret; + + dev->init = i2c_dw_init_slave; + + ret = i2c_dw_init_regmap(dev); + if (ret) + return ret; + + ret = i2c_dw_set_sda_hold(dev); + if (ret) + return ret; + + ret = i2c_dw_set_fifo_size(dev); + if (ret) + return ret; + + ret = dev->init(dev); + if (ret) + return ret; + + snprintf(adap->name, sizeof(adap->name), + "Synopsys DesignWare I2C Slave adapter"); + adap->retries = 3; + adap->algo = &i2c_dw_algo; + adap->dev.parent = dev->dev; + i2c_set_adapdata(adap, dev); + + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr_slave, + IRQF_SHARED, dev_name(dev->dev), dev); + if (ret) { + dev_err(dev->dev, "failure requesting irq %i: %d\n", + dev->irq, ret); + return ret; + } + + ret = i2c_add_numbered_adapter(adap); + if (ret) + dev_err(dev->dev, "failure adding adapter: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(i2c_dw_probe_slave); + +MODULE_AUTHOR("Luis Oliveira "); +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus slave adapter"); +MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/math.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/math.h new file mode 100644 index 0000000000..e358575882 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/math.h @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_MATH_H +#define _LINUX_MATH_H + +#include +#include + +/* + * This looks more complex than it should be. But we need to + * get the type for the ~ right in round_down (it needs to be + * as wide as the result!), and we want to evaluate the macro + * arguments just once each. + */ +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) + +/** + * round_up - round up to next specified power of 2 + * @x: the value to round + * @y: multiple to round up to (must be a power of 2) + * + * Rounds @x up to next multiple of @y (which must be a power of 2). + * To perform arbitrary rounding up, use roundup() below. + */ +#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) + +/** + * round_down - round down to next specified power of 2 + * @x: the value to round + * @y: multiple to round down to (must be a power of 2) + * + * Rounds @x down to next multiple of @y (which must be a power of 2). + * To perform arbitrary rounding down, use rounddown() below. + */ +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + +#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP + +#define DIV_ROUND_DOWN_ULL(ll, d) \ + ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) + +#define DIV_ROUND_UP_ULL(ll, d) \ + DIV_ROUND_DOWN_ULL((unsigned long long)(ll) + (d) - 1, (d)) + +#if BITS_PER_LONG == 32 +# define DIV_ROUND_UP_SECTOR_T(ll,d) DIV_ROUND_UP_ULL(ll, d) +#else +# define DIV_ROUND_UP_SECTOR_T(ll,d) DIV_ROUND_UP(ll,d) +#endif + +/** + * roundup - round up to the next specified multiple + * @x: the value to up + * @y: multiple to round up to + * + * Rounds @x up to next multiple of @y. If @y will always be a power + * of 2, consider using the faster round_up(). + */ +#define roundup(x, y) ( \ +{ \ + typeof(y) __y = y; \ + (((x) + (__y - 1)) / __y) * __y; \ +} \ +) +/** + * rounddown - round down to next specified multiple + * @x: the value to round + * @y: multiple to round down to + * + * Rounds @x down to next multiple of @y. If @y will always be a power + * of 2, consider using the faster round_down(). + */ +#define rounddown(x, y) ( \ +{ \ + typeof(x) __x = (x); \ + __x - (__x % (y)); \ +} \ +) + +/* + * Divide positive or negative dividend by positive or negative divisor + * and round to closest integer. Result is undefined for negative + * divisors if the dividend variable type is unsigned and for negative + * dividends if the divisor variable type is unsigned. + */ +#define DIV_ROUND_CLOSEST(x, divisor)( \ +{ \ + typeof(x) __x = x; \ + typeof(divisor) __d = divisor; \ + (((typeof(x))-1) > 0 || \ + ((typeof(divisor))-1) > 0 || \ + (((__x) > 0) == ((__d) > 0))) ? \ + (((__x) + ((__d) / 2)) / (__d)) : \ + (((__x) - ((__d) / 2)) / (__d)); \ +} \ +) +/* + * Same as above but for u64 dividends. divisor must be a 32-bit + * number. + */ +#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \ +{ \ + typeof(divisor) __d = divisor; \ + unsigned long long _tmp = (x) + (__d) / 2; \ + do_div(_tmp, __d); \ + _tmp; \ +} \ +) + +/* + * Multiplies an integer by a fraction, while avoiding unnecessary + * overflow or loss of precision. + */ +#define mult_frac(x, numer, denom)( \ +{ \ + typeof(x) quot = (x) / (denom); \ + typeof(x) rem = (x) % (denom); \ + (quot * (numer)) + ((rem * (numer)) / (denom)); \ +} \ +) + +#define sector_div(a, b) do_div(a, b) + +/** + * abs - return absolute value of an argument + * @x: the value. If it is unsigned type, it is converted to signed type first. + * char is treated as if it was signed (regardless of whether it really is) + * but the macro's return type is preserved as char. + * + * Return: an absolute value of x. + */ +#define abs(x) __abs_choose_expr(x, long long, \ + __abs_choose_expr(x, long, \ + __abs_choose_expr(x, int, \ + __abs_choose_expr(x, short, \ + __abs_choose_expr(x, char, \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), char), \ + (char)({ signed char __x = (x); __x<0?-__x:__x; }), \ + ((void)0))))))) + +#define __abs_choose_expr(x, type, other) __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), signed type) || \ + __builtin_types_compatible_p(typeof(x), unsigned type), \ + ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other) + +u64 int_pow(u64 base, unsigned int exp); + +#endif /* _LINUX_MATH_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/units.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/units.h new file mode 100644 index 0000000000..8f71e50054 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/i2c-designware/units.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_UNITS_H +#define _LINUX_UNITS_H + +#include "math.h" + +/* Metric prefixes in accordance with Système international (d'unités) */ +#define PETA 1000000000000000ULL +#define TERA 1000000000000ULL +#define GIGA 1000000000UL +#define MEGA 1000000UL +#define KILO 1000UL +#define HECTO 100UL +#define DECA 10UL +#define DECI 10UL +#define CENTI 100UL +#define MILLI 1000UL +#define MICRO 1000000UL +#define NANO 1000000000UL +#define PICO 1000000000000ULL +#define FEMTO 1000000000000000ULL + +#define HZ_PER_KHZ 1000UL +#define KHZ_PER_MHZ 1000UL +#define HZ_PER_MHZ 1000000UL + +#define MILLIWATT_PER_WATT 1000UL +#define MICROWATT_PER_MILLIWATT 1000UL +#define MICROWATT_PER_WATT 1000000UL + +#define ABSOLUTE_ZERO_MILLICELSIUS -273150 + +static inline long milli_kelvin_to_millicelsius(long t) +{ + return t + ABSOLUTE_ZERO_MILLICELSIUS; +} + +static inline long millicelsius_to_milli_kelvin(long t) +{ + return t - ABSOLUTE_ZERO_MILLICELSIUS; +} + +#define MILLIDEGREE_PER_DEGREE 1000 +#define MILLIDEGREE_PER_DECIDEGREE 100 + +static inline long kelvin_to_millicelsius(long t) +{ + return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DEGREE); +} + +static inline long millicelsius_to_kelvin(long t) +{ + t = millicelsius_to_milli_kelvin(t); + + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE); +} + +static inline long deci_kelvin_to_celsius(long t) +{ + t = milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE); + + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE); +} + +static inline long celsius_to_deci_kelvin(long t) +{ + t = millicelsius_to_milli_kelvin(t * MILLIDEGREE_PER_DEGREE); + + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE); +} + +/** + * deci_kelvin_to_millicelsius_with_offset - convert Kelvin to Celsius + * @t: temperature value in decidegrees Kelvin + * @offset: difference between Kelvin and Celsius in millidegrees + * + * Return: temperature value in millidegrees Celsius + */ +static inline long deci_kelvin_to_millicelsius_with_offset(long t, long offset) +{ + return t * MILLIDEGREE_PER_DECIDEGREE - offset; +} + +static inline long deci_kelvin_to_millicelsius(long t) +{ + return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE); +} + +static inline long millicelsius_to_deci_kelvin(long t) +{ + t = millicelsius_to_milli_kelvin(t); + + return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE); +} + +static inline long kelvin_to_celsius(long t) +{ + return t + DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, + MILLIDEGREE_PER_DEGREE); +} + +static inline long celsius_to_kelvin(long t) +{ + return t - DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, + MILLIDEGREE_PER_DEGREE); +} + +#endif /* _LINUX_UNITS_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Makefile new file mode 100644 index 0000000000..f32a305383 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Makefile @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 1999 - 2026 Intel Corporation + +src := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) + +KCOMPAT_KSRC := $(KERNEL_SRC)/source +KCOMPAT_KOBJ := $(KERNEL_SRC)/build +KCOMPAT_OUT := $(src)/kcompat_generated_defs.h +KCOMPAT_CONFIG_FILE := $(KCOMPAT_KOBJ)/include/generated/autoconf.h +PWD = $(shell pwd) + +ccflags-y += -I$(src) + +.PHONY: prepare all clean + +prepare: $(KCOMPAT_OUT) + +# kbuild part of makefile +# +# Makefile for the Intel(R) 10GbE PCI Express Linux Network Driver +# + +obj-m += wb_ixgbe.o + +define ixgbe-y + ixgbe_main.o + ixgbe_api.o + ixgbe_common.o + ixgbe_dcb.o + ixgbe_dcb_82598.o + ixgbe_dcb_82599.o + ixgbe_ethtool.o + ixgbe_lib.o + ixgbe_mbx.o + ixgbe_sriov.o + ixgbe_param.o + ixgbe_phy.o + ixgbe_procfs.o + ixgbe_xsk.o + ixgbe_82598.o + ixgbe_82599.o + ixgbe_x540.o + ixgbe_x550.o + ixgbe_e610.o + ixgbe_devlink.o + ixgbe_fw_update.o +endef +wb_ixgbe-y := $(strip ${ixgbe-y}) + +wb_ixgbe-${CONFIG_DCB} += ixgbe_dcb_nl.o + +wb_ixgbe-${CONFIG_DEBUG_FS} += ixgbe_debugfs.o + +wb_ixgbe-${CONFIG_FCOE:m=y} += ixgbe_fcoe.o + +wb_ixgbe-$(CONFIG_PTP_1588_CLOCK:m=y) += ixgbe_ptp.o +wb_ixgbe-$(CONFIG_PTP_1588_CLOCK:m=y) += ixgbe_ptp_e600.o + +wb_ixgbe-${CONFIG_SYSFS} += ixgbe_sysfs.o + +# Use kcompat pldmfw.c if kernel does not provide CONFIG_PLDMFW +ifndef CONFIG_PLDMFW +wb_ixgbe-y += kcompat_pldmfw.o +endif + +wb_ixgbe-y += kcompat.o + +# Force generation of kcompat_generated_defs.h before any ixgbe objects build +$(foreach f,$(wb_ixgbe-y) ixgbe_dcb_nl.o ixgbe_debugfs.o ixgbe_fcoe.o ixgbe_ptp.o ixgbe_ptp_e600.o ixgbe_sysfs.o kcompat_pldmfw.o, \ + $(eval $(obj)/$(f): $(KCOMPAT_OUT))) + +all: prepare + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) + +$(KCOMPAT_OUT): $(src)/kcompat-generator.sh $(KCOMPAT_CONFIG_FILE) + @echo " GEN $@" + @echo " KSRC $(KCOMPAT_KSRC)" + @echo " KOBJ $(KCOMPAT_KOBJ)" + @echo " CONFIG $(KCOMPAT_CONFIG_FILE)" + @KSRC=$(KCOMPAT_KSRC) KOBJ=$(KCOMPAT_KOBJ) OUT=$(KCOMPAT_OUT) CONFIG_FILE=$(KCOMPAT_CONFIG_FILE) \ + bash $(src)/kcompat-generator.sh + + +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/*.order $(PWD)/*.mod $(PWD)/*.txt $(PWD)/*.symvers $(PWD)/kcompat_generated_defs.h diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Module.supported b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Module.supported new file mode 100644 index 0000000000..af24796479 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/Module.supported @@ -0,0 +1 @@ +ixgbe.ko external diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/auxiliary_compat.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/auxiliary_compat.h new file mode 100644 index 0000000000..a39cbf6a71 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/auxiliary_compat.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _AUXILIARY_COMPAT_H_ +#define _AUXILIARY_COMPAT_H_ + +/* This file contains only the minimal set of kernel compatibility backports + * required by auxiliary.c to build. It is similar to the kcompat.h file, but + * reduced to an absolute minimum in order to reduce the risk of generating + * different kernel symbol CRC values at build time. + * + * For a detailed discussion of kernel symbol CRCs, please read: + * + * Documentation/kernel-symbol-crc.rst + * + * Include only the minimum required kernel compatibility implementations from + * kcompat_generated_defs.h and kcompat_impl.h. If a new fix is required, + * please first implement it as part of the kcompat project before porting it + * to this file. + * + * The current list of required implementations is: + * + * NEED_BUS_FIND_DEVICE_CONST_DATA + * NEED_DEV_PM_DOMAIN_ATTACH + * NEED_DEV_PM_DOMAIN_DETACH + * + * Note that kernels since v5.11 support auxiliary as a built-in config + * option. Using this is always preferred to using an out-of-tree module when + * available. + */ + +#include "kcompat_generated_defs.h" + +/**************************** + * Backport implementations * + ****************************/ + +#ifdef NEED_BUS_FIND_DEVICE_CONST_DATA +/* NEED_BUS_FIND_DEVICE_CONST_DATA + * + * bus_find_device() was updated in upstream commit 418e3ea157ef + * ("bus_find_device: Unify the match callback with class_find_device") + * to take a const void *data parameter and also have the match() function + * passed in take a const void *data parameter. + * + * all of the kcompat below makes it so the caller can always just call + * bus_find_device() according to the upstream kernel without having to worry + * about const vs. non-const arguments. + */ +struct _kc_bus_find_device_custom_data { + const void *real_data; + int (*real_match)(struct device *dev, const void *data); +}; + +static inline int _kc_bus_find_device_wrapped_match(struct device *dev, void *data) +{ + struct _kc_bus_find_device_custom_data *custom_data = data; + + return custom_data->real_match(dev, custom_data->real_data); +} + +static inline struct device * +_kc_bus_find_device(struct bus_type *type, struct device *start, + const void *data, + int (*match)(struct device *dev, const void *data)) +{ + struct _kc_bus_find_device_custom_data custom_data = {}; + + custom_data.real_data = data; + custom_data.real_match = match; + + return bus_find_device(type, start, &custom_data, + _kc_bus_find_device_wrapped_match); +} + +/* force callers of bus_find_device() to call _kc_bus_find_device() on kernels + * where NEED_BUS_FIND_DEVICE_CONST_DATA is defined + */ +#define bus_find_device(type, start, data, match) \ + _kc_bus_find_device(type, start, data, match) +#endif /* NEED_BUS_FIND_DEVICE_CONST_DATA */ + +#if defined(NEED_DEV_PM_DOMAIN_ATTACH) && defined(NEED_DEV_PM_DOMAIN_DETACH) +#include +/* NEED_DEV_PM_DOMAIN_ATTACH and NEED_DEV_PM_DOMAIN_DETACH + * + * dev_pm_domain_attach() and dev_pm_domain_detach() were added in upstream + * commit 46420dd73b80 ("PM / Domains: Add APIs to attach/detach a PM domain for + * a device"). To support older kernels and OSVs that don't have these API, just + * implement how older versions worked by directly calling acpi_dev_pm_attach() + * and acpi_dev_pm_detach(). + */ +static inline int dev_pm_domain_attach(struct device *dev, bool power_on) +{ + if (dev->pm_domain) + return 0; + + if (ACPI_HANDLE(dev)) + return acpi_dev_pm_attach(dev, true); + + return 0; +} + +static inline void dev_pm_domain_detach(struct device *dev, bool power_off) +{ + if (ACPI_HANDLE(dev)) + acpi_dev_pm_detach(dev, true); +} +#else /* NEED_DEV_PM_DOMAIN_ATTACH && NEED_DEV_PM_DOMAIN_DETACH */ +/* it doesn't make sense to compat only one of these functions, and it is + * likely either a failure in kcompat-generator.sh or a failed distribution + * backport if this occurs. Don't try to support it. + */ +#ifdef NEED_DEV_PM_DOMAIN_ATTACH +#error "NEED_DEV_PM_DOMAIN_ATTACH defined but NEED_DEV_PM_DOMAIN_DETACH not defined???" +#endif /* NEED_DEV_PM_DOMAIN_ATTACH */ +#ifdef NEED_DEV_PM_DOMAIN_DETACH +#error "NEED_DEV_PM_DOMAIN_DETACH defined but NEED_DEV_PM_DOMAIN_ATTACH not defined???" +#endif /* NEED_DEV_PM_DOMAIN_DETACH */ +#endif /* NEED_DEV_PM_DOMAIN_ATTACH && NEED_DEV_PM_DOMAIN_DETACH */ + +#endif /* _AUXILIARY_COMPAT_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/common.mk b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/common.mk new file mode 100644 index 0000000000..92c5d3f517 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/common.mk @@ -0,0 +1,463 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 1999 - 2026 Intel Corporation + +# +# common Makefile rules useful for out-of-tree Linux driver builds +# +# Usage: include common.mk +# +# After including, you probably want to add a minimum_kver_check call +# +# Required Variables: +# DRIVER +# -- Set to the lowercase driver name + +##################### +# Helpful functions # +##################### + +SHELL := $(shell which bash) +src ?= $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +readlink = $(shell readlink -f ${1}) + +# helper functions for converting kernel version to version codes +get_kver = $(or $(word ${2},$(subst ., ,${1})),0) +get_kvercode = $(shell [ "${1}" -ge 0 -a "${1}" -le 255 2>/dev/null ] && \ + [ "${2}" -ge 0 -a "${2}" -le 255 2>/dev/null ] && \ + [ "${3}" -ge 0 -a "${3}" -le 255 2>/dev/null ] && \ + printf %d $$(( ( ${1} << 16 ) + ( ${2} << 8 ) + ( ${3} ) )) ) + +################ +# depmod Macro # +################ + +cmd_depmod = /sbin/depmod $(if ${SYSTEM_MAP_FILE},-e -F ${SYSTEM_MAP_FILE}) \ + $(if $(strip ${INSTALL_MOD_PATH}),-b ${INSTALL_MOD_PATH}) \ + -a ${KVER} + +##################### +# Environment tests # +##################### + +DRIVER_UPPERCASE := $(shell echo ${DRIVER} | tr "[:lower:]" "[:upper:]") + +ifeq (,${BUILD_KERNEL}) +BUILD_KERNEL=$(shell uname -r) +endif + +# Kernel Search Path +# All the places we look for kernel source +KSP := /lib/modules/${BUILD_KERNEL}/source \ + /lib/modules/${BUILD_KERNEL}/build \ + /usr/src/linux-${BUILD_KERNEL} \ + /usr/src/kernel-headers-${BUILD_KERNEL} \ + /usr/src/kernel-source-${BUILD_KERNEL} \ + /usr/src/linux \ + /usr/src/kernels/${BUILD_KERNEL} \ + /usr/src/kernels + +# prune the list down to only values that exist and have an include/linux +# sub-directory. We can't use include/config because some older kernels don't +# have this. +test_dir = $(shell [ -e ${dir}/include/linux ] && echo ${dir}) +KSP := $(foreach dir, ${KSP}, ${test_dir}) + +# we will use this first valid entry in the search path +ifeq (,${KSRC}) + KSRC := $(firstword ${KSP}) +endif + +ifeq (,${KSRC}) + $(warning *** Kernel header files not in any of the expected locations.) + $(warning *** Install the appropriate kernel development package, e.g.) + $(error kernel-devel, for building kernel modules and try again) +else +ifeq (/lib/modules/${BUILD_KERNEL}/source, ${KSRC}) + KOBJ := /lib/modules/${BUILD_KERNEL}/build +else + KOBJ := ${KSRC} +endif +endif + +SCRIPT_PATH := ${KSRC}/scripts +info_signed_modules = + +ifeq (,${SCRIPT_PATH}) + info_signed_modules += echo "*** Could not find sign-file script. Cannot sign driver." ; +else + SIGN_FILE_EXISTS := $(or $(and $(wildcard $(SCRIPT_PATH)/sign-file),1),) + PRIV_KEY_EXISTS := $(or $(and $(wildcard intel-linux-key.key),1),) + PUB_KEY_EXISTS := $(or $(and $(wildcard intel-linux-key.crt),1),) +ifneq ($(and $(SIGN_FILE_EXISTS),$(PRIV_KEY_EXISTS),$(PUB_KEY_EXISTS)),) + info_signed_modules += \ + echo "*** Is sign-file present: ${SIGN_FILE_EXISTS}" ; \ + echo "*** Is private key present: ${PRIV_KEY_EXISTS}" ; \ + echo "*** Is public key present: ${PUB_KEY_EXISTS}" ; + info_signed_modules += echo "*** All files are present, signing driver." ; + sign_driver = $(shell ${SCRIPT_PATH}/sign-file sha256 intel-linux-key.key \ + intel-linux-key.crt ${DRIVER}.ko) +else + info_signed_modules += echo "*** Files are missing, cannot sign driver." ; + sign_driver = +endif +endif + +# Version file Search Path +VSP := ${KOBJ}/include/generated/utsrelease.h \ + ${KOBJ}/include/linux/utsrelease.h \ + ${KOBJ}/include/linux/version.h \ + ${KOBJ}/include/generated/uapi/linux/version.h \ + /boot/vmlinuz.version.h + +# Config file Search Path +CSP := ${KOBJ}/include/generated/autoconf.h \ + ${KOBJ}/include/linux/autoconf.h \ + /boot/vmlinuz.autoconf.h + +# System.map Search Path (for depmod) +MSP := ${KSRC}/System.map \ + /usr/lib/debug/boot/System.map-${BUILD_KERNEL} \ + /boot/System.map-${BUILD_KERNEL} + +# prune the lists down to only files that exist +test_file = $(shell [ -f ${1} ] && echo ${1}) +VSP := $(foreach file, ${VSP}, $(call test_file,${file})) +CSP := $(foreach file, ${CSP}, $(call test_file,${file})) +MSP := $(foreach file, ${MSP}, $(call test_file,${file})) + + +# and use the first valid entry in the Search Paths +ifeq (,${VERSION_FILE}) + VERSION_FILE := $(firstword ${VSP}) +endif + +ifeq (,${CONFIG_FILE}) + CONFIG_FILE := $(firstword ${CSP}) +endif + +ifeq (,${SYSTEM_MAP_FILE}) + SYSTEM_MAP_FILE := $(firstword ${MSP}) +endif + +ifeq (,$(wildcard ${VERSION_FILE})) + $(error Linux kernel source not configured - missing version header file) +endif + +ifeq (,$(wildcard ${CONFIG_FILE})) + $(error Linux kernel source not configured - missing autoconf.h) +endif + +ifeq (,$(wildcard ${SYSTEM_MAP_FILE})) + $(warning Missing System.map file - depmod will not check for missing symbols during module installation) +endif + +ifneq ($(words $(subst :, ,$(CURDIR))), 1) + $(error Sources directory '$(CURDIR)' cannot contain spaces nor colons. Rename directory or move sources to another path) +endif + +######################## +# Extract config value # +######################## + +get_config_value = $(shell ${CC} -E -dM ${CONFIG_FILE} 2> /dev/null |\ + grep -m 1 ${1} | awk '{ print $$3 }') + +################ +# dracut Macro # +################ + +cmd_initrd := $(shell \ + if [[ ${KOBJ} != /lib/modules/${BUILD_KERNEL}/* ]]; then \ + echo ""; \ + elif which dracut > /dev/null 2>&1 ; then \ + echo "dracut --force --kver ${BUILD_KERNEL}"; \ + elif which update-initramfs > /dev/null 2>&1 ; then \ + echo "update-initramfs -u -k ${BUILD_KERNEL}"; \ + fi ) + +######################## +# Check module signing # +######################## + +CONFIG_MODULE_SIG_ALL := $(call get_config_value,CONFIG_MODULE_SIG_ALL) +CONFIG_MODULE_SIG_FORCE := $(call get_config_value,CONFIG_MODULE_SIG_FORCE) +CONFIG_MODULE_SIG_KEY := $(call get_config_value,CONFIG_MODULE_SIG_KEY) + +SIG_KEY_SP := ${KOBJ}/${CONFIG_MODULE_SIG_KEY} \ + ${KOBJ}/certs/signing_key.pem + +SIG_KEY_FILE := $(firstword $(foreach file, ${SIG_KEY_SP}, $(call test_file,${file}))) + +# print a warning if the kernel configuration attempts to sign modules but +# the signing key can't be found. +ifneq (${SIG_KEY_FILE},) +warn_signed_modules := : ; +else +warn_signed_modules := +ifeq (${CONFIG_MODULE_SIG_ALL},1) +warn_signed_modules += \ + echo "*** The target kernel has CONFIG_MODULE_SIG_ALL enabled, but" ; \ + echo "*** the signing key cannot be found. Module signing has been" ; \ + echo "*** disabled for this build." ; +endif # CONFIG_MODULE_SIG_ALL=y +ifeq (${CONFIG_MODULE_SIG_FORCE},1) + warn_signed_modules += \ + echo "warning: The target kernel has CONFIG_MODULE_SIG_FORCE enabled," ; \ + echo "warning: but the signing key cannot be found. The module must" ; \ + echo "warning: be signed manually using 'scripts/sign-file'." ; +endif # CONFIG_MODULE_SIG_FORCE +DISABLE_MODULE_SIGNING := Yes +endif + +####################### +# Linux Version Setup # +####################### + +# The following command line parameter is intended for development of KCOMPAT +# against upstream kernels such as net-next which have broken or non-updated +# version codes in their Makefile. They are intended for debugging and +# development purpose only so that we can easily test new KCOMPAT early. If you +# don't know what this means, you do not need to set this flag. There is no +# arcane magic here. + +# Convert LINUX_VERSION into LINUX_VERSION_CODE +ifneq (${LINUX_VERSION},) + LINUX_VERSION_CODE=$(call get_kvercode,$(call get_kver,${LINUX_VERSION},1),$(call get_kver,${LINUX_VERSION},2),$(call get_kver,${LINUX_VERSION},3)) +endif + +# Honor LINUX_VERSION_CODE +ifneq (${LINUX_VERSION_CODE},) + $(warning Forcing target kernel to build with LINUX_VERSION_CODE of ${LINUX_VERSION_CODE}$(if ${LINUX_VERSION}, from LINUX_VERSION=${LINUX_VERSION}). Do this at your own risk.) + KVER_CODE := ${LINUX_VERSION_CODE} + EXTRA_CFLAGS += -DLINUX_VERSION_CODE=${LINUX_VERSION_CODE} +endif + +# Determine SLE_KERNEL_REVISION for SuSE SLE >= 11 (needed by kcompat) +# This assumes SuSE will continue setting CONFIG_LOCALVERSION to the string +# appended to the stable kernel version on which their kernel is based with +# additional versioning information (up to 3 numbers), a possible abbreviated +# git SHA1 commit id and a kernel type, e.g. CONFIG_LOCALVERSION=-1.2.3-default +# or CONFIG_LOCALVERSION=-999.gdeadbee-default +# SLE >= 15SP3 added additional information about version and service pack +# to their kernel version e.g CONFIG_LOCALVERSION=-150300.59.43.1-default +# +# SLE_LOCALVERSION_CODE is also exported to support legacy kcompat.h +# definitions. +ifeq (1,$(call get_config_value,CONFIG_SUSE_KERNEL)) + +ifneq (10,$(call get_config_value,CONFIG_SLE_VERSION)) + + CONFIG_LOCALVERSION := $(call get_config_value,CONFIG_LOCALVERSION) + LOCALVERSION := $(shell echo ${CONFIG_LOCALVERSION} | \ + cut -d'-' -f2 | sed 's/\.g[[:xdigit:]]\{7\}//') + LOCALVER_A := $(shell echo ${LOCALVERSION} | cut -d'.' -f1) +ifeq ($(shell test ${LOCALVER_A} -gt 65535; echo $$?),0) + LOCAL_VER_MAJOR := $(shell echo ${LOCALVER_A:0:3}) + LOCAL_VER_MINOR := $(shell echo ${LOCALVER_A:3:3}) + LOCALVER_B := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f2) + LOCALVER_C := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f3) + LOCALVER_D := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f4) + SLE_LOCALVERSION_CODE := $(shell expr ${LOCALVER_B} \* 65536 + \ + 0${LOCALVER_C} \* 256 + 0${LOCALVER_D}) + EXTRA_CFLAGS += -DSLE_LOCALVERSION_CODE=${SLE_LOCALVERSION_CODE} + EXTRA_CFLAGS += -DSLE_KERNEL_REVISION=${LOCALVER_B} +else + LOCALVER_B := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f2) + LOCALVER_C := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f3) + SLE_LOCALVERSION_CODE := $(shell expr ${LOCALVER_A} \* 65536 + \ + 0${LOCALVER_B} \* 256 + 0${LOCALVER_C}) + EXTRA_CFLAGS += -DSLE_LOCALVERSION_CODE=${SLE_LOCALVERSION_CODE} + EXTRA_CFLAGS += -DSLE_KERNEL_REVISION=${LOCALVER_A} +endif +endif +endif + +EXTRA_CFLAGS += -std=gnu11 +EXTRA_CFLAGS += ${CFLAGS_EXTRA} + +# get the kernel version - we use this to find the correct install path +KVER := $(shell ${CC} ${EXTRA_CFLAGS} -E -dM ${VERSION_FILE} | grep UTS_RELEASE | \ + awk '{ print $$3 }' | sed 's/\"//g') + +# assume source symlink is the same as build, otherwise adjust KOBJ +ifneq (,$(wildcard /lib/modules/${KVER}/build)) + ifneq (${KSRC},$(call readlink,/lib/modules/${KVER}/build)) + KOBJ=/lib/modules/${KVER}/build + endif +endif + +ifeq (${KVER_CODE},) + KVER_CODE := $(shell ${CC} ${EXTRA_CFLAGS} -E -dM ${VSP} 2> /dev/null |\ + grep -m 1 LINUX_VERSION_CODE | awk '{ print $$3 }' | sed 's/\"//g') +endif + +# minimum_kver_check +# +# helper function to provide uniform output for different drivers to abort the +# build based on kernel version check. Usage: "$(call minimum_kver_check,2,6,XX)". +define _minimum_kver_check +ifeq (0,$(shell [ ${KVER_CODE} -lt $(call get_kvercode,${1},${2},${3}) ]; echo "$$?")) + $$(warning *** Aborting the build.) + $$(error This driver is not supported on kernel versions older than ${1}.${2}.${3}) +endif +endef +minimum_kver_check = $(eval $(call _minimum_kver_check,${1},${2},${3})) + +############################# +# kcompat definitions setup # +############################# + +# In most cases, kcompat flags can be checked within the driver source files +# using simple CPP checks. However, it may be necessary to check for a flag +# value within the Makefile for some specific edge cases. For example, if an +# entire feature ought to be excluded on some kernels due to missing +# functionality. +# +# To support this, kcompat_defs.h is preprocessed and converted into a word list +# that can be checked to determine whether a given kcompat feature flag will +# be defined for this kernel. +# + +# call script that populates defines automatically +$(if $(shell \ + $(if $(findstring 1,${V}),,QUIET_COMPAT=1) \ + KSRC=${KSRC} OUT=${src}/kcompat_generated_defs.h CONFIG_FILE=${CONFIG_FILE} \ + bash ${src}/kcompat-generator.sh && echo ok), , $(error kcompat-generator.sh failed)) + +################ +# Manual Pages # +################ + +MANSECTION = 7 + +ifeq (,${MANDIR}) + # find the best place to install the man page + MANPATH := $(shell (manpath 2>/dev/null || echo $MANPATH) | sed 's/:/ /g') + ifneq (,${MANPATH}) + # test based on inclusion in MANPATH + test_dir = $(findstring ${dir}, ${MANPATH}) + else + # no MANPATH, test based on directory existence + test_dir = $(shell [ -e ${dir} ] && echo ${dir}) + endif + # our preferred install path + # should /usr/local/man be in here ? + MANDIR := /usr/share/man /usr/man + MANDIR := $(foreach dir, ${MANDIR}, ${test_dir}) + MANDIR := $(firstword ${MANDIR}) +endif +ifeq (,${MANDIR}) + # fallback to /usr/man + MANDIR := /usr/man +endif + +#################### +# CCFLAGS variable # +#################### + +# set correct CCFLAGS variable for kernels older than 2.6.24 +ifeq (0,$(shell [ ${KVER_CODE} -lt $(call get_kvercode,2,6,24) ]; echo $$?)) +CCFLAGS_VAR := EXTRA_CFLAGS +else +CCFLAGS_VAR := ccflags-y +endif + +################# +# KBUILD_OUTPUT # +################# + +# Only set KBUILD_OUTPUT if the real paths of KOBJ and KSRC differ +ifneq ($(call readlink,${KSRC}),$(call readlink,${KOBJ})) +export KBUILD_OUTPUT ?= ${KOBJ} +endif + +############################ +# Module Install Directory # +############################ + +# Default to using updates/drivers/net/ethernet/intel/ path, since depmod since +# v3.1 defaults to checking updates folder first, and only checking kernels/ +# and extra afterwards. We use updates instead of kernel/* due to desire to +# prevent over-writing built-in modules files. +export INSTALL_MOD_DIR ?= updates/drivers/net/ethernet/intel/${DRIVER} + +################# +# Auxiliary Bus # +################# + +# If the check_aux_bus script exists, then this driver depends on the +# auxiliary module. Run the script to determine if we need to include +# auxiliary files with this build. +CHECK_AUX_BUS ?= ../scripts/check_aux_bus +ifneq ($(call test_file,${CHECK_AUX_BUS}),) +NEED_AUX_BUS := $(shell ${CHECK_AUX_BUS} --ksrc="${KSRC}" --build-kernel="${BUILD_KERNEL}" >/dev/null 2>&1; echo $$?) +endif # check_aux_bus exists + +# The out-of-tree auxiliary module we ship should be moved into this +# directory as part of installation. +export INSTALL_AUX_DIR ?= updates/drivers/net/ethernet/intel/auxiliary + +# If we're installing auxiliary bus out-of-tree, the following steps are +# necessary to ensure the relevant files get put in place. +AUX_BUS_HEADERS ?= linux/auxiliary_bus.h auxiliary_compat.h kcompat_generated_defs.h +ifeq (${NEED_AUX_BUS},2) +define auxiliary_post_install + install -D -m 644 Module.symvers ${INSTALL_MOD_PATH}/lib/modules/${KVER}/extern-symvers/intel_auxiliary.symvers + install -d ${INSTALL_MOD_PATH}/lib/modules/${KVER}/${INSTALL_AUX_DIR} + mv -f ${INSTALL_MOD_PATH}/lib/modules/${KVER}/${INSTALL_MOD_DIR}/intel_auxiliary.ko* \ + ${INSTALL_MOD_PATH}/lib/modules/${KVER}/${INSTALL_AUX_DIR}/ + install -d ${INSTALL_MOD_PATH}/${KSRC}/include/linux + install -D -m 644 ${AUX_BUS_HEADERS} -t ${INSTALL_MOD_PATH}/${KSRC}/include/linux +endef +else +auxiliary_post_install = +endif + +ifeq (${NEED_AUX_BUS},2) +define auxiliary_post_uninstall + rm -f ${INSTALL_MOD_PATH}/lib/modules/${KVER}/extern-symvers/intel_auxiliary.symvers + rm -f ${INSTALL_MOD_PATH}/lib/modules/${KVER}/${INSTALL_AUX_DIR}/intel_auxiliary.ko* + rm -f ${INSTALL_MOD_PATH}/${KSRC}/include/linux/auxiliary_bus.h + rm -f ${INSTALL_MOD_PATH}/${KSRC}/include/linux/auxiliary_compat.h + rm -f ${INSTALL_MOD_PATH}/${KSRC}/include/linux/kcompat_generated_defs.h +endef +else +auxiliary_post_uninstall = +endif + +ifeq (${NEED_AUX_BUS},2) +EXTRA_CFLAGS += -DUSE_INTEL_AUX_BUS +endif +###################### +# Kernel Build Macro # +###################### + +# kernel build function +# ${1} is the kernel build target +# ${2} may contain any extra rules to pass directly to the sub-make process +# +# This function is expected to be executed by +# @+$(call kernelbuild,,) +# from within a Makefile recipe. +# +# The following variables are expected to be defined for its use: +# GCC_I_SYS -- if set it will enable use of gcc-i-sys.sh wrapper to use -isystem +# CCFLAGS_VAR -- the CCFLAGS variable to set extra CFLAGS +# EXTRA_CFLAGS -- a set of extra CFLAGS to pass into the ccflags-y variable +# KSRC -- the location of the kernel source tree to build against +# DRIVER_UPPERCASE -- the uppercase name of the kernel module, set from DRIVER +# W -- if set, enables the W= kernel warnings options +# C -- if set, enables the C= kernel sparse build options +# +kernelbuild = ${Q}$(call warn_signed_modules) \ + ${MAKE} $(if ${GCC_I_SYS},CC="${GCC_I_SYS}") \ + ${CCFLAGS_VAR}="${EXTRA_CFLAGS}" \ + -C "${KSRC}" \ + CONFIG_${DRIVER_UPPERCASE}=m \ + $(if ${DISABLE_MODULE_SIGNING},CONFIG_MODULE_SIG=n) \ + $(if ${DISABLE_MODULE_SIGNING},CONFIG_MODULE_SIG_ALL=) \ + M="${CURDIR}" \ + $(if ${W},W="${W}") \ + $(if ${C},C="${C}") \ + $(if ${NEED_AUX_BUS},NEED_AUX_BUS="${NEED_AUX_BUS}") \ + ${2} ${1} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe.h new file mode 100644 index 0000000000..00c072a1df --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe.h @@ -0,0 +1,1547 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_H_ +#define _IXGBE_H_ + +#include "kcompat.h" +#include "kcompat_kthread.h" + +#include +#include + +#include +#include +#include +#include +#ifdef SIOCETHTOOL +#include +#endif +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) +#include +#endif +/* Can't use IS_ENABLED until after kcompat is loaded */ +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) +#define IXGBE_DCA +#include +#endif +#include +#include "ixgbe_dcb.h" + +#ifdef HAVE_XDP_BUFF_RXQ +#include +#endif + +#ifdef HAVE_NDO_BUSY_POLL +#include +#define BP_EXTENDED_STATS +#endif + +#ifdef HAVE_SCTP +#include +#endif + +#ifdef HAVE_INCLUDE_LINUX_MDIO_H +#include +#endif + +#if IS_ENABLED(CONFIG_FCOE) +#include "ixgbe_fcoe.h" +#endif /* CONFIG_FCOE */ + +#include "ixgbe_api.h" + +#if IS_ENABLED(CONFIG_NET_DEVLINK) +#include +#endif /* CONFIG_NET_DEVLINK */ + +#include "ixgbe_e610.h" +#include "ixgbe_common.h" + +#define DPRINTK(nlevel, klevel, fmt, args...) \ + ((NETIF_MSG_##nlevel & adapter->msg_enable) ? \ + (void)(netdev_printk(KERN_##klevel, adapter->netdev, \ + "%s: " fmt, __func__, ## args)) : NULL) + +#ifdef HAVE_PTP_1588_CLOCK +#ifdef HAVE_INCLUDE_LINUX_TIMECOUNTER_H +#include +#endif /* HAVE_INCLUDE_TIMECOUNTER_H */ +#include +#include +#include +#endif + +/* Features advertised by PF driver */ +#define IXGBE_SUPPORTED_FEATURES 0 + +/* TX/RX descriptor defines */ +#define IXGBE_DEFAULT_TXD 512 +#define IXGBE_DEFAULT_TX_WORK 256 + +#define IXGBE_DEFAULT_RXD 512 + +#define IXGBE_MAX_NUM_DESCRIPTORS 4096 +#define IXGBE_MIN_NUM_DESCRIPTORS 64 + +#define IXGBE_ETH_P_LLDP 0x88CC + + +/* flow control */ +#define IXGBE_MIN_FCRTL 0x40 +#define IXGBE_MAX_FCRTL 0x7FF80 +#define IXGBE_MIN_FCRTH 0x600 +#define IXGBE_MAX_FCRTH 0x7FFF0 +#define IXGBE_DEFAULT_FCPAUSE 0xFFFF +#define IXGBE_MIN_FCPAUSE 0 +#define IXGBE_MAX_FCPAUSE 0xFFFF + +/* Supported Rx Buffer Sizes */ +#define IXGBE_RXBUFFER_256 256 /* Used for skb receive header */ +#define IXGBE_RXBUFFER_1536 1536 +#define IXGBE_RXBUFFER_2K 2048 +#define IXGBE_RXBUFFER_3K 3072 +#define IXGBE_RXBUFFER_4K 4096 +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +#define IXGBE_RXBUFFER_7K 7168 +#define IXGBE_RXBUFFER_8K 8192 +#define IXGBE_RXBUFFER_15K 15360 +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ +#define IXGBE_MAX_RXBUFFER 16384 /* largest size for single descriptor */ + +/* Attempt to maximize the headroom available for incoming frames. We + * use a 2K buffer for receives and need 1536/1534 to store the data for + * the frame. This leaves us with 512 bytes of room. From that we need + * to deduct the space needed for the shared info and the padding needed + * to IP align the frame. + * + * Note: For cache line sizes 256 or larger this value is going to end + * up negative. In these cases we should fall back to the 3K + * buffers. + */ +#if (PAGE_SIZE < 8192) +#define IXGBE_MAX_2K_FRAME_BUILD_SKB (IXGBE_RXBUFFER_1536 - NET_IP_ALIGN) +#define IXGBE_2K_TOO_SMALL_WITH_PADDING \ +((NET_SKB_PAD + IXGBE_RXBUFFER_1536) > SKB_WITH_OVERHEAD(IXGBE_RXBUFFER_2K)) + +static inline int ixgbe_compute_pad(int rx_buf_len) +{ + int page_size, pad_size; + + page_size = ALIGN(rx_buf_len, PAGE_SIZE / 2); + pad_size = SKB_WITH_OVERHEAD(page_size) - rx_buf_len; + + return pad_size; +} + +static inline int ixgbe_skb_pad(void) +{ + int rx_buf_len; + + /* If a 2K buffer cannot handle a standard Ethernet frame then + * optimize padding for a 3K buffer instead of a 1.5K buffer. + * + * For a 3K buffer we need to add enough padding to allow for + * tailroom due to NET_IP_ALIGN possibly shifting us out of + * cache-line alignment. + */ + if (IXGBE_2K_TOO_SMALL_WITH_PADDING) + rx_buf_len = IXGBE_RXBUFFER_3K + SKB_DATA_ALIGN(NET_IP_ALIGN); + else + rx_buf_len = IXGBE_RXBUFFER_1536; + + /* if needed make room for NET_IP_ALIGN */ + rx_buf_len -= NET_IP_ALIGN; + + return ixgbe_compute_pad(rx_buf_len); +} + +#define IXGBE_SKB_PAD ixgbe_skb_pad() +#else +#define IXGBE_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN) +#endif + +/* + * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN means we + * reserve 64 more, and skb_shared_info adds an additional 320 bytes more, + * this adds up to 448 bytes of extra data. + * + * Since netdev_alloc_skb now allocates a page fragment we can use a value + * of 256 and the resultant skb will have a truesize of 960 or less. + */ +#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256 + +#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) + +/* How many Rx Buffers do we bundle into one write to the hardware ? */ +#define IXGBE_RX_BUFFER_WRITE 16 /* Must be power of 2 */ + +#ifdef HAVE_STRUCT_DMA_ATTRS +#define IXGBE_RX_DMA_ATTR NULL +#else +#define IXGBE_RX_DMA_ATTR \ + (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING) +#endif + +/* assume the kernel supports 8021p to avoid stripping vlan tags */ +#ifdef IXGBE_DISABLE_8021P_SUPPORT +#ifndef HAVE_8021P_SUPPORT +#define HAVE_8021P_SUPPORT +#endif +#endif /* IXGBE_DISABLE_8021P_SUPPORT */ + +enum ixgbe_tx_flags { + /* cmd_type flags */ + IXGBE_TX_FLAGS_HW_VLAN = 0x01, + IXGBE_TX_FLAGS_TSO = 0x02, + IXGBE_TX_FLAGS_TSTAMP = 0x04, + + /* olinfo flags */ + IXGBE_TX_FLAGS_CC = 0x08, + IXGBE_TX_FLAGS_IPV4 = 0x10, + IXGBE_TX_FLAGS_CSUM = 0x20, + + /* software defined flags */ + IXGBE_TX_FLAGS_SW_VLAN = 0x40, + IXGBE_TX_FLAGS_FCOE = 0x80, +}; + +/* VLAN info */ +#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 +#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000 +#define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29 +#define IXGBE_TX_FLAGS_VLAN_SHIFT 16 + +#define IXGBE_MAX_RX_DESC_POLL 10 + +#define IXGBE_MAX_VF_MC_ENTRIES 30 +#define IXGBE_MAX_VF_FUNCTIONS 64 +#define IXGBE_MAX_VFTA_ENTRIES 128 +#define MAX_EMULATION_MAC_ADDRS 16 +#define IXGBE_MAX_PF_MACVLANS 15 + +/* must account for pools assigned to VFs. */ +#ifdef CONFIG_PCI_IOV +#define VMDQ_P(p) ((p) + adapter->ring_feature[RING_F_VMDQ].offset) +#else +#define VMDQ_P(p) (p) +#endif + +#define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter) \ + { \ + u32 current_counter = IXGBE_READ_REG(hw, reg); \ + if (current_counter < last_counter) \ + counter += 0x100000000LL; \ + last_counter = current_counter; \ + counter &= 0xFFFFFFFF00000000LL; \ + counter |= current_counter; \ + } + +#define UPDATE_VF_COUNTER_36bit(reg_lsb, reg_msb, last_counter, counter) \ + { \ + u64 current_counter_lsb = IXGBE_READ_REG(hw, reg_lsb); \ + u64 current_counter_msb = IXGBE_READ_REG(hw, reg_msb); \ + u64 current_counter = (current_counter_msb << 32) | \ + current_counter_lsb; \ + if (current_counter < last_counter) \ + counter += 0x1000000000LL; \ + last_counter = current_counter; \ + counter &= 0xFFFFFFF000000000LL; \ + counter |= current_counter; \ + } + +struct vf_stats { + u64 gprc; + u64 gorc; + u64 gptc; + u64 gotc; + u64 mprc; +}; + +struct vf_data_storage { + struct pci_dev *vfdev; + unsigned char vf_mac_addresses[ETH_ALEN]; + u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES]; + u16 num_vf_mc_hashes; + bool clear_to_send; + struct vf_stats vfstats; + struct vf_stats last_vfstats; + struct vf_stats saved_rst_vfstats; + bool pf_set_mac; + u16 pf_vlan; /* When set, guest VLAN config not allowed. */ + u16 pf_qos; + u16 tx_rate; + int link_enable; +#ifdef HAVE_NDO_SET_VF_LINK_STATE + int link_state; +#endif + u8 spoofchk_enabled; +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN + bool rss_query_enabled; +#endif + u8 trusted; + int xcast_mode; + unsigned int vf_api; + u8 primary_abort_count; +}; + +struct vf_macvlans { + struct list_head l; + int vf; + bool free; + bool is_macvlan; + u8 vf_macvlan[ETH_ALEN]; +}; + +#define IXGBE_MAX_TXD_PWR 14 +#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) + +/* Tx Descriptors needed, worst case */ +#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IXGBE_MAX_DATA_PER_TXD) +#ifndef MAX_SKB_FRAGS +#define DESC_NEEDED 4 +#elif (MAX_SKB_FRAGS < 16) +#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4) +#else +#define DESC_NEEDED (MAX_SKB_FRAGS + 4) +#endif + +/* wrapper around a pointer to a socket buffer, + * so a DMA handle can be stored along with the buffer */ +struct ixgbe_tx_buffer { + union ixgbe_adv_tx_desc *next_to_watch; + unsigned long time_stamp; + union { + struct sk_buff *skb; +#ifdef HAVE_XDP_FRAME_STRUCT + struct xdp_frame *xdpf; +#else + /* XDP uses address ptr on irq_clean */ + void *data; +#endif + }; + unsigned int bytecount; + unsigned short gso_segs; + __be16 protocol; + DEFINE_DMA_UNMAP_ADDR(dma); + DEFINE_DMA_UNMAP_LEN(len); + u32 tx_flags; +}; + +struct ixgbe_rx_buffer { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct sk_buff *skb; + dma_addr_t dma; +#endif +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + union { + struct { +#ifdef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct sk_buff *skb; + dma_addr_t dma; +#endif + struct page *page; + __u32 page_offset; + __u16 pagecnt_bias; + }; +#ifdef HAVE_AF_XDP_ZC_SUPPORT + struct { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + void *addr; + u64 handle; +#else + bool discard; + struct xdp_buff *xdp; +#endif + }; +#endif + }; +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ +}; + +struct ixgbe_queue_stats { + u64 packets; + u64 bytes; +#ifdef BP_EXTENDED_STATS + u64 yields; + u64 misses; + u64 cleaned; +#endif /* BP_EXTENDED_STATS */ +}; + +struct ixgbe_tx_queue_stats { + u64 restart_queue; + u64 tx_busy; + u64 tx_done_old; +}; + +struct ixgbe_rx_queue_stats { + u64 rsc_count; + u64 rsc_flush; + u64 non_eop_descs; + u64 alloc_rx_page; + u64 alloc_rx_page_failed; + u64 alloc_rx_buff_failed; + u64 csum_err; +}; + +#define IXGBE_TS_HDR_LEN 8 +enum ixgbe_ring_state_t { +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + __IXGBE_RX_3K_BUFFER, + __IXGBE_RX_BUILD_SKB_ENABLED, +#endif + __IXGBE_RX_RSC_ENABLED, + __IXGBE_RX_CSUM_UDP_ZERO_ERR, +#if IS_ENABLED(CONFIG_FCOE) + __IXGBE_RX_FCOE, +#endif + __IXGBE_TX_FDIR_INIT_DONE, + __IXGBE_TX_XPS_INIT_DONE, + __IXGBE_TX_DETECT_HANG, + __IXGBE_HANG_CHECK_ARMED, + __IXGBE_TX_XDP_RING, +#ifdef HAVE_AF_XDP_ZC_SUPPORT + __IXGBE_TX_DISABLED, +#endif +}; +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + +#define ring_uses_build_skb(ring) \ + test_bit(__IXGBE_RX_BUILD_SKB_ENABLED, &(ring)->state) +#endif + +#define check_for_tx_hang(ring) \ + test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) +#define set_check_for_tx_hang(ring) \ + set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) +#define clear_check_for_tx_hang(ring) \ + clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) +#define ring_is_rsc_enabled(ring) \ + test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) +#define set_ring_rsc_enabled(ring) \ + set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) +#define clear_ring_rsc_enabled(ring) \ + clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) +#define ring_is_xdp(ring) \ + test_bit(__IXGBE_TX_XDP_RING, &(ring)->state) +#define set_ring_xdp(ring) \ + set_bit(__IXGBE_TX_XDP_RING, &(ring)->state) +#define clear_ring_xdp(ring) \ + clear_bit(__IXGBE_TX_XDP_RING, &(ring)->state) +#define netdev_ring(ring) (ring->netdev) +#define ring_queue_index(ring) (ring->queue_index) + + +struct ixgbe_ring { + struct ixgbe_ring *next; /* pointer to next ring in q_vector */ + struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */ + struct net_device *netdev; /* netdev ring belongs to */ + struct bpf_prog *xdp_prog; + struct device *dev; /* device for DMA mapping */ + void *desc; /* descriptor ring memory */ + union { + struct ixgbe_tx_buffer *tx_buffer_info; + struct ixgbe_rx_buffer *rx_buffer_info; + }; + unsigned long state; + u8 __iomem *tail; + dma_addr_t dma; /* phys. address of descriptor ring */ + unsigned int size; /* length in bytes */ + + u16 count; /* amount of descriptors */ + + u8 queue_index; /* needed for multiqueue queue management */ + u8 reg_idx; /* holds the special value that gets + * the hardware register offset + * associated with this ring, which is + * different for DCB and RSS modes + */ + u16 next_to_use; + u16 next_to_clean; + +#ifdef HAVE_PTP_1588_CLOCK + unsigned long last_rx_timestamp; + +#endif + union { +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + u16 rx_buf_len; +#else + union { + u16 next_to_alloc; + u16 next_rs_idx; + }; +#endif + struct { + u8 atr_sample_rate; + u8 atr_count; + }; + }; + +#ifdef HAVE_XDP_SUPPORT +#ifdef HAVE_AF_XDP_ZC_SUPPORT + u16 xdp_tx_active; +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif /* HAVE_XDP_SUPPORT */ + + u8 dcb_tc; + struct ixgbe_queue_stats stats; +#ifdef HAVE_NDO_GET_STATS64 + struct u64_stats_sync syncp; +#endif + union { + struct ixgbe_tx_queue_stats tx_stats; + struct ixgbe_rx_queue_stats rx_stats; + }; + u16 rx_offset; + spinlock_t tx_lock; /* used in XDP mode */ +#ifdef HAVE_XDP_BUFF_RXQ + struct xdp_rxq_info xdp_rxq; +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#ifdef HAVE_NETDEV_BPF_XSK_POOL + struct xsk_buff_pool *xsk_pool; +#else + struct xdp_umem *xsk_pool; +#endif +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct zero_copy_allocator zca; /* ZC allocator anchor */ +#endif + u16 ring_idx; /* {rx,tx,xdp}_ring back reference idx */ + u16 rx_buf_len; +#endif +#endif +} ____cacheline_internodealigned_in_smp; + +enum ixgbe_ring_f_enum { + RING_F_NONE = 0, + RING_F_VMDQ, /* SR-IOV uses the same ring feature */ + RING_F_RSS, + RING_F_FDIR, +#if IS_ENABLED(CONFIG_FCOE) + RING_F_FCOE, +#endif /* CONFIG_FCOE */ + RING_F_ARRAY_SIZE /* must be last in enum set */ +}; + +#define IXGBE_MAX_DCB_INDICES 8 +#define IXGBE_MAX_RSS_INDICES 16 +#define IXGBE_MAX_RSS_INDICES_X550 63 +#define IXGBE_MAX_RSS_INDICES_E610 63 +#define IXGBE_MAX_VMDQ_INDICES 64 +#define IXGBE_MAX_FDIR_INDICES 63 +#if IS_ENABLED(CONFIG_FCOE) +#define IXGBE_MAX_FCOE_INDICES 8 +#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES) +#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES) +#else +#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1) +#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1) +#endif /* CONFIG_FCOE */ +#define IXGBE_MAX_XDP_QS (IXGBE_MAX_FDIR_INDICES + 1) + +#define IXGBE_MAX_TX_QUEUES 128 +#define IXGBE_MAX_TX_DESCRIPTORS 40 +#define IXGBE_MAX_TX_VF_HANGS 4 + +DECLARE_STATIC_KEY_FALSE(ixgbe_xdp_locking_key); + +struct ixgbe_ring_feature { + u16 limit; /* upper limit on feature indices */ + u16 indices; /* current value of indices */ + u16 mask; /* Mask used for feature to ring mapping */ + u16 offset; /* offset to start of feature */ +}; + +#define IXGBE_82599_VMDQ_8Q_MASK 0x78 +#define IXGBE_82599_VMDQ_4Q_MASK 0x7C +#define IXGBE_82599_VMDQ_2Q_MASK 0x7E + +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +/* + * FCoE requires that all Rx buffers be over 2200 bytes in length. Since + * this is twice the size of a half page we need to double the page order + * for FCoE enabled Rx queues. + */ +static inline unsigned int ixgbe_rx_bufsz(struct ixgbe_ring __maybe_unused *ring) +{ +#if MAX_SKB_FRAGS < 8 + return ALIGN(IXGBE_MAX_RXBUFFER / MAX_SKB_FRAGS, 1024); +#else + if (test_bit(__IXGBE_RX_3K_BUFFER, &ring->state)) + return IXGBE_RXBUFFER_3K; +#if (PAGE_SIZE < 8192) + if (ring_uses_build_skb(ring)) + return IXGBE_MAX_2K_FRAME_BUILD_SKB; +#endif + return IXGBE_RXBUFFER_2K; +#endif +} + +static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring __maybe_unused *ring) +{ +#if (PAGE_SIZE < 8192) + if (test_bit(__IXGBE_RX_3K_BUFFER, &ring->state)) + return 1; +#endif + return 0; +} +#define ixgbe_rx_pg_size(_ring) (PAGE_SIZE << ixgbe_rx_pg_order(_ring)) + +#else +static inline unsigned int ixgbe_rx_bufsz(struct ixgbe_ring *ring) +{ + return ring->rx_buf_len; +} +#endif +#define IXGBE_ITR_ADAPTIVE_MIN_INC 2 +#define IXGBE_ITR_ADAPTIVE_MIN_USECS 10 +#define IXGBE_ITR_ADAPTIVE_MAX_USECS 84 +#define IXGBE_ITR_ADAPTIVE_LATENCY 0x80 +#define IXGBE_ITR_ADAPTIVE_BULK 0x00 +#define IXGBE_ITR_ADAPTIVE_MASK_USECS (IXGBE_ITR_ADAPTIVE_LATENCY - \ + IXGBE_ITR_ADAPTIVE_MIN_INC) + +struct ixgbe_ring_container { + struct ixgbe_ring *ring; /* pointer to linked list of rings */ + unsigned long next_update; /* jiffies value of last update */ + unsigned int total_bytes; /* total bytes processed this int */ + unsigned int total_packets; /* total packets processed this int */ + u16 work_limit; /* total work allowed per interrupt */ + u8 count; /* total number of rings in vector */ + u8 itr; /* current ITR setting for ring */ +}; + +#define ixgbe_pf_to_dev(pf) (&((pf)->pdev->dev)) + +/* iterator for handling rings in ring container */ +#define ixgbe_for_each_ring(pos, head) \ + for (pos = (head).ring; pos != NULL; pos = pos->next) + +#define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ + ? 8 : 1) +#define MAX_TX_PACKET_BUFFERS MAX_RX_PACKET_BUFFERS + +#define IXGBE_IFNAMSIZ (IFNAMSIZ + 9) + +/* MAX_MSIX_Q_VECTORS of these are allocated, + * but we only use one per queue-specific vector. + */ +struct ixgbe_q_vector { + struct ixgbe_adapter *adapter; + int cpu; /* CPU for DCA */ + u16 v_idx; /* index of q_vector within array, also used for + * finding the bit in EICR and friends that + * represents the vector for this ring */ + u16 itr; /* Interrupt throttle rate written to EITR */ + struct ixgbe_ring_container rx, tx; + + struct napi_struct napi; +#ifndef HAVE_NETDEV_NAPI_LIST + struct net_device poll_dev; +#endif +#ifdef HAVE_IRQ_AFFINITY_HINT + cpumask_t affinity_mask; +#endif + int node; + struct rcu_head rcu; /* to avoid race with update stats on free */ + char name[IXGBE_IFNAMSIZ]; + bool netpoll_rx; + +#ifdef HAVE_NDO_BUSY_POLL + atomic_t state; +#endif /* HAVE_NDO_BUSY_POLL */ +#ifdef HAVE_PTP_1588_CLOCK + struct list_head ptp_skbs_e600; + spinlock_t ptp_skbs_lock_e600; /* Protects ptp_skbs_e600 access. */ + bool ptp_hold_rx_skb : 1; +#endif /* HAVE_PTP_1588_CLOCK */ + + /* for dynamic allocation of rings associated with this q_vector */ + struct ixgbe_ring ring[0] ____cacheline_internodealigned_in_smp; +}; + +#ifdef HAVE_NDO_BUSY_POLL +enum ixgbe_qv_state_t { + IXGBE_QV_STATE_IDLE = 0, + IXGBE_QV_STATE_NAPI, + IXGBE_QV_STATE_POLL, + IXGBE_QV_STATE_DISABLE +}; + +static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector) +{ + /* reset state to idle */ + atomic_set(&q_vector->state, IXGBE_QV_STATE_IDLE); +} + +/* called from the device poll routine to get ownership of a q_vector */ +static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector) +{ + int rc = atomic_cmpxchg(&q_vector->state, IXGBE_QV_STATE_IDLE, + IXGBE_QV_STATE_NAPI); +#ifdef BP_EXTENDED_STATS + if (rc != IXGBE_QV_STATE_IDLE) + q_vector->tx.ring->stats.yields++; +#endif + + return rc == IXGBE_QV_STATE_IDLE; +} + +/* returns true is someone tried to get the qv while napi had it */ +static inline void ixgbe_qv_unlock_napi(struct ixgbe_q_vector *q_vector) +{ + WARN_ON(atomic_read(&q_vector->state) != IXGBE_QV_STATE_NAPI); + + /* flush any outstanding Rx frames */ + if (q_vector->napi.gro_list) + napi_gro_flush(&q_vector->napi, false); + + /* reset state to idle */ + atomic_set(&q_vector->state, IXGBE_QV_STATE_IDLE); +} + +/* called from ixgbe_low_latency_poll() */ +static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector) +{ + int rc = atomic_cmpxchg(&q_vector->state, IXGBE_QV_STATE_IDLE, + IXGBE_QV_STATE_POLL); +#ifdef BP_EXTENDED_STATS + if (rc != IXGBE_QV_STATE_IDLE) + q_vector->rx.ring->stats.yields++; +#endif + return rc == IXGBE_QV_STATE_IDLE; +} + +/* returns true if someone tried to get the qv while it was locked */ +static inline void ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector) +{ + WARN_ON(atomic_read(&q_vector->state) != IXGBE_QV_STATE_POLL); + + /* reset state to idle */ + atomic_set(&q_vector->state, IXGBE_QV_STATE_IDLE); +} + +/* true if a socket is polling, even if it did not get the lock */ +static inline bool ixgbe_qv_busy_polling(struct ixgbe_q_vector *q_vector) +{ + return atomic_read(&q_vector->state) == IXGBE_QV_STATE_POLL; +} + +/* false if QV is currently owned */ +static inline bool ixgbe_qv_disable(struct ixgbe_q_vector *q_vector) +{ + int rc = atomic_cmpxchg(&q_vector->state, IXGBE_QV_STATE_IDLE, + IXGBE_QV_STATE_DISABLE); + + return rc == IXGBE_QV_STATE_IDLE; +} + +#endif /* HAVE_NDO_BUSY_POLL */ +#ifdef IXGBE_HWMON + +#define IXGBE_HWMON_TYPE_LOC 0 +#define IXGBE_HWMON_TYPE_TEMP 1 +#define IXGBE_HWMON_TYPE_CAUTION 2 +#define IXGBE_HWMON_TYPE_MAX 3 + +struct hwmon_attr { + struct device_attribute dev_attr; + struct ixgbe_hw *hw; + struct ixgbe_thermal_diode_data *sensor; + char name[12]; +}; + +struct hwmon_buff { +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + struct attribute_group group; + const struct attribute_group *groups[2]; + struct attribute *attrs[IXGBE_MAX_SENSORS * 4 + 1]; + struct hwmon_attr hwmon_list[IXGBE_MAX_SENSORS * 4]; +#else + struct device *device; + struct hwmon_attr *hwmon_list; +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ + unsigned int n_hwmon; +}; +#endif /* IXGBE_HWMON */ + +struct ixgbe_fwlog_user_input { + unsigned long events; +#define IXGBE_FWLOG_METHOD_ARQ 0 +#define IXGBE_FWLOG_METHOD_UART 1 + u8 log_method; + u8 log_level; +}; + +/* + * microsecond values for various ITR rates shifted by 2 to fit itr register + * with the first 3 bits reserved 0 + */ +#define IXGBE_MIN_RSC_ITR 24 +#define IXGBE_100K_ITR 40 +#define IXGBE_20K_ITR 200 +#define IXGBE_16K_ITR 248 +#define IXGBE_12K_ITR 336 + +/* ixgbe_test_staterr - tests bits in Rx descriptor status and error fields */ +static inline __le32 ixgbe_test_staterr(union ixgbe_adv_rx_desc *rx_desc, + const u32 stat_err_bits) +{ + return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits); +} + +/* ixgbe_desc_unused - calculate if we have unused descriptors */ +static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring) +{ + u16 ntc = ring->next_to_clean; + u16 ntu = ring->next_to_use; + + return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1; +} + +#define IXGBE_RX_DESC(R, i) \ + (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) +#define IXGBE_TX_DESC(R, i) \ + (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i])) +#define IXGBE_TX_CTXTDESC(R, i) \ + (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i])) + +#define IXGBE_MAX_JUMBO_FRAME_SIZE 9728 +#if IS_ENABLED(CONFIG_FCOE) +/* use 3K as the baby jumbo frame size for FCoE */ +#define IXGBE_FCOE_JUMBO_FRAME_SIZE 3072 +#endif /* CONFIG_FCOE */ + +#define TCP_TIMER_VECTOR 0 +#define OTHER_VECTOR 1 +#define NON_Q_VECTORS (OTHER_VECTOR + TCP_TIMER_VECTOR) + +#define IXGBE_MAX_MSIX_Q_VECTORS_82599 64 +#define IXGBE_MAX_MSIX_Q_VECTORS_82598 16 + +struct ixgbe_mac_addr { + u8 addr[ETH_ALEN]; + u16 pool; + u16 state; /* bitmask */ +}; + +#define IXGBE_MAC_STATE_DEFAULT 0x1 +#define IXGBE_MAC_STATE_MODIFIED 0x2 +#define IXGBE_MAC_STATE_IN_USE 0x4 + +#ifdef IXGBE_PROCFS +struct ixgbe_therm_proc_data { + struct ixgbe_hw *hw; + struct ixgbe_thermal_diode_data *sensor_data; +}; + +#endif /* IXGBE_PROCFS */ +/* + * Only for array allocations in our adapter struct. On 82598, there will be + * unused entries in the array, but that's not a big deal. Also, in 82599, + * we can actually assign 64 queue vectors based on our extended-extended + * interrupt registers. This is different than 82598, which is limited to 16. + */ +#define MAX_MSIX_Q_VECTORS IXGBE_MAX_MSIX_Q_VECTORS_82599 +#define MAX_MSIX_COUNT IXGBE_MAX_MSIX_VECTORS_82599 + + +#define MIN_MSIX_Q_VECTORS 1 +#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS) + +/* default to trying for four seconds */ +#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) +#define IXGBE_SFP_POLL_JIFFIES (2 * HZ) /* SFP poll every 2 seconds */ + +#define IXGBE_PRIMARY_ABORT_LIMIT 5 + +enum ixgbe_state_t { + __IXGBE_TESTING, + __IXGBE_RESETTING, + __IXGBE_DOWN, + __IXGBE_DISABLED, + __IXGBE_REMOVING, + __IXGBE_SERVICE_SCHED, + __IXGBE_SERVICE_INITED, + __IXGBE_IN_SFP_INIT, +#ifdef HAVE_PTP_1588_CLOCK + __IXGBE_PTP_RUNNING, + __IXGBE_PTP_TX_IN_PROGRESS, +#endif + __IXGBE_RESET_REQUESTED, + __IXGBE_STATE_T_NUM /* Must be last */ +}; + +#ifdef HAVE_PTP_1588_CLOCK +/** struct ixgbe_rx_phy_ts_skb_e610 - tracker for E610 PHY Rx timestamps or Rx + * PTP skbs + * + * This structure contains data for tracking Rx PTP packets. It's used either + * for a single Rx PTP skb or for a single Rx timestamp from the PHY. + * + * @list: list member structure + * @ns: Rx timestamp in nanoseconds + * @skb: Rx PTP skb + * @acquired: time when TS/skb was acquired in jiffies + * @seq_id: Rx TS/skb sequence ID + */ +struct ixgbe_rx_phy_ts_skb_e610 { + struct list_head list; + union { + u64 ns; + struct sk_buff *skb; + }; + unsigned long acquired; + u16 seq_id; +}; + +struct ixgbe_ptp_e600 { + bool ptp_by_phy_ena : 1; + bool vlan_ena : 1; + atomic_t vlan_change; + atomic_t reinit_phy_tod; + u16 ptp_seq_id; + u16 max_drift_threshold; + struct ptp_pin_desc pin_config[1]; + struct list_head rx_tstamps; + spinlock_t rx_tstamps_lock; /* Protects rx_tstamps access. */ +#ifndef HAVE_PTP_CANCEL_WORKER_SYNC + struct kthread_worker *ptp_kworker; + struct kthread_delayed_work ptp_aux_work; +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ +}; +#endif /* HAVE_PTP_1588_CLOCK */ +enum ixgbe_eee_state { + IXGBE_EEE_DISABLED, /* EEE explicitly disabled by user */ + IXGBE_EEE_ENABLED, /* EEE enabled under condition that link + * requirements are met; for E610 it's the + * default state. + */ + IXGBE_EEE_FORCED_DOWN, /* EEE disabled by link conditions, try to + * restore when possible + */ +}; + +/* board specific private data structure */ +struct ixgbe_adapter { +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) +#ifdef HAVE_VLAN_RX_REGISTER + struct vlan_group *vlgrp; /* must be first, see ixgbe_receive_skb */ +#else + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; +#endif +#endif /* NETIF_F_HW_VLAN_TX || NETIF_F_HW_VLAN_CTAG_TX */ + /* OS defined structs */ + struct net_device *netdev; + struct bpf_prog *xdp_prog; + struct pci_dev *pdev; + + DECLARE_BITMAP(state, __IXGBE_STATE_T_NUM); + enum ixgbe_eee_state eee_state; + /* Some features need tri-state capability, + * thus the additional *_CAPABLE flags. + */ + u32 flags; +#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 0) +#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1) +#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 2) +#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 3) +#ifndef IXGBE_NO_LLI +#define IXGBE_FLAG_LLI_PUSH (u32)(1 << 4) +#endif + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) +#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 6) +#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 7) +#define IXGBE_FLAG_DCA_ENABLED_DATA (u32)(1 << 8) +#else +#define IXGBE_FLAG_DCA_ENABLED (u32)0 +#define IXGBE_FLAG_DCA_CAPABLE (u32)0 +#define IXGBE_FLAG_DCA_ENABLED_DATA (u32)0 +#endif +#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 9) +#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 10) +#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 11) +#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 12) +#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 13) +#define IXGBE_FLAG_NEED_LINK_CONFIG (u32)(1 << 14) +#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 15) +#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 16) +#if IS_ENABLED(CONFIG_FCOE) +#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 17) +#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 18) +#endif /* CONFIG_FCOE */ +#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 19) +#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 20) +#define IXGBE_FLAG_SRIOV_REPLICATION_ENABLE (u32)(1 << 21) +#define IXGBE_FLAG_SRIOV_L2SWITCH_ENABLE (u32)(1 << 22) +#define IXGBE_FLAG_SRIOV_VEPA_BRIDGE_MODE (u32)(1 << 23) +#define IXGBE_FLAG_RX_HWTSTAMP_ENABLED (u32)(1 << 24) +#define IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE (u32)(1 << 25) +#define IXGBE_FLAG_VXLAN_OFFLOAD_ENABLE (u32)(1 << 26) +#define IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER (u32)(1 << 27) +#define IXGBE_FLAG_MDD_ENABLED (u32)(1 << 29) +#define IXGBE_FLAG_DCB_CAPABLE (u32)(1 << 30) +#define IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE BIT(31) + +/* preset defaults */ +#define IXGBE_FLAGS_82598_INIT (IXGBE_FLAG_MSI_CAPABLE | \ + IXGBE_FLAG_MSIX_CAPABLE | \ + IXGBE_FLAG_MQ_CAPABLE) + +#define IXGBE_FLAGS_82599_INIT (IXGBE_FLAGS_82598_INIT | \ + IXGBE_FLAG_SRIOV_CAPABLE) + +#define IXGBE_FLAGS_X540_INIT IXGBE_FLAGS_82599_INIT + +#define IXGBE_FLAGS_X550_INIT (IXGBE_FLAGS_82599_INIT | \ + IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE) + + u32 flags2; +#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1 << 0) +#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1) +#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 3) +#define IXGBE_FLAG2_TEMP_SENSOR_EVENT (u32)(1 << 4) +#define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 5) +#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 6) +#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 8) +#define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 9) +#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 10) +#define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11) +#define IXGBE_FLAG2_FW_ASYNC_EVENT BIT(12) +#define IXGBE_FLAG2_MOD_POWER_UNSUPPORTED BIT(13) +#define IXGBE_FLAG2_EEE_CAPABLE (u32)(1 << 14) +#define IXGBE_FLAG2_UDP_TUN_REREG_NEEDED (u32)(1 << 16) +#define IXGBE_FLAG2_PHY_INTERRUPT (u32)(1 << 17) +#define IXGBE_FLAG2_VLAN_PROMISC (u32)(1 << 18) +#define IXGBE_FLAG2_RX_LEGACY (u32)(1 << 19) +#define IXGBE_FLAG2_AUTO_DISABLE_VF BIT(20) +#define IXGBE_FLAG2_PHY_FW_LOAD_FAILED BIT(24) +#define IXGBE_FLAG2_NO_MEDIA BIT(25) +#define IXGBE_FLAG2_FWLOG_CAPABLE BIT(26) + + /* Tx fast path data */ + int num_tx_queues; + u16 tx_itr_setting; + u16 tx_work_limit; + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) + __be16 vxlan_port; +#endif /* HAVE_UDP_ENC_RX_OFFLAD || HAVE_VXLAN_RX_OFFLOAD */ +#ifdef HAVE_UDP_ENC_RX_OFFLOAD + __be16 geneve_port; +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ + + /* Rx fast path data */ + int num_rx_queues; + u16 rx_itr_setting; + + /* XDP */ + int num_xdp_queues; + struct ixgbe_ring *xdp_ring[IXGBE_MAX_XDP_QS]; + unsigned long *af_xdp_zc_qps; /* tracks AF_XDP ZC enabled rings */ + + /* TX */ + struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp; + + u64 restart_queue; + u64 lsc_int; + u32 tx_timeout_count; + + /* RX */ + struct ixgbe_ring *rx_ring[MAX_RX_QUEUES]; + int num_rx_pools; /* does not include pools assigned to VFs */ + int num_rx_queues_per_pool; + u64 hw_csum_rx_error; + u64 hw_rx_no_dma_resources; + u64 rsc_total_count; + u64 rsc_total_flush; + u64 non_eop_descs; + u32 alloc_rx_page; + u32 alloc_rx_page_failed; + u32 alloc_rx_buff_failed; + + struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; + +#ifdef HAVE_DCBNL_IEEE + struct ieee_pfc *ixgbe_ieee_pfc; + struct ieee_ets *ixgbe_ieee_ets; +#endif + struct ixgbe_dcb_config dcb_cfg; + struct ixgbe_dcb_config temp_dcb_cfg; + u8 dcb_set_bitmap; + u8 dcbx_cap; +#ifndef HAVE_MQPRIO + u8 dcb_tc; +#endif + enum ixgbe_fc_mode last_lfc_mode; + + int num_q_vectors; /* current number of q_vectors for device */ + int max_q_vectors; /* upper limit of q_vectors for device */ + struct ixgbe_ring_feature ring_feature[RING_F_ARRAY_SIZE]; + struct msix_entry *msix_entries; + +#ifndef HAVE_NETDEV_STATS_IN_NETDEV + struct net_device_stats net_stats; +#endif + +#ifdef ETHTOOL_TEST + u32 test_icr; + struct ixgbe_ring test_tx_ring; + struct ixgbe_ring test_rx_ring; +#endif + + /* structs defined in ixgbe_hw.h */ + struct ixgbe_hw hw; + u16 msg_enable; + struct ixgbe_hw_stats stats; +#ifndef IXGBE_NO_LLI + u32 lli_port; + u32 lli_size; + u32 lli_etype; + u32 lli_vlan_pri; +#endif /* IXGBE_NO_LLI */ + + u32 *config_space; + u64 tx_busy; + unsigned int tx_ring_count; + unsigned int xdp_ring_count; + unsigned int rx_ring_count; + + u32 link_speed; + bool link_up; + + bool cloud_mode; + + unsigned long sfp_poll_time; + unsigned long link_check_timeout; + + struct timer_list service_timer; + struct work_struct service_task; + + struct hlist_head fdir_filter_list; + unsigned long fdir_overflow; /* number of times ATR was backed off */ + union ixgbe_atr_input fdir_mask; + int fdir_filter_count; + u32 fdir_pballoc; + u32 atr_sample_rate; + spinlock_t fdir_perfect_lock; + +#if IS_ENABLED(CONFIG_FCOE) + struct ixgbe_fcoe fcoe; +#endif /* CONFIG_FCOE */ + u8 __iomem *io_addr; /* Mainly for iounmap use */ + u32 wol; + + u16 bd_number; + +#ifdef HAVE_BRIDGE_ATTRIBS + u16 bridge_mode; +#endif + + char eeprom_id[32]; + u16 eeprom_cap; + bool netdev_registered; + u32 interrupt_event; +#ifdef HAVE_ETHTOOL_SET_PHYS_ID + u32 led_reg; +#endif + +#ifdef HAVE_PTP_1588_CLOCK + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_caps; + struct work_struct ptp_tx_work; + struct sk_buff *ptp_tx_skb; + struct hwtstamp_config tstamp_config; + unsigned long ptp_tx_start; + unsigned long last_overflow_check; + unsigned long last_rx_ptp_check; + spinlock_t tmreg_lock; + struct cyclecounter hw_cc; + struct timecounter hw_tc; + u32 base_incval; + u32 tx_hwtstamp_timeouts; + u32 tx_hwtstamp_skipped; + u32 rx_hwtstamp_cleared; + void (*ptp_setup_sdp) (struct ixgbe_adapter *); + struct ixgbe_ptp_e600 ptp; +#endif /* HAVE_PTP_1588_CLOCK */ + + DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); + unsigned int num_vfs; + unsigned int max_vfs; + struct vf_data_storage *vfinfo; + int vf_rate_link_speed; + struct vf_macvlans vf_mvs; + struct vf_macvlans *mv_list; +#ifdef CONFIG_PCI_IOV + u32 timer_event_accumulator; + u32 vferr_refcount; +#endif + struct ixgbe_mac_addr *mac_table; + u16 tx_hang_count[IXGBE_MAX_TX_QUEUES]; + u16 lse_mask; +#ifdef IXGBE_SYSFS +#ifdef IXGBE_HWMON +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + struct hwmon_buff *ixgbe_hwmon_buff; +#else + struct hwmon_buff ixgbe_hwmon_buff; +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ +#endif /* IXGBE_HWMON */ +#else /* IXGBE_SYSFS */ +#ifdef IXGBE_PROCFS + struct proc_dir_entry *eth_dir; + struct proc_dir_entry *info_dir; + u64 old_lsc; + struct proc_dir_entry *therm_dir[IXGBE_MAX_SENSORS]; + struct ixgbe_therm_proc_data therm_data[IXGBE_MAX_SENSORS]; +#endif /* IXGBE_PROCFS */ +#endif /* IXGBE_SYSFS */ + +#ifdef HAVE_IXGBE_DEBUG_FS + struct dentry *ixgbe_dbg_adapter_pf; + struct dentry *ixgbe_dbg_adapter_fw; + struct dentry *ixgbe_dbg_adapter_fw_cluster; + void *ixgbe_cluster_blk; + u16 fw_dump_cluster_id; +#endif /*HAVE_IXGBE_DEBUG_FS*/ + u8 default_up; +#ifdef HAVE_TC_SETUP_CLSU32 +#define IXGBE_MAX_LINK_HANDLE 10 + struct ixgbe_jump_table *jump_tables[IXGBE_MAX_LINK_HANDLE]; + unsigned long tables; +#endif /* NETIF_F_HW_TC */ + +/* maximum number of RETA entries among all devices supported by ixgbe + * driver: currently it's x550 device in non-SRIOV mode + */ +#define IXGBE_MAX_RETA_ENTRIES 512 + u8 rss_indir_tbl[IXGBE_MAX_RETA_ENTRIES]; + +#define IXGBE_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ + u32 *rss_key; + +#ifdef HAVE_TX_MQ +#ifndef HAVE_NETDEV_SELECT_QUEUE + unsigned int indices; +#endif +#endif +#ifdef HAVE_AF_XDP_ZC_SUPPORT + /* AF_XDP zero-copy */ +#ifndef HAVE_NETDEV_BPF_XSK_POOL + struct xdp_umem **xsk_pools; + u16 num_xsk_pools_used; + u16 num_xsk_pools; +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ +#endif + struct devlink *devlink; + struct devlink_port devlink_port; +#ifdef HAVE_DEVLINK_REGIONS + struct devlink_region *nvm_region; + struct devlink_region *sram_region; + struct devlink_region *devcaps_region; +#endif /* HAVE_DEVLINK_REGIONS */ + bool fw_emp_reset_disabled; + +}; + +static inline unsigned int ixgbe_determine_xdp_q_idx(unsigned int cpu) +{ + if (static_key_enabled((struct static_key *)&ixgbe_xdp_locking_key)) + return cpu % IXGBE_MAX_XDP_QS; + else + return cpu; +} + +static inline +struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter) +{ + unsigned int index = ixgbe_determine_xdp_q_idx(smp_processor_id()); + + return adapter->xdp_ring[index]; +} + +static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter) +{ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + return IXGBE_MAX_RSS_INDICES; + break; + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + return IXGBE_MAX_RSS_INDICES_X550; + default: + return 0; + break; + } +} + +struct ixgbe_fdir_filter { + struct hlist_node fdir_node; + union ixgbe_atr_input filter; + u16 sw_idx; + u64 action; +}; + +struct ixgbe_cb { +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + union { /* Union defining head/tail partner */ + struct sk_buff *head; + struct sk_buff *tail; + }; +#endif + dma_addr_t dma; +#ifdef HAVE_VLAN_RX_REGISTER + u16 vid; /* VLAN tag */ +#endif + u16 append_cnt; /* number of skb's appended */ +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + bool page_released; +#endif +}; +#define IXGBE_CB(skb) ((struct ixgbe_cb *)(skb)->cb) + +#ifdef IXGBE_SYSFS +void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter); +int ixgbe_sysfs_init(struct ixgbe_adapter *adapter); +#endif /* IXGBE_SYSFS */ +#ifdef IXGBE_PROCFS +void ixgbe_procfs_exit(struct ixgbe_adapter *adapter); +int ixgbe_procfs_init(struct ixgbe_adapter *adapter); +int ixgbe_procfs_topdir_init(void); +void ixgbe_procfs_topdir_exit(void); +#endif /* IXGBE_PROCFS */ + +extern struct dcbnl_rtnl_ops ixgbe_dcbnl_ops; +int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max); + +u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index); + +/* needed by ixgbe_main.c */ +int ixgbe_validate_mac_addr(u8 *mc_addr); +void ixgbe_check_options(struct ixgbe_adapter *adapter); +void ixgbe_assign_netdev_ops(struct net_device *netdev); + +/* needed by ixgbe_ethtool.c */ +#ifdef HAVE_NON_CONST_PCI_DRIVER_NAME +extern char ixgbe_driver_name[]; +#else +extern const char ixgbe_driver_name[]; +#endif +extern const char ixgbe_driver_version[]; + +int ixgbe_open(struct net_device *netdev); +int ixgbe_close(struct net_device *netdev); +void ixgbe_up(struct ixgbe_adapter *adapter); +void ixgbe_down(struct ixgbe_adapter *adapter); +void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); +void ixgbe_reset(struct ixgbe_adapter *adapter); +void ixgbe_set_ethtool_ops(struct net_device *netdev); +int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +int ixgbe_setup_tx_resources(struct ixgbe_ring *); +void ixgbe_free_rx_resources(struct ixgbe_ring *); +void ixgbe_free_tx_resources(struct ixgbe_ring *); +void ixgbe_configure_rx_ring(struct ixgbe_adapter *, + struct ixgbe_ring *); +void ixgbe_configure_tx_ring(struct ixgbe_adapter *, + struct ixgbe_ring *); +void ixgbe_update_stats(struct ixgbe_adapter *adapter); +int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); +void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter); +void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter); +void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); +bool ixgbe_is_ixgbe(struct pci_dev *pcidev); +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, + struct ixgbe_adapter *, + struct ixgbe_ring *); +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, + struct ixgbe_tx_buffer *); +void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); +void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *); +void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *); +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) +void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *, u32); +#endif +int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ixgbe_fdir_filter *input, + u16 sw_idx); +void ixgbe_set_rx_mode(struct net_device *netdev); +int ixgbe_write_mc_addr_list(struct net_device *netdev); +int ixgbe_setup_tc(struct net_device *dev, u8 tc); +void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); +void ixgbe_do_reset(struct net_device *netdev); +void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector); +int ixgbe_poll(struct napi_struct *napi, int budget); +void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter); +void ixgbe_disable_tx_queue(struct ixgbe_adapter *adapter); +void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter); +void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter); +#ifdef ETHTOOL_OPS_COMPAT +int ethtool_ioctl(struct ifreq *ifr); +#endif +#if IS_ENABLED(CONFIG_FCOE) +void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); +int ixgbe_fso(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, + u8 *hdr_len); +int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb); +int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); +#ifdef HAVE_NETDEV_OPS_FCOE_DDP_TARGET +int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); +#endif /* HAVE_NETDEV_OPS_FCOE_DDP_TARGET */ +int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); +int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter); +void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter); +#ifdef HAVE_NETDEV_OPS_FCOE_ENABLE +int ixgbe_fcoe_enable(struct net_device *netdev); +int ixgbe_fcoe_disable(struct net_device *netdev); +#else +int ixgbe_fcoe_ddp_enable(struct ixgbe_adapter *adapter); +void ixgbe_fcoe_ddp_disable(struct ixgbe_adapter *adapter); +#endif /* HAVE_NETDEV_OPS_FCOE_ENABLE */ +#if IS_ENABLED(CONFIG_DCB) +#ifdef HAVE_DCBNL_OPS_GETAPP +u8 ixgbe_fcoe_getapp(struct net_device *netdev); +#endif /* HAVE_DCBNL_OPS_GETAPP */ +u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up); +#endif /* CONFIG_DCB */ +u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter); +#ifdef HAVE_NETDEV_OPS_FCOE_GETWWN +int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); +#endif +#endif /* CONFIG_FCOE */ + +#ifdef HAVE_IXGBE_DEBUG_FS +void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter); +void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter); +void ixgbe_dbg_init(void); +void ixgbe_dbg_exit(void); +#endif /* HAVE_IXGBE_DEBUG_FS */ + +static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) +{ + return netdev_get_tx_queue(ring->netdev, ring->queue_index); +} + +#if IS_ENABLED(CONFIG_DCB) +#ifdef HAVE_DCBNL_IEEE +s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame); +#endif /* HAVE_DCBNL_IEEE */ +#endif /* CONFIG_DCB */ + +int ixgbe_pf_fwlog_update_modules(struct ixgbe_adapter *adapter, u8 log_level, + unsigned long events); +bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, + u16 subdevice_id); +void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter); +int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, + const u8 *addr, u16 queue); +int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, + const u8 *addr, u16 queue); +int ixgbe_available_rars(struct ixgbe_adapter *adapter, u16 pool); +void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid); +bool ixgbe_check_link_for_eee_e610(struct ixgbe_adapter *adapter, + bool print_msg); +#ifndef HAVE_VLAN_RX_REGISTER +void ixgbe_vlan_mode(struct net_device *, u32); +#else +#ifdef CONFIG_PCI_IOV +int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan); +#endif +#endif +#ifdef HAVE_PTP_1588_CLOCK +#ifdef IXGBE_SYSFS +#endif /* IXGBE_SYSFS */ +int ixgbe_ptp_fw_intr_e600(struct ixgbe_adapter *adapter); +void ixgbe_ptp_rx_phytstamp_e600(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb, unsigned int ptp_class); +void ixgbe_ptp_init(struct ixgbe_adapter *adapter); +void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); +void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter); +void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); +void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); +void ixgbe_ptp_tx_hang(struct ixgbe_adapter *adapter); +void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work); +void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter); +static inline void ixgbe_ptp_eicr_timesync(struct ixgbe_adapter *adapter) { + int err = -EINTR; + + if (adapter->ptp.ptp_by_phy_ena) + err = ixgbe_ptp_fw_intr_e600(adapter); + + if (err == -EINTR) + ixgbe_ptp_check_pps_event(adapter); + else if (err) + e_dbg(link, "PTP by PHY Tx TS err=%d\n", err); +} + +void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb); +void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb); +static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_TSIP))) { + struct ixgbe_adapter *adapter = rx_ring->q_vector->adapter; + unsigned int ptp_class = PTP_CLASS_NONE; + + if (unlikely(adapter->ptp.ptp_by_phy_ena)) + ptp_class = ptp_classify_raw(skb); + + if (unlikely(ptp_class != PTP_CLASS_NONE)) { + ixgbe_ptp_rx_phytstamp_e600(rx_ring->q_vector, skb, + ptp_class); + return; + } + + ixgbe_ptp_rx_pktstamp(rx_ring->q_vector, skb); + return; + } + + if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) + return; + + ixgbe_ptp_rx_rgtstamp(rx_ring->q_vector, skb); + + /* Update the last_rx_timestamp timer in order to enable watchdog check + * for error case of latched timestamp on a dropped packet. + */ + rx_ring->last_rx_timestamp = jiffies; +} + +int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); +int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); +void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); +void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); +#endif /* HAVE_PTP_1588_CLOCK */ +#ifdef CONFIG_PCI_IOV +void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter); +#endif +u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter); +void ixgbe_store_key(struct ixgbe_adapter *adapter); +void ixgbe_store_reta(struct ixgbe_adapter *adapter); + +void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); + +bool ixgbe_fwlog_ring_full(struct ixgbe_fwlog_ring *rings); +bool ixgbe_fwlog_ring_empty(struct ixgbe_fwlog_ring *rings); +void ixgbe_fwlog_ring_increment(u16 *item, u16 size); +void ixgbe_fwlog_realloc_rings(struct ixgbe_hw *hw, int ring_size); +s32 ixgbe_fwlog_init(struct ixgbe_hw *hw); +int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter); + +#endif /* _IXGBE_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.c new file mode 100644 index 0000000000..3aa937cf9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.c @@ -0,0 +1,1379 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_82598.h" +#include "ixgbe_api.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" + +#define IXGBE_82598_MAX_TX_QUEUES 32 +#define IXGBE_82598_MAX_RX_QUEUES 64 +#define IXGBE_82598_RAR_ENTRIES 16 +#define IXGBE_82598_MC_TBL_SIZE 128 +#define IXGBE_82598_VFT_TBL_SIZE 128 +#define IXGBE_82598_RX_PB_SIZE 512 + +STATIC s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); +STATIC enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); +STATIC s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete); +STATIC s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *link_up, + bool link_up_wait_to_complete); +STATIC s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +STATIC s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +STATIC s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); +STATIC s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +STATIC s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw); +STATIC void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb, + u32 headroom, int strategy); +STATIC s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data); +/** + * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout + * @hw: pointer to the HW structure + * + * The defaults for 82598 should be in the range of 50us to 50ms, + * however the hardware default for these parts is 500us to 1ms which is less + * than the 10ms recommended by the pci-e spec. To address this we need to + * increase the value to either 10ms to 250ms for capability version 1 config, + * or 16ms to 55ms for version 2. + **/ +void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw) +{ + u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR); + u16 pcie_devctl2; + + /* only take action if timeout value is defaulted to 0 */ + if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK) + goto out; + + /* + * if capababilities version is type 1 we can write the + * timeout of 10ms to 250ms through the GCR register + */ + if (!(gcr & IXGBE_GCR_CAP_VER2)) { + gcr |= IXGBE_GCR_CMPL_TMOUT_10ms; + goto out; + } + + /* + * for version 2 capabilities we need to write the config space + * directly in order to set the completion timeout value for + * 16ms to 55ms + */ + pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2); + pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms; + IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2); +out: + /* disable completion timeout resend */ + gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND; + IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr); +} + +/** + * ixgbe_init_ops_82598 - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type for 82598. + * Does not touch the hardware. + **/ +s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_82598"); + + ret_val = ixgbe_init_phy_ops_generic(hw); + ret_val = ixgbe_init_ops_generic(hw); + + /* PHY */ + phy->ops.init = ixgbe_init_phy_ops_82598; + + /* MAC */ + mac->ops.start_hw = ixgbe_start_hw_82598; + mac->ops.reset_hw = ixgbe_reset_hw_82598; + mac->ops.get_media_type = ixgbe_get_media_type_82598; + mac->ops.get_supported_physical_layer = + ixgbe_get_supported_physical_layer_82598; + mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82598; + mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82598; + mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie_82598; + mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82598; + + /* RAR, Multicast, VLAN */ + mac->ops.set_vmdq = ixgbe_set_vmdq_82598; + mac->ops.clear_vmdq = ixgbe_clear_vmdq_82598; + mac->ops.set_vfta = ixgbe_set_vfta_82598; + mac->ops.set_vlvf = NULL; + mac->ops.clear_vfta = ixgbe_clear_vfta_82598; + + /* Flow Control */ + mac->ops.fc_enable = ixgbe_fc_enable_82598; + + mac->mcft_size = IXGBE_82598_MC_TBL_SIZE; + mac->vft_size = IXGBE_82598_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES; + mac->rx_pb_size = IXGBE_82598_RX_PB_SIZE; + mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); + + /* SFP+ Module */ + phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_82598; + phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_82598; + + /* Link */ + mac->ops.check_link = ixgbe_check_mac_link_82598; + mac->ops.setup_link = ixgbe_setup_mac_link_82598; + mac->ops.flap_tx_laser = NULL; + mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82598; + mac->ops.setup_rxpba = ixgbe_set_rxpba_82598; + + /* Manageability interface */ + mac->ops.set_fw_drv_ver = NULL; + + mac->ops.get_rtrup2tc = NULL; + + return ret_val; +} + +/** + * ixgbe_init_phy_ops_82598 - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + * + **/ +s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val = IXGBE_SUCCESS; + u16 list_offset, data_offset; + + DEBUGFUNC("ixgbe_init_phy_ops_82598"); + + /* Identify the PHY */ + phy->ops.identify(hw); + + /* Overwrite the link function pointers if copper PHY */ + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { + mac->ops.setup_link = ixgbe_setup_copper_link_82598; + mac->ops.get_link_capabilities = + ixgbe_get_copper_link_capabilities_generic; + } + + switch (hw->phy.type) { + case ixgbe_phy_tn: + phy->ops.setup_link = ixgbe_setup_phy_link_tnx; + phy->ops.check_link = ixgbe_check_phy_link_tnx; + phy->ops.get_firmware_version = + ixgbe_get_phy_firmware_version_tnx; + break; + case ixgbe_phy_nl: + phy->ops.reset = ixgbe_reset_phy_nl; + + /* Call SFP+ identify routine to get the SFP+ module type */ + ret_val = phy->ops.identify_sfp(hw); + if (ret_val != IXGBE_SUCCESS) + goto out; + else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) { + ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + + /* Check to see if SFP+ module is supported */ + ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, + &list_offset, + &data_offset); + if (ret_val != IXGBE_SUCCESS) { + ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + break; + default: + break; + } + +out: + return ret_val; +} + +/** + * ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware using the generic start_hw function. + * Disables relaxed ordering Then set pcie completion timeout + * + **/ +s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) +{ + u32 regval; + u32 i; + s32 ret_val = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_start_hw_82598"); + + ret_val = ixgbe_start_hw_generic(hw); + if (ret_val) + return ret_val; + + /* Disable relaxed ordering */ + for (i = 0; ((i < hw->mac.max_tx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); + regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); + } + + for (i = 0; ((i < hw->mac.max_rx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | + IXGBE_DCA_RXCTRL_HEAD_WRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + + /* set the completion timeout for interface */ + ixgbe_set_pcie_completion_timeout(hw); + + return ret_val; +} + +/** + * ixgbe_get_link_capabilities_82598 - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: boolean auto-negotiation value + * + * Determines the link capabilities by reading the AUTOC register. + **/ +STATIC s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_SUCCESS; + u32 autoc = 0; + + DEBUGFUNC("ixgbe_get_link_capabilities_82598"); + + /* + * Determine link capabilities based on the stored value of AUTOC, + * which represents EEPROM defaults. If AUTOC value has not been + * stored, use the current register value. + */ + if (hw->mac.orig_link_settings_stored) + autoc = hw->mac.orig_autoc; + else + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = false; + break; + + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + *speed = IXGBE_LINK_SPEED_10GB_FULL; + *autoneg = false; + break; + + case IXGBE_AUTOC_LMS_1G_AN: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + break; + + case IXGBE_AUTOC_LMS_KX4_AN: + case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (autoc & IXGBE_AUTOC_KX_SUPP) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + break; + + default: + status = IXGBE_ERR_LINK_SETUP; + break; + } + + return status; +} + +/** + * ixgbe_get_media_type_82598 - Determines media type + * @hw: pointer to hardware structure + * + * Returns the media type (fiber, copper, backplane) + **/ +STATIC enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) +{ + enum ixgbe_media_type media_type; + + DEBUGFUNC("ixgbe_get_media_type_82598"); + + /* Detect if there is a copper PHY attached. */ + switch (hw->phy.type) { + case ixgbe_phy_cu_unknown: + case ixgbe_phy_tn: + media_type = ixgbe_media_type_copper; + goto out; + default: + break; + } + + /* Media type for I82598 is based on device ID */ + switch (hw->device_id) { + case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82598_BX: + /* Default device ID is mezzanine card KX/KX4 */ + media_type = ixgbe_media_type_backplane; + break; + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + case IXGBE_DEV_ID_82598_DA_DUAL_PORT: + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: + case IXGBE_DEV_ID_82598EB_XF_LR: + case IXGBE_DEV_ID_82598EB_SFP_LOM: + media_type = ixgbe_media_type_fiber; + break; + case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + media_type = ixgbe_media_type_cx4; + break; + case IXGBE_DEV_ID_82598AT: + case IXGBE_DEV_ID_82598AT2: + media_type = ixgbe_media_type_copper; + break; + default: + media_type = ixgbe_media_type_unknown; + break; + } +out: + return media_type; +} + +/** + * ixgbe_fc_enable_82598 - Enable flow control + * @hw: pointer to hardware structure + * + * Enable flow control according to the current settings. + **/ +s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + u32 fctrl_reg; + u32 rmcs_reg; + u32 reg; + u32 fcrtl, fcrth; + u32 link_speed = 0; + int i; + bool link_up; + + DEBUGFUNC("ixgbe_fc_enable_82598"); + + /* Validate the water mark configuration */ + if (!hw->fc.pause_time) { + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* Low water mark of zero causes XOFF floods */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && + hw->fc.high_water[i]) { + if (!hw->fc.low_water[i] || + hw->fc.low_water[i] >= hw->fc.high_water[i]) { + hw_dbg(hw, "Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + } + } + + /* + * On 82598 having Rx FC on causes resets while doing 1G + * so if it's on turn it off once we know link_speed. For + * more details see 82598 Specification update. + */ + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) { + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + hw->fc.requested_mode = ixgbe_fc_tx_pause; + break; + case ixgbe_fc_rx_pause: + hw->fc.requested_mode = ixgbe_fc_none; + break; + default: + /* no change */ + break; + } + } + + /* Negotiate the fc mode to use */ + ixgbe_fc_autoneg(hw); + + /* Disable any previous flow control settings */ + fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); + fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); + + rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); + + /* + * The possible values of fc.current_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.current_mode) { + case ixgbe_fc_none: + /* + * Flow control is disabled by software override or autoneg. + * The code below will actually disable it in the HW. + */ + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + fctrl_reg |= IXGBE_FCTRL_RFCE; + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; + break; + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + fctrl_reg |= IXGBE_FCTRL_RFCE; + rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; + break; + default: + hw_dbg(hw, "Flow control param set incorrectly\n"); + ret_val = IXGBE_ERR_CONFIG; + goto out; + break; + } + + /* Set 802.3x based flow control settings. */ + fctrl_reg |= IXGBE_FCTRL_DPF; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); + IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); + + /* Set up and enable Rx high/low water mark thresholds, enable XON. */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && + hw->fc.high_water[i]) { + fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; + fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth); + } else { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); + } + + } + + /* Configure pause time (2 TCs per register) */ + reg = hw->fc.pause_time * 0x00010001; + for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + +out: + return ret_val; +} + +/** + * ixgbe_start_mac_link_82598 - Configures MAC link settings + * @hw: pointer to hardware structure + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Configures link settings based on values in the ixgbe_hw struct. + * Restarts the link. Performs autonegotiation if needed. + **/ +STATIC s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete) +{ + u32 autoc_reg; + u32 links_reg; + u32 i; + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_start_mac_link_82598"); + + /* Restart link */ + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + + /* Only poll for autoneg to complete if specified to do so */ + if (autoneg_wait_to_complete) { + if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_AN || + (autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { + links_reg = 0; /* Just in case Autoneg time = 0 */ + for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + if (links_reg & IXGBE_LINKS_KX_AN_COMP) + break; + msec_delay(100); + } + if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { + status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; + hw_dbg(hw, "Autonegotiation did not complete.\n"); + } + } + } + + /* Add delay to filter out noises during initial link setup */ + msec_delay(50); + + return status; +} + +/** + * ixgbe_validate_link_ready - Function looks for phy link + * @hw: pointer to hardware structure + * + * Function indicates success when phy link is available. If phy is not ready + * within 5 seconds of MAC indicating link, the function returns error. + **/ +STATIC s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw) +{ + u32 timeout; + u16 an_reg; + + if (hw->device_id != IXGBE_DEV_ID_82598AT2) + return IXGBE_SUCCESS; + + for (timeout = 0; + timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg); + + if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) && + (an_reg & IXGBE_MII_AUTONEG_LINK_UP)) + break; + + msec_delay(100); + } + + if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) { + hw_dbg(hw, "Link was indicated but link is down\n"); + return IXGBE_ERR_LINK_SETUP; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_check_mac_link_82598 - Get link/speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true is link is up, false otherwise + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Reads the links register to determine if link is up and the current speed + **/ +STATIC s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *link_up, + bool link_up_wait_to_complete) +{ + u32 links_reg; + u32 i; + u16 link_reg, adapt_comp_reg; + + DEBUGFUNC("ixgbe_check_mac_link_82598"); + + /* + * SERDES PHY requires us to read link status from undocumented + * register 0xC79F. Bit 0 set indicates link is up/ready; clear + * indicates link down. OxC00C is read to check that the XAUI lanes + * are active. Bit 0 clear indicates active; set indicates inactive. + */ + if (hw->phy.type == ixgbe_phy_nl) { + hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); + hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); + hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, + &adapt_comp_reg); + if (link_up_wait_to_complete) { + for (i = 0; i < hw->mac.max_link_up_time; i++) { + if ((link_reg & 1) && + ((adapt_comp_reg & 1) == 0)) { + *link_up = true; + break; + } else { + *link_up = false; + } + msec_delay(100); + hw->phy.ops.read_reg(hw, 0xC79F, + IXGBE_TWINAX_DEV, + &link_reg); + hw->phy.ops.read_reg(hw, 0xC00C, + IXGBE_TWINAX_DEV, + &adapt_comp_reg); + } + } else { + if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0)) + *link_up = true; + else + *link_up = false; + } + + if (*link_up == false) + goto out; + } + + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + if (link_up_wait_to_complete) { + for (i = 0; i < hw->mac.max_link_up_time; i++) { + if (links_reg & IXGBE_LINKS_UP) { + *link_up = true; + break; + } else { + *link_up = false; + } + msec_delay(100); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + } + } else { + if (links_reg & IXGBE_LINKS_UP) + *link_up = true; + else + *link_up = false; + } + + if (links_reg & IXGBE_LINKS_SPEED) + *speed = IXGBE_LINK_SPEED_10GB_FULL; + else + *speed = IXGBE_LINK_SPEED_1GB_FULL; + + if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == true) && + (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS)) + *link_up = false; + +out: + return IXGBE_SUCCESS; +} + +/** + * ixgbe_setup_mac_link_82598 - Set MAC link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Set the link speed in the AUTOC register and restarts link. + **/ +STATIC s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + bool autoneg = false; + s32 status = IXGBE_SUCCESS; + ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; + u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 autoc = curr_autoc; + u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; + + DEBUGFUNC("ixgbe_setup_mac_link_82598"); + + /* Check to see if speed passed in is supported. */ + ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg); + speed &= link_capabilities; + + if (speed == IXGBE_LINK_SPEED_UNKNOWN) + status = IXGBE_ERR_LINK_SETUP; + + /* Set KX4/KX support according to speed requested */ + else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || + link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { + autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK; + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + autoc |= IXGBE_AUTOC_KX4_SUPP; + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + autoc |= IXGBE_AUTOC_KX_SUPP; + if (autoc != curr_autoc) + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); + } + + if (status == IXGBE_SUCCESS) { + /* + * Setup and restart the link based on the new values in + * ixgbe_hw This will write the AUTOC register based on the new + * stored values + */ + status = ixgbe_start_mac_link_82598(hw, + autoneg_wait_to_complete); + } + + return status; +} + + +/** + * ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true if waiting is needed to complete + * + * Sets the link speed in the AUTOC register in the MAC and restarts link. + **/ +STATIC s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 status; + + DEBUGFUNC("ixgbe_setup_copper_link_82598"); + + /* Setup the PHY according to input speed */ + status = hw->phy.ops.setup_link_speed(hw, speed, + autoneg_wait_to_complete); + /* Set up MAC */ + ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); + + return status; +} + +/** + * ixgbe_reset_hw_82598 - Performs hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks and + * clears all interrupts, performing a PHY reset, and performing a link (MAC) + * reset. + **/ +STATIC s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + s32 phy_status = IXGBE_SUCCESS; + u32 ctrl; + u32 gheccr; + u32 i; + u32 autoc; + u8 analog_val; + + DEBUGFUNC("ixgbe_reset_hw_82598"); + + /* Call adapter stop to disable tx/rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); + if (status != IXGBE_SUCCESS) + goto reset_hw_out; + + /* + * Power up the Atlas Tx lanes if they are currently powered down. + * Atlas Tx lanes are powered down for MAC loopback tests, but + * they are not automatically restored on reset. + */ + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val); + if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) { + /* Enable Tx Atlas so packets can be transmitted again */ + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, + &analog_val); + analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, + analog_val); + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, + &analog_val); + analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, + analog_val); + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, + &analog_val); + analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, + analog_val); + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, + &analog_val); + analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, + analog_val); + } + + /* Reset PHY */ + if (hw->phy.reset_disable == false) { + /* PHY ops must be identified and initialized prior to reset */ + + /* Init PHY and function pointers, perform SFP setup */ + phy_status = hw->phy.ops.init(hw); + if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) + goto mac_reset_top; + + hw->phy.ops.reset(hw); + } + +mac_reset_top: + /* + * Issue global reset to the MAC. This needs to be a SW reset. + * If link reset is used, it might reset the MAC when mng is using it + */ + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST; + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); + + /* Poll for reset bit to self-clear indicating reset is complete */ + for (i = 0; i < 10; i++) { + usec_delay(1); + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST)) + break; + } + if (ctrl & IXGBE_CTRL_RST) { + status = IXGBE_ERR_RESET_FAILED; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + + msec_delay(50); + + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + goto mac_reset_top; + } + + gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); + gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6)); + IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); + + /* + * Store the original AUTOC value if it has not been + * stored off yet. Otherwise restore the stored original + * AUTOC value since the reset operation sets back to deaults. + */ + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + if (hw->mac.orig_link_settings_stored == false) { + hw->mac.orig_autoc = autoc; + hw->mac.orig_link_settings_stored = true; + } else if (autoc != hw->mac.orig_autoc) { + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); + } + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table + */ + hw->mac.ops.init_rx_addrs(hw); + +reset_hw_out: + if (phy_status != IXGBE_SUCCESS) + status = phy_status; + + return status; +} + +/** + * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq set index + **/ +s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_set_vmdq_82598"); + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + rar_high &= ~IXGBE_RAH_VIND_MASK; + rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK); + IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq clear index (not used in 82598, but elsewhere) + **/ +STATIC s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + UNREFERENCED_1PARAMETER(vmdq); + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + if (rar_high & IXGBE_RAH_VIND_MASK) { + rar_high &= ~IXGBE_RAH_VIND_MASK; + IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_vfta_82598 - Set VLAN filter table + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VFTA + * @vlan_on: boolean flag to turn on/off VLAN in VFTA + * @vlvf_bypass: boolean flag - unused + * + * Turn on/off specified VLAN in the VLAN filter table. + **/ +s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, bool vlvf_bypass) +{ + u32 regindex; + u32 bitindex; + u32 bits; + u32 vftabyte; + + UNREFERENCED_1PARAMETER(vlvf_bypass); + + DEBUGFUNC("ixgbe_set_vfta_82598"); + + if (vlan > 4095) + return IXGBE_ERR_PARAM; + + /* Determine 32-bit word position in array */ + regindex = (vlan >> 5) & 0x7F; /* upper seven bits */ + + /* Determine the location of the (VMD) queue index */ + vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */ + bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */ + + /* Set the nibble for VMD queue index */ + bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex)); + bits &= (~(0x0F << bitindex)); + bits |= (vind << bitindex); + IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits); + + /* Determine the location of the bit for this VLAN id */ + bitindex = vlan & 0x1F; /* lower five bits */ + + bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); + if (vlan_on) + /* Turn on this VLAN id */ + bits |= (1 << bitindex); + else + /* Turn off this VLAN id */ + bits &= ~(1 << bitindex); + IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_vfta_82598 - Clear VLAN filter table + * @hw: pointer to hardware structure + * + * Clears the VLAN filer table, and the VMDq index associated with the filter + **/ +STATIC s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) +{ + u32 offset; + u32 vlanbyte; + + DEBUGFUNC("ixgbe_clear_vfta_82598"); + + for (offset = 0; offset < hw->mac.vft_size; offset++) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); + + for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) + for (offset = 0; offset < hw->mac.vft_size; offset++) + IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), + 0); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register + * @hw: pointer to hardware structure + * @reg: analog register to read + * @val: read value + * + * Performs read operation to Atlas analog register specified. + **/ +s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val) +{ + u32 atlas_ctl; + + DEBUGFUNC("ixgbe_read_analog_reg8_82598"); + + IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, + IXGBE_ATLASCTL_WRITE_CMD | (reg << 8)); + IXGBE_WRITE_FLUSH(hw); + usec_delay(10); + atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL); + *val = (u8)atlas_ctl; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register + * @hw: pointer to hardware structure + * @reg: atlas register to write + * @val: value to write + * + * Performs write operation to Atlas analog register specified. + **/ +s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) +{ + u32 atlas_ctl; + + DEBUGFUNC("ixgbe_write_analog_reg8_82598"); + + atlas_ctl = (reg << 8) | val; + IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl); + IXGBE_WRITE_FLUSH(hw); + usec_delay(10); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface. + * @hw: pointer to hardware structure + * @dev_addr: address to read from + * @byte_offset: byte offset to read from dev_addr + * @eeprom_data: value read + * + * Performs 8 byte read operation to SFP module's EEPROM over I2C interface. + **/ +STATIC s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr, + u8 byte_offset, u8 *eeprom_data) +{ + s32 status = IXGBE_SUCCESS; + u16 sfp_addr = 0; + u16 sfp_data = 0; + u16 sfp_stat = 0; + u16 gssr; + u32 i; + + DEBUGFUNC("ixgbe_read_i2c_phy_82598"); + + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) + gssr = IXGBE_GSSR_PHY1_SM; + else + gssr = IXGBE_GSSR_PHY0_SM; + + if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS) + return IXGBE_ERR_SWFW_SYNC; + + if (hw->phy.type == ixgbe_phy_nl) { + /* + * NetLogic phy SDA/SCL registers are at addresses 0xC30A to + * 0xC30D. These registers are used to talk to the SFP+ + * module's EEPROM through the SDA/SCL (I2C) interface. + */ + sfp_addr = (dev_addr << 8) + byte_offset; + sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK); + hw->phy.ops.write_reg_mdi(hw, + IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + sfp_addr); + + /* Poll status */ + for (i = 0; i < 100; i++) { + hw->phy.ops.read_reg_mdi(hw, + IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &sfp_stat); + sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; + if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) + break; + msec_delay(10); + } + + if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { + hw_dbg(hw, "EEPROM read did not pass.\n"); + status = IXGBE_ERR_SFP_NOT_PRESENT; + goto out; + } + + /* Read data */ + hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data); + + *eeprom_data = (u8)(sfp_data >> 8); + } else { + status = IXGBE_ERR_PHY; + } + +out: + hw->mac.ops.release_swfw_sync(hw, gssr); + return status; +} + +/** + * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface. + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to read + * @eeprom_data: value read + * + * Performs 8 byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data) +{ + return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR, + byte_offset, eeprom_data); +} + +/** + * ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface. + * @hw: pointer to hardware structure + * @byte_offset: byte offset at address 0xA2 + * @sff8472_data: value read + * + * Performs 8 byte read operation to SFP module's SFF-8472 data over I2C + **/ +STATIC s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data) +{ + return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2, + byte_offset, sff8472_data); +} + +/** + * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u64 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) +{ + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; + u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; + u16 ext_ability = 0; + + DEBUGFUNC("ixgbe_get_supported_physical_layer_82598"); + + hw->phy.ops.identify(hw); + + /* Copper PHY must be checked before AUTOC LMS to determine correct + * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ + switch (hw->phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_cu_unknown: + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + goto out; + default: + break; + } + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_AN: + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + if (pma_pmd_1g == IXGBE_AUTOC_1G_KX) + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; + else + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX; + break; + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + else /* XAUI */ + physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + break; + case IXGBE_AUTOC_LMS_KX4_AN: + case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: + if (autoc & IXGBE_AUTOC_KX_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + break; + default: + break; + } + + if (hw->phy.type == ixgbe_phy_nl) { + hw->phy.ops.identify_sfp(hw); + + switch (hw->phy.sfp_type) { + case ixgbe_sfp_type_da_cu: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + break; + case ixgbe_sfp_type_sr: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + break; + case ixgbe_sfp_type_lr: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + break; + default: + physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + break; + } + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_82598_DA_DUAL_PORT: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + break; + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + break; + case IXGBE_DEV_ID_82598EB_XF_LR: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + break; + default: + break; + } + +out: + return physical_layer; +} + +/** + * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple + * port devices. + * @hw: pointer to the HW structure + * + * Calls common function and corrects issue with some single port devices + * that enable LAN1 but not LAN0. + **/ +void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw) +{ + struct ixgbe_bus_info *bus = &hw->bus; + u16 pci_gen = 0; + u16 pci_ctrl2 = 0; + + DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598"); + + ixgbe_set_lan_id_multi_port_pcie(hw); + + /* check if LAN0 is disabled */ + hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen); + if ((pci_gen != 0) && (pci_gen != 0xFFFF)) { + + hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2); + + /* if LAN0 is completely disabled force function to 0 */ + if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) && + !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) && + !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) { + + bus->func = 0; + } + } +} + +/** + * ixgbe_set_rxpba_82598 - Initialize RX packet buffer + * @hw: pointer to hardware structure + * @num_pb: number of packet buffers to allocate + * @headroom: reserve n KB of headroom + * @strategy: packet buffer allocation strategy + **/ +STATIC void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb, + u32 headroom, int strategy) +{ + u32 rxpktsize = IXGBE_RXPBSIZE_64KB; + u8 i = 0; + UNREFERENCED_1PARAMETER(headroom); + + if (!num_pb) + return; + + /* Setup Rx packet buffer sizes */ + switch (strategy) { + case PBA_STRATEGY_WEIGHTED: + /* Setup the first four at 80KB */ + rxpktsize = IXGBE_RXPBSIZE_80KB; + for (; i < 4; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + /* Setup the last four at 48KB...don't re-init i */ + rxpktsize = IXGBE_RXPBSIZE_48KB; + /* Fall Through */ + case PBA_STRATEGY_EQUAL: + default: + /* Divide the remaining Rx packet buffer evenly among the TCs */ + for (; i < IXGBE_MAX_PACKET_BUFFERS; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + break; + } + + /* Setup Tx packet buffer sizes */ + for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB); +} + +/** + * ixgbe_enable_rx_dma_82598 - Enable the Rx DMA unit + * @hw: pointer to hardware structure + * @regval: register value to write to RXCTRL + * + * Enables the Rx DMA unit + **/ +s32 ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, u32 regval) +{ + DEBUGFUNC("ixgbe_enable_rx_dma_82598"); + + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); + + return IXGBE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.h new file mode 100644 index 0000000000..0e66bd3d86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82598.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_82598_H_ +#define _IXGBE_82598_H_ + +u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw); +s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw); +s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw); +s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on, + bool vlvf_bypass); +s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val); +s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data); +u64 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw); +s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw); +void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw); +void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw); +s32 ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, u32 regval); +#endif /* _IXGBE_82598_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.c new file mode 100644 index 0000000000..36e387c9eb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.c @@ -0,0 +1,2537 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_82599.h" +#include "ixgbe_api.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" + +#define IXGBE_82599_MAX_TX_QUEUES 128 +#define IXGBE_82599_MAX_RX_QUEUES 128 +#define IXGBE_82599_RAR_ENTRIES 128 +#define IXGBE_82599_MC_TBL_SIZE 128 +#define IXGBE_82599_VFT_TBL_SIZE 128 +#define IXGBE_82599_RX_PB_SIZE 512 + +STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +STATIC s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); +STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, + u16 offset, u16 *data); +STATIC s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +STATIC s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data); +STATIC s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data); + +void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + + DEBUGFUNC("ixgbe_init_mac_link_ops_82599"); + + /* + * enable the laser control functions for SFP+ fiber + * and MNG not enabled + */ + if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) && + !ixgbe_mng_enabled(hw)) { + mac->ops.disable_tx_laser = + ixgbe_disable_tx_laser_multispeed_fiber; + mac->ops.enable_tx_laser = + ixgbe_enable_tx_laser_multispeed_fiber; + mac->ops.flap_tx_laser = ixgbe_flap_tx_laser_multispeed_fiber; + + } else { + mac->ops.disable_tx_laser = NULL; + mac->ops.enable_tx_laser = NULL; + mac->ops.flap_tx_laser = NULL; + } + + if (hw->phy.multispeed_fiber) { + /* Set up dual speed SFP+ support */ + mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber; + mac->ops.setup_mac_link = ixgbe_setup_mac_link_82599; + mac->ops.set_rate_select_speed = + ixgbe_set_hard_rate_select_speed; + } else { + if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) && + (hw->phy.smart_speed == ixgbe_smart_speed_auto || + hw->phy.smart_speed == ixgbe_smart_speed_on) && + !ixgbe_verify_lesm_fw_enabled_82599(hw)) { + mac->ops.setup_link = ixgbe_setup_mac_link_smartspeed; + } else { + mac->ops.setup_link = ixgbe_setup_mac_link_82599; + } + } +} + +/** + * ixgbe_init_phy_ops_82599 - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + * + **/ +s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val = IXGBE_SUCCESS; + u32 esdp; + + DEBUGFUNC("ixgbe_init_phy_ops_82599"); + + if (hw->device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP) { + /* Store flag indicating I2C bus access control unit. */ + hw->phy.qsfp_shared_i2c_bus = TRUE; + + /* Initialize access to QSFP+ I2C bus */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp |= IXGBE_ESDP_SDP0_DIR; + esdp &= ~IXGBE_ESDP_SDP1_DIR; + esdp &= ~IXGBE_ESDP_SDP0; + esdp &= ~IXGBE_ESDP_SDP0_NATIVE; + esdp &= ~IXGBE_ESDP_SDP1_NATIVE; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + + phy->ops.read_i2c_byte = ixgbe_read_i2c_byte_82599; + phy->ops.write_i2c_byte = ixgbe_write_i2c_byte_82599; + } + /* Identify the PHY or SFP module */ + ret_val = phy->ops.identify(hw); + if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto init_phy_ops_out; + + /* Setup function pointers based on detected SFP module and speeds */ + ixgbe_init_mac_link_ops_82599(hw); + if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) + hw->phy.ops.reset = NULL; + + /* If copper media, overwrite with copper function pointers */ + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { + mac->ops.setup_link = ixgbe_setup_copper_link_82599; + mac->ops.get_link_capabilities = + ixgbe_get_copper_link_capabilities_generic; + } + + /* Set necessary function pointers based on PHY type */ + switch (hw->phy.type) { + case ixgbe_phy_tn: + phy->ops.setup_link = ixgbe_setup_phy_link_tnx; + phy->ops.check_link = ixgbe_check_phy_link_tnx; + phy->ops.get_firmware_version = + ixgbe_get_phy_firmware_version_tnx; + break; + default: + break; + } +init_phy_ops_out: + return ret_val; +} + +s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + u16 list_offset, data_offset, data_value; + + DEBUGFUNC("ixgbe_setup_sfp_modules_82599"); + + if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { + ixgbe_init_mac_link_ops_82599(hw); + + hw->phy.ops.reset = NULL; + + ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset, + &data_offset); + if (ret_val != IXGBE_SUCCESS) + goto setup_sfp_out; + + /* PHY config will finish before releasing the semaphore */ + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (ret_val != IXGBE_SUCCESS) { + ret_val = IXGBE_ERR_SWFW_SYNC; + goto setup_sfp_out; + } + + if (hw->eeprom.ops.read(hw, ++data_offset, &data_value)) + goto setup_sfp_err; + while (data_value != 0xffff) { + IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value); + IXGBE_WRITE_FLUSH(hw); + if (hw->eeprom.ops.read(hw, ++data_offset, &data_value)) + goto setup_sfp_err; + } + + /* Release the semaphore */ + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); + /* Delay obtaining semaphore again to allow FW access + * prot_autoc_write uses the semaphore too. + */ + msec_delay(hw->eeprom.semaphore_delay); + + /* Restart DSP and set SFI mode */ + ret_val = hw->mac.ops.prot_autoc_write(hw, + hw->mac.orig_autoc | IXGBE_AUTOC_LMS_10G_SERIAL, + false); + + if (ret_val) { + hw_dbg(hw, "sfp module setup not complete\n"); + ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; + goto setup_sfp_out; + } + + } + +setup_sfp_out: + return ret_val; + +setup_sfp_err: + /* Release the semaphore */ + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); + /* Delay obtaining semaphore again to allow FW access */ + msec_delay(hw->eeprom.semaphore_delay); + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", data_offset); + return IXGBE_ERR_PHY; +} + +/** + * prot_autoc_read_82599 - Hides MAC differences needed for AUTOC read + * @hw: pointer to hardware structure + * @locked: Return the if we locked for this read. + * @reg_val: Value we read from AUTOC + * + * For this part (82599) we need to wrap read-modify-writes with a possible + * FW/SW lock. It is assumed this lock will be freed with the next + * prot_autoc_write_82599(). + */ +s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val) +{ + s32 ret_val; + + *locked = false; + /* If LESM is on then we need to hold the SW/FW semaphore. */ + if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (ret_val != IXGBE_SUCCESS) + return IXGBE_ERR_SWFW_SYNC; + + *locked = true; + } + + *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC); + return IXGBE_SUCCESS; +} + +/** + * prot_autoc_write_82599 - Hides MAC differences needed for AUTOC write + * @hw: pointer to hardware structure + * @autoc: value to write to AUTOC + * @locked: bool to indicate whether the SW/FW lock was already taken by + * previous proc_autoc_read_82599. + * + * This part (82599) may need to hold the SW/FW lock around all writes to + * AUTOC. Likewise after a write we need to do a pipeline reset. + */ +s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 autoc, bool locked) +{ + s32 ret_val = IXGBE_SUCCESS; + + /* Blocked by MNG FW so bail */ + if (ixgbe_check_reset_blocked(hw)) + goto out; + + /* We only need to get the lock if: + * - We didn't do it already (in the read part of a read-modify-write) + * - LESM is enabled. + */ + if (!locked && ixgbe_verify_lesm_fw_enabled_82599(hw)) { + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (ret_val != IXGBE_SUCCESS) + return IXGBE_ERR_SWFW_SYNC; + + locked = true; + } + + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); + ret_val = ixgbe_reset_pipeline_82599(hw); + +out: + /* Free the SW/FW semaphore as we either grabbed it here or + * already had it when this function was called. + */ + if (locked) + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); + + return ret_val; +} + +/** + * ixgbe_init_ops_82599 - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type for 82599. + * Does not touch the hardware. + **/ + +s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_init_ops_82599"); + + ixgbe_init_phy_ops_generic(hw); + ret_val = ixgbe_init_ops_generic(hw); + + /* PHY */ + phy->ops.identify = ixgbe_identify_phy_82599; + phy->ops.init = ixgbe_init_phy_ops_82599; + + /* MAC */ + mac->ops.reset_hw = ixgbe_reset_hw_82599; + mac->ops.get_media_type = ixgbe_get_media_type_82599; + mac->ops.get_supported_physical_layer = + ixgbe_get_supported_physical_layer_82599; + mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic; + mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic; + mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82599; + mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82599; + mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82599; + mac->ops.start_hw = ixgbe_start_hw_82599; + mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic; + mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic; + mac->ops.get_device_caps = ixgbe_get_device_caps_generic; + mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic; + mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic; + mac->ops.prot_autoc_read = prot_autoc_read_82599; + mac->ops.prot_autoc_write = prot_autoc_write_82599; + + /* RAR, Multicast, VLAN */ + mac->ops.set_vmdq = ixgbe_set_vmdq_generic; + mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic; + mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic; + mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic; + mac->rar_highwater = 1; + mac->ops.set_vfta = ixgbe_set_vfta_generic; + mac->ops.set_vlvf = ixgbe_set_vlvf_generic; + mac->ops.clear_vfta = ixgbe_clear_vfta_generic; + mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic; + mac->ops.setup_sfp = ixgbe_setup_sfp_modules_82599; + mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing; + mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing; + + /* Link */ + mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82599; + mac->ops.check_link = ixgbe_check_mac_link_generic; + mac->ops.setup_rxpba = ixgbe_set_rxpba_generic; + ixgbe_init_mac_link_ops_82599(hw); + + mac->mcft_size = IXGBE_82599_MC_TBL_SIZE; + mac->vft_size = IXGBE_82599_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES; + mac->rx_pb_size = IXGBE_82599_RX_PB_SIZE; + mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); + + mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)) + & IXGBE_FWSM_MODE_MASK); + + for (i = 0; i < 64; i++) + hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf; + + /* EEPROM */ + eeprom->ops.read = ixgbe_read_eeprom_82599; + eeprom->ops.read_buffer = ixgbe_read_eeprom_buffer_82599; + + /* Manageability interface */ + mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic; + + mac->ops.get_thermal_sensor_data = + ixgbe_get_thermal_sensor_data_generic; + mac->ops.init_thermal_sensor_thresh = + ixgbe_init_thermal_sensor_thresh_generic; + + mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic; + + return ret_val; +} + +/** + * ixgbe_get_link_capabilities_82599 - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: true when autoneg or autotry is enabled + * + * Determines the link capabilities by reading the AUTOC register. + **/ +s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_SUCCESS; + u32 autoc = 0; + + DEBUGFUNC("ixgbe_get_link_capabilities_82599"); + + + /* Check if 1G SFP module. */ + if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + goto out; + } + + /* + * Determine link capabilities based on the stored value of AUTOC, + * which represents EEPROM defaults. If AUTOC value has not + * been stored, use the current register values. + */ + if (hw->mac.orig_link_settings_stored) + autoc = hw->mac.orig_autoc; + else + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = false; + break; + + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + *speed = IXGBE_LINK_SPEED_10GB_FULL; + *autoneg = false; + break; + + case IXGBE_AUTOC_LMS_1G_AN: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + break; + + case IXGBE_AUTOC_LMS_10G_SERIAL: + *speed = IXGBE_LINK_SPEED_10GB_FULL; + *autoneg = false; + break; + + case IXGBE_AUTOC_LMS_KX4_KX_KR: + case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + if (autoc & IXGBE_AUTOC_KR_SUPP) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (autoc & IXGBE_AUTOC_KX_SUPP) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + break; + + case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII: + *speed = IXGBE_LINK_SPEED_100_FULL; + if (autoc & IXGBE_AUTOC_KR_SUPP) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (autoc & IXGBE_AUTOC_KX_SUPP) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + break; + + case IXGBE_AUTOC_LMS_SGMII_1G_100M: + *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL; + *autoneg = false; + break; + + default: + status = IXGBE_ERR_LINK_SETUP; + goto out; + break; + } + + if (hw->phy.multispeed_fiber) { + *speed |= IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + + /* QSFP must not enable full auto-negotiation + * Limited autoneg is enabled at 1G + */ + if (hw->phy.media_type == ixgbe_media_type_fiber_qsfp) + *autoneg = false; + else + *autoneg = true; + } + +out: + return status; +} + +/** + * ixgbe_get_media_type_82599 - Get media type + * @hw: pointer to hardware structure + * + * Returns the media type (fiber, copper, backplane) + **/ +enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) +{ + enum ixgbe_media_type media_type; + + DEBUGFUNC("ixgbe_get_media_type_82599"); + + /* Detect if there is a copper PHY attached. */ + switch (hw->phy.type) { + case ixgbe_phy_cu_unknown: + case ixgbe_phy_tn: + media_type = ixgbe_media_type_copper; + goto out; + default: + break; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: + case IXGBE_DEV_ID_82599_XAUI_LOM: + /* Default device ID is mezzanine card KX/KX4 */ + media_type = ixgbe_media_type_backplane; + break; + case IXGBE_DEV_ID_82599_SFP: + case IXGBE_DEV_ID_82599_SFP_FCOE: + case IXGBE_DEV_ID_82599_SFP_EM: + case IXGBE_DEV_ID_82599_SFP_SF2: + case IXGBE_DEV_ID_82599_SFP_SF_QP: + case IXGBE_DEV_ID_82599EN_SFP: + media_type = ixgbe_media_type_fiber; + break; + case IXGBE_DEV_ID_82599_CX4: + media_type = ixgbe_media_type_cx4; + break; + case IXGBE_DEV_ID_82599_T3_LOM: + media_type = ixgbe_media_type_copper; + break; + case IXGBE_DEV_ID_82599_QSFP_SF_QP: + media_type = ixgbe_media_type_fiber_qsfp; + break; + default: + media_type = ixgbe_media_type_unknown; + break; + } +out: + return media_type; +} + +/** + * ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3 + * @hw: pointer to hardware structure + * + * Disables link during D3 power down sequence. + * + **/ +void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw) +{ + u16 ee_ctrl_2 = 0; + u32 autoc2_reg; + u32 status; + + DEBUGFUNC("ixgbe_stop_mac_link_on_d3_82599"); + status = ixgbe_read_eeprom(hw, IXGBE_EEPROM_CTRL_2, &ee_ctrl_2); + + if (status == IXGBE_SUCCESS && + !ixgbe_mng_present(hw) && !hw->wol_enabled && + ee_ctrl_2 & IXGBE_EEPROM_CCD_BIT) { + autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + autoc2_reg |= IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg); + } +} + +/** + * ixgbe_start_mac_link_82599 - Setup MAC link settings + * @hw: pointer to hardware structure + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Configures link settings based on values in the ixgbe_hw struct. + * Restarts the link. Performs autonegotiation if needed. + **/ +s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete) +{ + u32 autoc_reg; + u32 links_reg; + u32 i; + s32 status = IXGBE_SUCCESS; + bool got_lock = false; + + DEBUGFUNC("ixgbe_start_mac_link_82599"); + + /* reset_pipeline requires us to hold this lock as it writes to + * AUTOC. + */ + if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { + status = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (status != IXGBE_SUCCESS) + goto out; + + got_lock = true; + } + + /* Restart link */ + ixgbe_reset_pipeline_82599(hw); + + if (got_lock) + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); + + /* Only poll for autoneg to complete if specified to do so */ + if (autoneg_wait_to_complete) { + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_KX_KR || + (autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || + (autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { + links_reg = 0; /* Just in case Autoneg time = 0 */ + for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + if (links_reg & IXGBE_LINKS_KX_AN_COMP) + break; + msec_delay(100); + } + if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { + status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; + hw_dbg(hw, "Autoneg did not complete.\n"); + } + } + } + + /* Add delay to filter out noises during initial link setup */ + msec_delay(50); + +out: + return status; +} + +/** + * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively shutting down the Tx + * laser on the PHY, effectively halting physical link. + **/ +void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* Blocked by MNG FW so bail */ + if (ixgbe_check_reset_blocked(hw)) + return; + + /* Disable Tx laser; allow 100us to go dark per spec */ + esdp_reg |= IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + usec_delay(100); +} + +/** + * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively turning on the Tx + * laser on the PHY, effectively starting physical link. + **/ +void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* Enable Tx laser; allow 100ms to light up */ + esdp_reg &= ~IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + msec_delay(100); +} + +/** + * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser + * @hw: pointer to hardware structure + * + * When the driver changes the link speeds that it can support, + * it sets autotry_restart to true to indicate that we need to + * initiate a new autotry session with the link partner. To do + * so, we set the speed then disable and re-enable the Tx laser, to + * alert the link partner that it also needs to restart autotry on its + * end. This is consistent with true clause 37 autoneg, which also + * involves a loss of signal. + **/ +void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + DEBUGFUNC("ixgbe_flap_tx_laser_multispeed_fiber"); + + /* Blocked by MNG FW so bail */ + if (ixgbe_check_reset_blocked(hw)) + return; + + if (hw->mac.autotry_restart) { + ixgbe_disable_tx_laser_multispeed_fiber(hw); + ixgbe_enable_tx_laser_multispeed_fiber(hw); + hw->mac.autotry_restart = false; + } +} + +/** + * ixgbe_set_hard_rate_select_speed - Set module link speed + * @hw: pointer to hardware structure + * @speed: link speed to set + * + * Set module link speed via RS0/RS1 rate select pins. + */ +void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw, + ixgbe_link_speed speed) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + switch (speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); + break; + case IXGBE_LINK_SPEED_1GB_FULL: + esdp_reg &= ~IXGBE_ESDP_SDP5; + esdp_reg |= IXGBE_ESDP_SDP5_DIR; + break; + default: + hw_dbg(hw, "Invalid fixed module speed\n"); + return; + } + + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Implements the Intel SmartSpeed algorithm. + **/ +s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 status = IXGBE_SUCCESS; + ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; + s32 i, j; + bool link_up = false; + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + DEBUGFUNC("ixgbe_setup_mac_link_smartspeed"); + + /* Set autoneg_advertised value based on input link speed */ + hw->phy.autoneg_advertised = 0; + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + if (speed & IXGBE_LINK_SPEED_100_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + + /* + * Implement Intel SmartSpeed algorithm. SmartSpeed will reduce the + * autoneg advertisement if link is unable to be established at the + * highest negotiated rate. This can sometimes happen due to integrity + * issues with the physical media connection. + */ + + /* First, try to get link with full advertisement */ + hw->phy.smart_speed_active = false; + for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) { + status = ixgbe_setup_mac_link_82599(hw, speed, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + goto out; + + /* + * Wait for the controller to acquire link. Per IEEE 802.3ap, + * Section 73.10.2, we may have to wait up to 500ms if KR is + * attempted, or 200ms if KX/KX4/BX/BX4 is attempted, per + * Table 9 in the AN MAS. + */ + for (i = 0; i < 5; i++) { + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, + false); + if (status != IXGBE_SUCCESS) + goto out; + + if (link_up) + goto out; + } + } + + /* + * We didn't get link. If we advertised KR plus one of KX4/KX + * (or BX4/BX), then disable KR and try again. + */ + if (((autoc_reg & IXGBE_AUTOC_KR_SUPP) == 0) || + ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0)) + goto out; + + /* Turn SmartSpeed on to disable KR support */ + hw->phy.smart_speed_active = true; + status = ixgbe_setup_mac_link_82599(hw, speed, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + goto out; + + /* + * Wait for the controller to acquire link. 600ms will allow for + * the AN link_fail_inhibit_timer as well for multiple cycles of + * parallel detect, both 10g and 1g. This allows for the maximum + * connect attempts as defined in the AN MAS table 73-7. + */ + for (i = 0; i < 6; i++) { + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, false); + if (status != IXGBE_SUCCESS) + goto out; + + if (link_up) + goto out; + } + + /* We didn't get link. Turn SmartSpeed back off. */ + hw->phy.smart_speed_active = false; + status = ixgbe_setup_mac_link_82599(hw, speed, + autoneg_wait_to_complete); + +out: + if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL)) + hw_dbg(hw, "Smartspeed has downgraded the link speed " + "from the maximum advertised\n"); + return status; +} + +/** + * ixgbe_setup_mac_link_82599 - Set MAC link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Set the link speed in the AUTOC register and restarts link. + **/ +s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + bool autoneg = false; + s32 status = IXGBE_SUCCESS; + u32 pma_pmd_1g, link_mode; + u32 current_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); /* holds the value of AUTOC register at this current point in time */ + u32 orig_autoc = 0; /* holds the cached value of AUTOC register */ + u32 autoc = current_autoc; /* Temporary variable used for comparison purposes */ + u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK; + u32 links_reg; + u32 i; + ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; + + DEBUGFUNC("ixgbe_setup_mac_link_82599"); + + /* Check to see if speed passed in is supported. */ + status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg); + if (status) + goto out; + + speed &= link_capabilities; + + if (speed == IXGBE_LINK_SPEED_UNKNOWN) { + status = IXGBE_ERR_LINK_SETUP; + goto out; + } + + /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ + if (hw->mac.orig_link_settings_stored) + orig_autoc = hw->mac.orig_autoc; + else + orig_autoc = autoc; + + link_mode = autoc & IXGBE_AUTOC_LMS_MASK; + pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; + + if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || + link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || + link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { + /* Set KX4/KX/KR support according to speed requested */ + autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) + autoc |= IXGBE_AUTOC_KX4_SUPP; + if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && + (hw->phy.smart_speed_active == false)) + autoc |= IXGBE_AUTOC_KR_SUPP; + } + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + autoc |= IXGBE_AUTOC_KX_SUPP; + } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && + (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN || + link_mode == IXGBE_AUTOC_LMS_1G_AN)) { + /* Switch from 1G SFI to 10G SFI if requested */ + if ((speed == IXGBE_LINK_SPEED_10GB_FULL) && + (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) { + autoc &= ~IXGBE_AUTOC_LMS_MASK; + autoc |= IXGBE_AUTOC_LMS_10G_SERIAL; + } + } else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) && + (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) { + /* Switch from 10G SFI to 1G SFI if requested */ + if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && + (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) { + autoc &= ~IXGBE_AUTOC_LMS_MASK; + if (autoneg || hw->phy.type == ixgbe_phy_qsfp_intel) + autoc |= IXGBE_AUTOC_LMS_1G_AN; + else + autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN; + } + } + + if (autoc != current_autoc) { + /* Restart link */ + status = hw->mac.ops.prot_autoc_write(hw, autoc, false); + if (status != IXGBE_SUCCESS) + goto out; + + /* Only poll for autoneg to complete if specified to do so */ + if (autoneg_wait_to_complete) { + if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || + link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || + link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { + links_reg = 0; /*Just in case Autoneg time=0*/ + for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { + links_reg = + IXGBE_READ_REG(hw, IXGBE_LINKS); + if (links_reg & IXGBE_LINKS_KX_AN_COMP) + break; + msec_delay(100); + } + if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { + status = + IXGBE_ERR_AUTONEG_NOT_COMPLETE; + hw_dbg(hw, "Autoneg did not complete.\n"); + } + } + } + + /* Add delay to filter out noises during initial link setup */ + msec_delay(50); + } + +out: + return status; +} + +/** + * ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true if waiting is needed to complete + * + * Restarts link on PHY and MAC based on settings passed in. + **/ +STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 status; + + DEBUGFUNC("ixgbe_setup_copper_link_82599"); + + /* Setup the PHY according to input speed */ + status = hw->phy.ops.setup_link_speed(hw, speed, + autoneg_wait_to_complete); + /* Set up MAC */ + ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete); + + return status; +} + +/** + * ixgbe_reset_hw_82599 - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks + * and clears all interrupts, perform a PHY reset, and perform a link (MAC) + * reset. + **/ +s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) +{ + ixgbe_link_speed link_speed; + s32 status; + u32 ctrl = 0; + u32 i, autoc, autoc2; + u32 curr_lms; + bool link_up = false; + + DEBUGFUNC("ixgbe_reset_hw_82599"); + + /* Call adapter stop to disable tx/rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); + if (status != IXGBE_SUCCESS) + goto reset_hw_out; + + /* flush pending Tx transactions */ + ixgbe_clear_tx_pending(hw); + + /* PHY ops must be identified and initialized prior to reset */ + + /* Identify PHY and related function pointers */ + status = hw->phy.ops.init(hw); + + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + + /* Setup SFP module if there is one present. */ + if (hw->phy.sfp_setup_needed) { + status = hw->mac.ops.setup_sfp(hw); + hw->phy.sfp_setup_needed = false; + } + + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + + /* Reset PHY */ + if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL) + hw->phy.ops.reset(hw); + + /* remember AUTOC from before we reset */ + curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK; + +mac_reset_top: + /* + * Issue global reset to the MAC. Needs to be SW reset if link is up. + * If link reset is used when link is up, it might reset the PHY when + * mng is using it. If link is down or the flag to force full link + * reset is set, then perform link reset. + */ + ctrl = IXGBE_CTRL_LNK_RST; + if (!hw->force_full_reset) { + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + if (link_up) + ctrl = IXGBE_CTRL_RST; + } + + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); + + /* Poll for reset bit to self-clear meaning reset is complete */ + for (i = 0; i < 10; i++) { + usec_delay(1); + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST_MASK)) + break; + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { + status = IXGBE_ERR_RESET_FAILED; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + + msec_delay(50); + + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to + * allow time for any pending HW events to complete. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + goto mac_reset_top; + } + + /* + * Store the original AUTOC/AUTOC2 values if they have not been + * stored off yet. Otherwise restore the stored original + * values since the reset operation sets back to defaults. + */ + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + + /* Enable link if disabled in NVM */ + if (autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK) { + autoc2 &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2); + IXGBE_WRITE_FLUSH(hw); + } + + if (hw->mac.orig_link_settings_stored == false) { + hw->mac.orig_autoc = autoc; + hw->mac.orig_autoc2 = autoc2; + hw->mac.orig_link_settings_stored = true; + } else { + + /* If MNG FW is running on a multi-speed device that + * doesn't autoneg with out driver support we need to + * leave LMS in the state it was before we MAC reset. + * Likewise if we support WoL we don't want change the + * LMS state. + */ + if ((hw->phy.multispeed_fiber && ixgbe_mng_enabled(hw)) || + hw->wol_enabled) + hw->mac.orig_autoc = + (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) | + curr_lms; + + if (autoc != hw->mac.orig_autoc) { + status = hw->mac.ops.prot_autoc_write(hw, + hw->mac.orig_autoc, + false); + if (status != IXGBE_SUCCESS) + goto reset_hw_out; + } + + if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != + (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { + autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK; + autoc2 |= (hw->mac.orig_autoc2 & + IXGBE_AUTOC2_UPPER_MASK); + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2); + } + } + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. Also reset num_rar_entries to 128, + * since we modify this value when programming the SAN MAC address. + */ + hw->mac.num_rar_entries = 128; + hw->mac.ops.init_rx_addrs(hw); + + /* Store the permanent SAN mac address */ + hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); + + /* Add the SAN MAC address to the RAR only if it's a valid address */ + if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { + /* Save the SAN MAC RAR index */ + hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; + + hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index, + hw->mac.san_addr, 0, IXGBE_RAH_AV); + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index, + IXGBE_CLEAR_VMDQ_ALL); + + /* Reserve the last RAR for the SAN MAC address */ + hw->mac.num_rar_entries--; + } + + /* Store the alternative WWNN/WWPN prefix */ + hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, + &hw->mac.wwpn_prefix); + +reset_hw_out: + return status; +} + +/** + * ixgbe_fdir_check_cmd_complete - poll to check whether FDIRCMD is complete + * @hw: pointer to hardware structure + * @fdircmd: current value of FDIRCMD register + */ +STATIC s32 ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw, u32 *fdircmd) +{ + int i; + + for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) { + *fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD); + if (!(*fdircmd & IXGBE_FDIRCMD_CMD_MASK)) + return IXGBE_SUCCESS; + usec_delay(10); + } + + return IXGBE_ERR_FDIR_CMD_INCOMPLETE; +} + +/** + * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables. + * @hw: pointer to hardware structure + **/ +s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) +{ + s32 err; + int i; + u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL); + u32 fdircmd; + fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE; + + DEBUGFUNC("ixgbe_reinit_fdir_tables_82599"); + + /* + * Before starting reinitialization process, + * FDIRCMD.CMD must be zero. + */ + err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd); + if (err) { + hw_dbg(hw, "Flow Director previous command did not complete, aborting table re-initialization.\n"); + return err; + } + + IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0); + IXGBE_WRITE_FLUSH(hw); + /* + * 82599 adapters flow director init flow cannot be restarted, + * Workaround 82599 silicon errata by performing the following steps + * before re-writing the FDIRCTRL control register with the same value. + * - write 1 to bit 8 of FDIRCMD register & + * - write 0 to bit 8 of FDIRCMD register + */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, + (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) | + IXGBE_FDIRCMD_CLEARHT)); + IXGBE_WRITE_FLUSH(hw); + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, + (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & + ~IXGBE_FDIRCMD_CLEARHT)); + IXGBE_WRITE_FLUSH(hw); + /* + * Clear FDIR Hash register to clear any leftover hashes + * waiting to be programmed. + */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00); + IXGBE_WRITE_FLUSH(hw); + + IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); + IXGBE_WRITE_FLUSH(hw); + + /* Poll init-done after we write FDIRCTRL register */ + for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { + if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & + IXGBE_FDIRCTRL_INIT_DONE) + break; + msec_delay(1); + } + if (i >= IXGBE_FDIR_INIT_DONE_POLL) { + hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); + return IXGBE_ERR_FDIR_REINIT_FAILED; + } + + /* Clear FDIR statistics registers (read to clear) */ + IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT); + IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT); + IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); + IXGBE_READ_REG(hw, IXGBE_FDIRMISS); + IXGBE_READ_REG(hw, IXGBE_FDIRLEN); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fdir_enable_82599 - Initialize Flow Director control registers + * @hw: pointer to hardware structure + * @fdirctrl: value to write to flow director control register + **/ +STATIC void ixgbe_fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl) +{ + int i; + + DEBUGFUNC("ixgbe_fdir_enable_82599"); + + /* Prime the keys for hashing */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY); + IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY); + + /* + * Poll init-done after we write the register. Estimated times: + * 10G: PBALLOC = 11b, timing is 60us + * 1G: PBALLOC = 11b, timing is 600us + * 100M: PBALLOC = 11b, timing is 6ms + * + * Multiple these timings by 4 if under full Rx load + * + * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for + * 1 msec per poll time. If we're at line rate and drop to 100M, then + * this might not finish in our poll time, but we can live with that + * for now. + */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); + IXGBE_WRITE_FLUSH(hw); + for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { + if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & + IXGBE_FDIRCTRL_INIT_DONE) + break; + msec_delay(1); + } + + if (i >= IXGBE_FDIR_INIT_DONE_POLL) + hw_dbg(hw, "Flow Director poll time exceeded!\n"); +} + +/** + * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters + * @hw: pointer to hardware structure + * @fdirctrl: value to write to flow director control register, initially + * contains just the value of the Rx packet buffer allocation + **/ +s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl) +{ + DEBUGFUNC("ixgbe_init_fdir_signature_82599"); + + /* + * Continue setup of fdirctrl register bits: + * Move the flexible bytes to use the ethertype - shift 6 words + * Set the maximum length per hash bucket to 0xA filters + * Send interrupt when 64 filters are left + */ + fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) | + (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) | + (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT); + + /* write hashes and fdirctrl register, poll for completion */ + ixgbe_fdir_enable_82599(hw, fdirctrl); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters + * @hw: pointer to hardware structure + * @fdirctrl: value to write to flow director control register, initially + * contains just the value of the Rx packet buffer allocation + * @cloud_mode: true - cloud mode, false - other mode + **/ +s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl, + bool cloud_mode) +{ + UNREFERENCED_1PARAMETER(cloud_mode); + DEBUGFUNC("ixgbe_init_fdir_perfect_82599"); + + /* + * Continue setup of fdirctrl register bits: + * Turn perfect match filtering on + * Report hash in RSS field of Rx wb descriptor + * Initialize the drop queue to queue 127 + * Move the flexible bytes to use the ethertype - shift 6 words + * Set the maximum length per hash bucket to 0xA filters + * Send interrupt when 64 (0x4 * 16) filters are left + */ + fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH | + IXGBE_FDIRCTRL_REPORT_STATUS | + (IXGBE_FDIR_DROP_QUEUE << IXGBE_FDIRCTRL_DROP_Q_SHIFT) | + (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) | + (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) | + (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT); + + if (cloud_mode) + fdirctrl |=(IXGBE_FDIRCTRL_FILTERMODE_CLOUD << + IXGBE_FDIRCTRL_FILTERMODE_SHIFT); + + /* write hashes and fdirctrl register, poll for completion */ + ixgbe_fdir_enable_82599(hw, fdirctrl); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_fdir_drop_queue_82599 - Set Flow Director drop queue + * @hw: pointer to hardware structure + * @dropqueue: Rx queue index used for the dropped packets + **/ +void ixgbe_set_fdir_drop_queue_82599(struct ixgbe_hw *hw, u8 dropqueue) +{ + u32 fdirctrl; + + DEBUGFUNC("ixgbe_set_fdir_drop_queue_82599"); + /* Clear init done bit and drop queue field */ + fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL); + fdirctrl &= ~(IXGBE_FDIRCTRL_DROP_Q_MASK | IXGBE_FDIRCTRL_INIT_DONE); + + /* Set drop queue */ + fdirctrl |= (dropqueue << IXGBE_FDIRCTRL_DROP_Q_SHIFT); + if (hw->mac.type == ixgbe_mac_X550 || + hw->mac.type == ixgbe_mac_X550EM_x || + hw->mac.type == ixgbe_mac_X550EM_a || + ixgbe_is_mac_E6xx(hw->mac.type)) + fdirctrl |= IXGBE_FDIRCTRL_DROP_NO_MATCH; + + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, + (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) | + IXGBE_FDIRCMD_CLEARHT)); + IXGBE_WRITE_FLUSH(hw); + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, + (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & + ~IXGBE_FDIRCMD_CLEARHT)); + IXGBE_WRITE_FLUSH(hw); + + /* write hashes and fdirctrl register, poll for completion */ + ixgbe_fdir_enable_82599(hw, fdirctrl); +} + +/* + * These defines allow us to quickly generate all of the necessary instructions + * in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION + * for values 0 through 15 + */ +#define IXGBE_ATR_COMMON_HASH_KEY \ + (IXGBE_ATR_BUCKET_HASH_KEY & IXGBE_ATR_SIGNATURE_HASH_KEY) +#define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \ +do { \ + u32 n = (_n); \ + if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) \ + common_hash ^= lo_hash_dword >> n; \ + else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \ + bucket_hash ^= lo_hash_dword >> n; \ + else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << n)) \ + sig_hash ^= lo_hash_dword << (16 - n); \ + if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << (n + 16))) \ + common_hash ^= hi_hash_dword >> n; \ + else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \ + bucket_hash ^= hi_hash_dword >> n; \ + else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \ + sig_hash ^= hi_hash_dword << (16 - n); \ +} while (0) + +/** + * ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash + * @input: input bitstream to compute the hash on + * @common: compressed common input dword + * + * This function is almost identical to the function above but contains + * several optimizations such as unwinding all of the loops, letting the + * compiler work out all of the conditional ifs since the keys are static + * defines, and computing two keys at once since the hashed dword stream + * will be the same for both keys. + **/ +u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common) +{ + u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan; + u32 sig_hash = 0, bucket_hash = 0, common_hash = 0; + + /* record the flow_vm_vlan bits as they are a key part to the hash */ + flow_vm_vlan = IXGBE_NTOHL(input.dword); + + /* generate common hash dword */ + hi_hash_dword = IXGBE_NTOHL(common.dword); + + /* low dword is word swapped version of common */ + lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16); + + /* apply flow ID/VM pool/VLAN ID bits to hash words */ + hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16); + + /* Process bits 0 and 16 */ + IXGBE_COMPUTE_SIG_HASH_ITERATION(0); + + /* + * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to + * delay this because bit 0 of the stream should not be processed + * so we do not add the VLAN until after bit 0 was processed + */ + lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16); + + /* Process remaining 30 bit of the key */ + IXGBE_COMPUTE_SIG_HASH_ITERATION(1); + IXGBE_COMPUTE_SIG_HASH_ITERATION(2); + IXGBE_COMPUTE_SIG_HASH_ITERATION(3); + IXGBE_COMPUTE_SIG_HASH_ITERATION(4); + IXGBE_COMPUTE_SIG_HASH_ITERATION(5); + IXGBE_COMPUTE_SIG_HASH_ITERATION(6); + IXGBE_COMPUTE_SIG_HASH_ITERATION(7); + IXGBE_COMPUTE_SIG_HASH_ITERATION(8); + IXGBE_COMPUTE_SIG_HASH_ITERATION(9); + IXGBE_COMPUTE_SIG_HASH_ITERATION(10); + IXGBE_COMPUTE_SIG_HASH_ITERATION(11); + IXGBE_COMPUTE_SIG_HASH_ITERATION(12); + IXGBE_COMPUTE_SIG_HASH_ITERATION(13); + IXGBE_COMPUTE_SIG_HASH_ITERATION(14); + IXGBE_COMPUTE_SIG_HASH_ITERATION(15); + + /* combine common_hash result with signature and bucket hashes */ + bucket_hash ^= common_hash; + bucket_hash &= IXGBE_ATR_HASH_MASK; + + sig_hash ^= common_hash << 16; + sig_hash &= IXGBE_ATR_HASH_MASK << 16; + + /* return completed signature hash */ + return sig_hash ^ bucket_hash; +} + +/** + * ixgbe_fdir_add_signature_filter_82599 - Adds a signature hash filter + * @hw: pointer to hardware structure + * @input: unique input dword + * @common: compressed common input dword + * @queue: queue index to direct traffic to + * + * Note that the tunnel bit in input must not be set when the hardware + * tunneling support does not exist. + **/ +void ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common, + u8 queue) +{ + u64 fdirhashcmd; + u8 flow_type; + bool tunnel; + u32 fdircmd; + + DEBUGFUNC("ixgbe_fdir_add_signature_filter_82599"); + + /* + * Get the flow_type in order to program FDIRCMD properly + * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 + * fifth is FDIRCMD.TUNNEL_FILTER + */ + tunnel = !!(input.formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK); + flow_type = input.formatted.flow_type & + (IXGBE_ATR_L4TYPE_TUNNEL_MASK - 1); + switch (flow_type) { + case IXGBE_ATR_FLOW_TYPE_TCPV4: + case IXGBE_ATR_FLOW_TYPE_UDPV4: + case IXGBE_ATR_FLOW_TYPE_SCTPV4: + case IXGBE_ATR_FLOW_TYPE_TCPV6: + case IXGBE_ATR_FLOW_TYPE_UDPV6: + case IXGBE_ATR_FLOW_TYPE_SCTPV6: + break; + default: + hw_dbg(hw, " Error on flow type input\n"); + return; + } + + /* configure FDIRCMD register */ + fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | + IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN; + fdircmd |= (u32)flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; + fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; + if (tunnel) + fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER; + + /* + * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits + * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH. + */ + fdirhashcmd = (u64)fdircmd << 32; + fdirhashcmd |= (u64)ixgbe_atr_compute_sig_hash_82599(input, common); + IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd); + + hw_dbg(hw, "Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd); + + return; +} + +#define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \ +do { \ + u32 n = (_n); \ + if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \ + bucket_hash ^= lo_hash_dword >> n; \ + if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \ + bucket_hash ^= hi_hash_dword >> n; \ +} while (0) + +/** + * ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash + * @input: input bitstream to compute the hash on + * @input_mask: mask for the input bitstream + * + * This function serves two main purposes. First it applies the input_mask + * to the atr_input resulting in a cleaned up atr_input data stream. + * Secondly it computes the hash and stores it in the bkt_hash field at + * the end of the input byte stream. This way it will be available for + * future use without needing to recompute the hash. + **/ +void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, + union ixgbe_atr_input *input_mask) +{ + + u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan; + u32 bucket_hash = 0; + u32 hi_dword = 0; + u32 i = 0; + + /* Apply masks to input data */ + for (i = 0; i < 14; i++) + input->dword_stream[i] &= input_mask->dword_stream[i]; + + /* record the flow_vm_vlan bits as they are a key part to the hash */ + flow_vm_vlan = IXGBE_NTOHL(input->dword_stream[0]); + + /* generate common hash dword */ + for (i = 1; i <= 13; i++) + hi_dword ^= input->dword_stream[i]; + hi_hash_dword = IXGBE_NTOHL(hi_dword); + + /* low dword is word swapped version of common */ + lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16); + + /* apply flow ID/VM pool/VLAN ID bits to hash words */ + hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16); + + /* Process bits 0 and 16 */ + IXGBE_COMPUTE_BKT_HASH_ITERATION(0); + + /* + * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to + * delay this because bit 0 of the stream should not be processed + * so we do not add the VLAN until after bit 0 was processed + */ + lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16); + + /* Process remaining 30 bit of the key */ + for (i = 1; i <= 15; i++) + IXGBE_COMPUTE_BKT_HASH_ITERATION(i); + + /* + * Limit hash to 13 bits since max bucket count is 8K. + * Store result at the end of the input stream. + */ + input->formatted.bkt_hash = bucket_hash & 0x1FFF; +} + +/** + * ixgbe_get_fdirtcpm_82599 - generate a TCP port from atr_input_masks + * @input_mask: mask to be bit swapped + * + * The source and destination port masks for flow director are bit swapped + * in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc. In order to + * generate a correctly swapped value we need to bit swap the mask and that + * is what is accomplished by this function. + **/ +STATIC u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask) +{ + u32 mask = IXGBE_NTOHS(input_mask->formatted.dst_port); + mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT; + mask |= (u32)IXGBE_NTOHS(input_mask->formatted.src_port); + mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1); + mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2); + mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4); + return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8); +} + +/* + * These two macros are meant to address the fact that we have registers + * that are either all or in part big-endian. As a result on big-endian + * systems we will end up byte swapping the value to little-endian before + * it is byte swapped again and written to the hardware in the original + * big-endian format. + */ +#define IXGBE_STORE_AS_BE32(_value) \ + (((u32)(_value) >> 24) | (((u32)(_value) & 0x00FF0000) >> 8) | \ + (((u32)(_value) & 0x0000FF00) << 8) | ((u32)(_value) << 24)) + +#define IXGBE_WRITE_REG_BE32(a, reg, value) \ + IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(IXGBE_NTOHL(value))) + +#define IXGBE_STORE_AS_BE16(_value) \ + IXGBE_NTOHS(((u16)(_value) >> 8) | ((u16)(_value) << 8)) + +s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input_mask, bool cloud_mode) +{ + /* mask IPv6 since it is currently not supported */ + u32 fdirm = IXGBE_FDIRM_DIPv6; + u32 fdirtcpm; + u32 fdirip6m; + UNREFERENCED_1PARAMETER(cloud_mode); + DEBUGFUNC("ixgbe_fdir_set_atr_input_mask_82599"); + + /* + * Program the relevant mask registers. If src/dst_port or src/dst_addr + * are zero, then assume a full mask for that field. Also assume that + * a VLAN of 0 is unspecified, so mask that out as well. L4type + * cannot be masked out in this implementation. + * + * This also assumes IPv4 only. IPv6 masking isn't supported at this + * point in time. + */ + + /* verify bucket hash is cleared on hash generation */ + if (input_mask->formatted.bkt_hash) + hw_dbg(hw, " bucket hash should always be 0 in mask\n"); + + /* Program FDIRM and verify partial masks */ + switch (input_mask->formatted.vm_pool & 0x7F) { + case 0x0: + fdirm |= IXGBE_FDIRM_POOL; + case 0x7F: + break; + default: + hw_dbg(hw, " Error on vm pool mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) { + case 0x0: + fdirm |= IXGBE_FDIRM_L4P; + if (input_mask->formatted.dst_port || + input_mask->formatted.src_port) { + hw_dbg(hw, " Error on src/dst port mask\n"); + return IXGBE_ERR_CONFIG; + } + case IXGBE_ATR_L4TYPE_MASK: + break; + default: + hw_dbg(hw, " Error on flow type mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (IXGBE_NTOHS(input_mask->formatted.vlan_id) & 0xEFFF) { + case 0x0000: + /* mask VLAN ID */ + fdirm |= IXGBE_FDIRM_VLANID; + fallthrough; + case 0x0FFF: + /* mask VLAN priority */ + fdirm |= IXGBE_FDIRM_VLANP; + break; + case 0xE000: + /* mask VLAN ID only */ + fdirm |= IXGBE_FDIRM_VLANID; + fallthrough; + case 0xEFFF: + /* no VLAN fields masked */ + break; + default: + hw_dbg(hw, " Error on VLAN mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (input_mask->formatted.flex_bytes & 0xFFFF) { + case 0x0000: + /* Mask Flex Bytes */ + fdirm |= IXGBE_FDIRM_FLEX; + fallthrough; + case 0xFFFF: + break; + default: + hw_dbg(hw, " Error on flexible byte mask\n"); + return IXGBE_ERR_CONFIG; + } + + if (cloud_mode) { + fdirm |= IXGBE_FDIRM_L3P; + fdirip6m = ((u32) 0xFFFFU << IXGBE_FDIRIP6M_DIPM_SHIFT); + fdirip6m |= IXGBE_FDIRIP6M_ALWAYS_MASK; + + switch (input_mask->formatted.inner_mac[0] & 0xFF) { + case 0x00: + /* Mask inner MAC, fall through */ + fdirip6m |= IXGBE_FDIRIP6M_INNER_MAC; + case 0xFF: + break; + default: + hw_dbg(hw, " Error on inner_mac byte mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (input_mask->formatted.tni_vni & 0xFFFFFFFF) { + case 0x0: + /* Mask vxlan id */ + fdirip6m |= IXGBE_FDIRIP6M_TNI_VNI; + break; + case 0x00FFFFFF: + fdirip6m |= IXGBE_FDIRIP6M_TNI_VNI_24; + break; + case 0xFFFFFFFF: + break; + default: + hw_dbg(hw, " Error on TNI/VNI byte mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (input_mask->formatted.tunnel_type & 0xFFFF) { + case 0x0: + /* Mask turnnel type, fall through */ + fdirip6m |= IXGBE_FDIRIP6M_TUNNEL_TYPE; + case 0xFFFF: + break; + default: + hw_dbg(hw, " Error on tunnel type byte mask\n"); + return IXGBE_ERR_CONFIG; + } + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIP6M, fdirip6m); + + /* Set all bits in FDIRTCPM, FDIRUDPM, FDIRSCTPM, + * FDIRSIP4M and FDIRDIP4M in cloud mode to allow + * L3/L3 packets to tunnel. + */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xFFFFFFFF); + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xFFFFFFFF); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M, 0xFFFFFFFF); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, 0xFFFFFFFF); + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, 0xFFFFFFFF); + break; + default: + break; + } + } + + /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); + + if (!cloud_mode) { + /* store the TCP/UDP port masks, bit reversed from port + * layout */ + fdirtcpm = ixgbe_get_fdirtcpm_82599(input_mask); + + /* write both the same so that UDP and TCP use the same mask */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm); + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm); + /* also use it for SCTP */ + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm); + break; + default: + break; + } + + /* store source and destination IP masks (big-enian) */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, + ~input_mask->formatted.src_ip[0]); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M, + ~input_mask->formatted.dst_ip[0]); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIP6M, 0xFFFFFFFF); + } + return IXGBE_SUCCESS; +} + +s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id, u8 queue, bool cloud_mode) +{ + u32 fdirport, fdirvlan, fdirhash, fdircmd; + u32 addr_low, addr_high; + u32 cloud_type = 0; + s32 err; + UNREFERENCED_1PARAMETER(cloud_mode); + + DEBUGFUNC("ixgbe_fdir_write_perfect_filter_82599"); + if (!cloud_mode) { + /* currently IPv6 is not supported, must be programmed with 0 */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0), + input->formatted.src_ip[0]); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1), + input->formatted.src_ip[1]); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2), + input->formatted.src_ip[2]); + + /* record the source address (big-endian) */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, + input->formatted.src_ip[0]); + + /* record the first 32 bits of the destination address + * (big-endian) */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, + input->formatted.dst_ip[0]); + + /* record source and destination port (little-endian)*/ + fdirport = IXGBE_NTOHS(input->formatted.dst_port); + fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT; + fdirport |= (u32)IXGBE_NTOHS(input->formatted.src_port); + IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport); + } + + /* record VLAN (little-endian) and flex_bytes(big-endian) */ + fdirvlan = IXGBE_STORE_AS_BE16(input->formatted.flex_bytes); + fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT; + fdirvlan |= (u32)IXGBE_NTOHS(input->formatted.vlan_id); + IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan); + + if (cloud_mode) { + if (input->formatted.tunnel_type != 0) + cloud_type = 0x80000000; + + addr_low = ((u32)input->formatted.inner_mac[0] | + ((u32)input->formatted.inner_mac[1] << 8) | + ((u32)input->formatted.inner_mac[2] << 16) | + ((u32)input->formatted.inner_mac[3] << 24)); + addr_high = ((u32)input->formatted.inner_mac[4] | + ((u32)input->formatted.inner_mac[5] << 8)); + cloud_type |= addr_high; + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0), addr_low); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1), cloud_type); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2), input->formatted.tni_vni); + } + + /* configure FDIRHASH register */ + fdirhash = input->formatted.bkt_hash; + fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); + + /* + * flush all previous writes to make certain registers are + * programmed prior to issuing the command + */ + IXGBE_WRITE_FLUSH(hw); + + /* configure FDIRCMD register */ + fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | + IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN; + if (queue == IXGBE_FDIR_DROP_QUEUE) + fdircmd |= IXGBE_FDIRCMD_DROP; + if (input->formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK) + fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER; + fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; + fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; + fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT; + + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); + err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd); + if (err) { + hw_dbg(hw, "Flow Director command did not complete!\n"); + return err; + } + + return IXGBE_SUCCESS; +} + +s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id) +{ + u32 fdirhash; + u32 fdircmd; + s32 err; + + /* configure FDIRHASH register */ + fdirhash = input->formatted.bkt_hash; + fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); + + /* flush hash to HW */ + IXGBE_WRITE_FLUSH(hw); + + /* Query if filter is present */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT); + + err = ixgbe_fdir_check_cmd_complete(hw, &fdircmd); + if (err) { + hw_dbg(hw, "Flow Director command did not complete!\n"); + return err; + } + + /* if filter exists in hardware then remove it */ + if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) { + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); + IXGBE_WRITE_FLUSH(hw); + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, + IXGBE_FDIRCMD_CMD_REMOVE_FLOW); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register + * @hw: pointer to hardware structure + * @reg: analog register to read + * @val: read value + * + * Performs read operation to Omer analog register specified. + **/ +s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val) +{ + u32 core_ctl; + + DEBUGFUNC("ixgbe_read_analog_reg8_82599"); + + IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD | + (reg << 8)); + IXGBE_WRITE_FLUSH(hw); + usec_delay(10); + core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL); + *val = (u8)core_ctl; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register + * @hw: pointer to hardware structure + * @reg: atlas register to write + * @val: value to write + * + * Performs write operation to Omer analog register specified. + **/ +s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val) +{ + u32 core_ctl; + + DEBUGFUNC("ixgbe_write_analog_reg8_82599"); + + core_ctl = (reg << 8) | val; + IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl); + IXGBE_WRITE_FLUSH(hw); + usec_delay(10); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware using the generic start_hw function + * and the generation start_hw function. + * Then performs revision-specific operations, if any. + **/ +s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_start_hw_82599"); + + ret_val = ixgbe_start_hw_generic(hw); + if (ret_val != IXGBE_SUCCESS) + goto out; + + ixgbe_start_hw_gen2(hw); + + /* We need to run link autotry after the driver loads */ + hw->mac.autotry_restart = true; + + if (ret_val == IXGBE_SUCCESS) + ret_val = ixgbe_verify_fw_version_82599(hw); +out: + return ret_val; +} + +/** + * ixgbe_identify_phy_82599 - Get physical layer module + * @hw: pointer to hardware structure + * + * Determines the physical layer module found on the current adapter. + * If PHY already detected, maintains current PHY type in hw struct, + * otherwise executes the PHY detection routine. + **/ +s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) +{ + s32 status; + + DEBUGFUNC("ixgbe_identify_phy_82599"); + + /* Detect PHY if not unknown - returns success if already detected. */ + status = ixgbe_identify_phy_generic(hw); + if (status != IXGBE_SUCCESS) { + /* 82599 10GBASE-T requires an external PHY */ + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) + return status; + else + status = ixgbe_identify_module_generic(hw); + } + + /* Set PHY type none if no PHY detected */ + if (hw->phy.type == ixgbe_phy_unknown) { + hw->phy.type = ixgbe_phy_none; + return IXGBE_SUCCESS; + } + + /* Return error if SFP module has been detected but is not supported */ + if (hw->phy.type == ixgbe_phy_sfp_unsupported) + return IXGBE_ERR_SFP_NOT_SUPPORTED; + + return status; +} + +/** + * ixgbe_get_supported_physical_layer_82599 - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u64 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) +{ + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK; + u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; + u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; + u16 ext_ability = 0; + + DEBUGFUNC("ixgbe_get_support_physical_layer_82599"); + + hw->phy.ops.identify(hw); + + switch (hw->phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_cu_unknown: + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + goto out; + default: + break; + } + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_AN: + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) { + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX | + IXGBE_PHYSICAL_LAYER_1000BASE_BX; + goto out; + } else + /* SFI mode so read SFP module */ + goto sfp_check; + break; + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_XAUI) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI; + goto out; + break; + case IXGBE_AUTOC_LMS_10G_SERIAL: + if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) { + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR; + goto out; + } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) + goto sfp_check; + break; + case IXGBE_AUTOC_LMS_KX4_KX_KR: + case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN: + if (autoc & IXGBE_AUTOC_KX_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + if (autoc & IXGBE_AUTOC_KR_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR; + goto out; + break; + default: + goto out; + break; + } + +sfp_check: + /* SFP check must be done last since DA modules are sometimes used to + * test KR mode - we need to id KR mode correctly before SFP module. + * Call identify_sfp because the pluggable module may have changed */ + physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw); +out: + return physical_layer; +} + +/** + * ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599 + * @hw: pointer to hardware structure + * @regval: register value to write to RXCTRL + * + * Enables the Rx DMA unit for 82599 + **/ +s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) +{ + + DEBUGFUNC("ixgbe_enable_rx_dma_82599"); + + /* + * Workaround for 82599 silicon errata when enabling the Rx datapath. + * If traffic is incoming before we enable the Rx unit, it could hang + * the Rx DMA unit. Therefore, make sure the security engine is + * completely disabled prior to enabling the Rx unit. + */ + + hw->mac.ops.disable_sec_rx_path(hw); + + if (regval & IXGBE_RXCTRL_RXEN) + ixgbe_enable_rx(hw); + else + ixgbe_disable_rx(hw); + + hw->mac.ops.enable_sec_rx_path(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_verify_fw_version_82599 - verify FW version for 82599 + * @hw: pointer to hardware structure + * + * Verifies that installed the firmware version is 0.6 or higher + * for SFI devices. All 82599 SFI devices should have version 0.6 or higher. + * + * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or + * if the FW version is not supported. + **/ +STATIC s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_EEPROM_VERSION; + u16 fw_offset, fw_ptp_cfg_offset; + u16 fw_version; + + DEBUGFUNC("ixgbe_verify_fw_version_82599"); + + /* firmware check is only necessary for SFI devices */ + if (hw->phy.media_type != ixgbe_media_type_fiber) { + status = IXGBE_SUCCESS; + goto fw_version_out; + } + + /* get the offset to the Firmware Module block */ + if (hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset)) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", IXGBE_FW_PTR); + return IXGBE_ERR_EEPROM_VERSION; + } + + if ((fw_offset == 0) || (fw_offset == 0xFFFF)) + goto fw_version_out; + + /* get the offset to the Pass Through Patch Configuration block */ + if (hw->eeprom.ops.read(hw, (fw_offset + + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR), + &fw_ptp_cfg_offset)) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", + fw_offset + + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR); + return IXGBE_ERR_EEPROM_VERSION; + } + + if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF)) + goto fw_version_out; + + /* get the firmware version */ + if (hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset + + IXGBE_FW_PATCH_VERSION_4), &fw_version)) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", + fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4); + return IXGBE_ERR_EEPROM_VERSION; + } + + if (fw_version > 0x5) + status = IXGBE_SUCCESS; + +fw_version_out: + return status; +} + +/** + * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state. + * @hw: pointer to hardware structure + * + * Returns true if the LESM FW module is present and enabled. Otherwise + * returns false. Smart Speed must be disabled if LESM FW module is enabled. + **/ +bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) +{ + bool lesm_enabled = false; + u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; + s32 status; + + DEBUGFUNC("ixgbe_verify_lesm_fw_enabled_82599"); + + /* get the offset to the Firmware Module block */ + status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset); + + if ((status != IXGBE_SUCCESS) || + (fw_offset == 0) || (fw_offset == 0xFFFF)) + goto out; + + /* get the offset to the LESM Parameters block */ + status = hw->eeprom.ops.read(hw, (fw_offset + + IXGBE_FW_LESM_PARAMETERS_PTR), + &fw_lesm_param_offset); + + if ((status != IXGBE_SUCCESS) || + (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF)) + goto out; + + /* get the LESM state word */ + status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset + + IXGBE_FW_LESM_STATE_1), + &fw_lesm_state); + + if ((status == IXGBE_SUCCESS) && + (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED)) + lesm_enabled = true; + +out: + return lesm_enabled; +} + +/** + * ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using + * fastest available method + * + * @hw: pointer to hardware structure + * @offset: offset of word in EEPROM to read + * @words: number of words + * @data: word(s) read from the EEPROM + * + * Retrieves 16 bit word(s) read from EEPROM + **/ +STATIC s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + s32 ret_val = IXGBE_ERR_CONFIG; + + DEBUGFUNC("ixgbe_read_eeprom_buffer_82599"); + + /* + * If EEPROM is detected and can be addressed using 14 bits, + * use EERD otherwise use bit bang + */ + if ((eeprom->type == ixgbe_eeprom_spi) && + (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR)) + ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words, + data); + else + ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset, + words, + data); + + return ret_val; +} + +/** + * ixgbe_read_eeprom_82599 - Read EEPROM word using + * fastest available method + * + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM + **/ +STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, + u16 offset, u16 *data) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + s32 ret_val = IXGBE_ERR_CONFIG; + + DEBUGFUNC("ixgbe_read_eeprom_82599"); + + /* + * If EEPROM is detected and can be addressed using 14 bits, + * use EERD otherwise use bit bang + */ + if ((eeprom->type == ixgbe_eeprom_spi) && + (offset <= IXGBE_EERD_MAX_ADDR)) + ret_val = ixgbe_read_eerd_generic(hw, offset, data); + else + ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data); + + return ret_val; +} + +/** + * ixgbe_reset_pipeline_82599 - perform pipeline reset + * + * @hw: pointer to hardware structure + * + * Reset pipeline by asserting Restart_AN together with LMS change to ensure + * full pipeline reset. This function assumes the SW/FW lock is held. + **/ +s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw) +{ + s32 ret_val; + u32 anlp1_reg = 0; + u32 i, autoc_reg, autoc2_reg; + + /* Enable link if disabled in NVM */ + autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + if (autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK) { + autoc2_reg &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg); + IXGBE_WRITE_FLUSH(hw); + } + + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */ + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, + autoc_reg ^ (0x4 << IXGBE_AUTOC_LMS_SHIFT)); + /* Wait for AN to leave state 0 */ + for (i = 0; i < 10; i++) { + msec_delay(4); + anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); + if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK) + break; + } + + if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) { + hw_dbg(hw, "auto negotiation not completed\n"); + ret_val = IXGBE_ERR_RESET_FAILED; + goto reset_pipeline_out; + } + + ret_val = IXGBE_SUCCESS; + +reset_pipeline_out: + /* Write AUTOC register with original LMS field and Restart_AN */ + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + IXGBE_WRITE_FLUSH(hw); + + return ret_val; +} + +/** + * ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: address to read from + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +STATIC s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + u32 esdp; + s32 status; + s32 timeout = 200; + + DEBUGFUNC("ixgbe_read_i2c_byte_82599"); + + if (hw->phy.qsfp_shared_i2c_bus == TRUE) { + /* Acquire I2C bus ownership. */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp |= IXGBE_ESDP_SDP0; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + + while (timeout) { + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (esdp & IXGBE_ESDP_SDP1) + break; + + msec_delay(5); + timeout--; + } + + if (!timeout) { + hw_dbg(hw, "Driver can't access resource," + " acquiring I2C bus timeout.\n"); + status = IXGBE_ERR_I2C; + goto release_i2c_access; + } + } + + status = ixgbe_read_i2c_byte_generic(hw, byte_offset, dev_addr, data); + +release_i2c_access: + + if (hw->phy.qsfp_shared_i2c_bus == TRUE) { + /* Release I2C bus ownership. */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp &= ~IXGBE_ESDP_SDP0; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + } + + return status; +} + +/** + * ixgbe_write_i2c_byte_82599 - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: address to read from + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +STATIC s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + u32 esdp; + s32 status; + s32 timeout = 200; + + DEBUGFUNC("ixgbe_write_i2c_byte_82599"); + + if (hw->phy.qsfp_shared_i2c_bus == TRUE) { + /* Acquire I2C bus ownership. */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp |= IXGBE_ESDP_SDP0; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + + while (timeout) { + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (esdp & IXGBE_ESDP_SDP1) + break; + + msec_delay(5); + timeout--; + } + + if (!timeout) { + hw_dbg(hw, "Driver can't access resource," + " acquiring I2C bus timeout.\n"); + status = IXGBE_ERR_I2C; + goto release_i2c_access; + } + } + + status = ixgbe_write_i2c_byte_generic(hw, byte_offset, dev_addr, data); + +release_i2c_access: + + if (hw->phy.qsfp_shared_i2c_bus == TRUE) { + /* Release I2C bus ownership. */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp &= ~IXGBE_ESDP_SDP0; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); + } + + return status; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.h new file mode 100644 index 0000000000..68ae5087cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_82599.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_82599_H_ +#define _IXGBE_82599_H_ + +s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *autoneg); +enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw); +void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw, + ixgbe_link_speed speed); +s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete); +s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw); +void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw); +s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw); +s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); +s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw); +s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw); +s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw); +s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval); +s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val); +s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 reg_val, bool locked); +#endif /* _IXGBE_82599_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.c new file mode 100644 index 0000000000..dffcecd47e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.c @@ -0,0 +1,1721 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_api.h" +#include "ixgbe_common.h" + +#define IXGBE_EMPTY_PARAM + +static const u32 ixgbe_mvals_base[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(IXGBE_EMPTY_PARAM) +}; + +static const u32 ixgbe_mvals_X540[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(_X540) +}; + +static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(_X550) +}; + +static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(_X550EM_x) +}; + +static const u32 ixgbe_mvals_X550EM_a[IXGBE_MVALS_IDX_LIMIT] = { + IXGBE_MVALS_INIT(_X550EM_a) +}; + +/** + * ixgbe_dcb_get_rtrup2tc - read rtrup2tc reg + * @hw: pointer to hardware structure + * @map: pointer to u8 arr for returning map + * + * Read the rtrup2tc HW register and resolve its content into map + **/ +void ixgbe_dcb_get_rtrup2tc(struct ixgbe_hw *hw, u8 *map) +{ + if (hw->mac.ops.get_rtrup2tc) + hw->mac.ops.get_rtrup2tc(hw, map); +} + +/** + * ixgbe_init_shared_code - Initialize the shared code + * @hw: pointer to hardware structure + * + * This will assign function pointers and assign the MAC type and PHY code. + * Does not touch the hardware. This function must be called prior to any + * other function in the shared code. The ixgbe_hw structure should be + * memset to 0 prior to calling this function. The following fields in + * hw structure should be filled in prior to calling this function: + * hw_addr, back, device_id, vendor_id, subsystem_device_id, + * subsystem_vendor_id, and revision_id + **/ +s32 ixgbe_init_shared_code(struct ixgbe_hw *hw) +{ + s32 status; + + DEBUGFUNC("ixgbe_init_shared_code"); + + /* + * Set the mac type + */ + ixgbe_set_mac_type(hw); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + status = ixgbe_init_ops_82598(hw); + break; + case ixgbe_mac_82599EB: + status = ixgbe_init_ops_82599(hw); + break; + case ixgbe_mac_X540: + status = ixgbe_init_ops_X540(hw); + break; + case ixgbe_mac_X550: + status = ixgbe_init_ops_X550(hw); + break; + case ixgbe_mac_X550EM_x: + status = ixgbe_init_ops_X550EM_x(hw); + break; + case ixgbe_mac_X550EM_a: + status = ixgbe_init_ops_X550EM_a(hw); + break; + case ixgbe_mac_E610: + status = ixgbe_init_ops_E610(hw); + break; + default: + status = IXGBE_ERR_DEVICE_NOT_SUPPORTED; + break; + } + hw->mac.max_link_up_time = IXGBE_LINK_UP_TIME; + + /* NVM Update features structure initialization */ + hw->nvmupd_features.major = IXGBE_NVMUPD_FEATURES_API_VER_MAJOR; + hw->nvmupd_features.minor = IXGBE_NVMUPD_FEATURES_API_VER_MINOR; + hw->nvmupd_features.size = sizeof(hw->nvmupd_features); + memset(hw->nvmupd_features.features, 0x0, + IXGBE_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN * + sizeof(*hw->nvmupd_features.features)); + + hw->nvmupd_features.features[0] = + IXGBE_NVMUPD_FEATURE_REGISTER_ACCESS_SUPPORT; + + return status; +} + +/** + * ixgbe_set_mac_type - Sets MAC type + * @hw: pointer to the HW structure + * + * This function sets the mac type of the adapter based on the + * vendor ID and device ID stored in the hw structure. + **/ +s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_set_mac_type\n"); + + if (hw->vendor_id != IXGBE_INTEL_VENDOR_ID) { + ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, + "Unsupported vendor id: %x", hw->vendor_id); + return IXGBE_ERR_DEVICE_NOT_SUPPORTED; + } + + hw->mvals = ixgbe_mvals_base; + + switch (hw->device_id) { + case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82598_BX: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AT: + case IXGBE_DEV_ID_82598AT2: + case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + case IXGBE_DEV_ID_82598_DA_DUAL_PORT: + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: + case IXGBE_DEV_ID_82598EB_XF_LR: + case IXGBE_DEV_ID_82598EB_SFP_LOM: + hw->mac.type = ixgbe_mac_82598EB; + break; + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_82599_XAUI_LOM: + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_82599_SFP: + case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: + case IXGBE_DEV_ID_82599_SFP_FCOE: + case IXGBE_DEV_ID_82599_SFP_EM: + case IXGBE_DEV_ID_82599_SFP_SF2: + case IXGBE_DEV_ID_82599_SFP_SF_QP: + case IXGBE_DEV_ID_82599_QSFP_SF_QP: + case IXGBE_DEV_ID_82599EN_SFP: + case IXGBE_DEV_ID_82599_CX4: + case IXGBE_DEV_ID_82599_T3_LOM: + hw->mac.type = ixgbe_mac_82599EB; + break; + case IXGBE_DEV_ID_X540T: + case IXGBE_DEV_ID_X540T1: + hw->mac.type = ixgbe_mac_X540; + hw->mvals = ixgbe_mvals_X540; + break; + case IXGBE_DEV_ID_X550T: + case IXGBE_DEV_ID_X550T1: + hw->mac.type = ixgbe_mac_X550; + hw->mvals = ixgbe_mvals_X550; + break; + case IXGBE_DEV_ID_X550EM_X_KX4: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_X_1G_T: + case IXGBE_DEV_ID_X550EM_X_SFP: + case IXGBE_DEV_ID_X550EM_X_XFI: + hw->mac.type = ixgbe_mac_X550EM_x; + hw->mvals = ixgbe_mvals_X550EM_x; + break; + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_QSFP: + case IXGBE_DEV_ID_X550EM_A_QSFP_N: + case IXGBE_DEV_ID_X550EM_A_SFP: + hw->mac.type = ixgbe_mac_X550EM_a; + hw->mvals = ixgbe_mvals_X550EM_a; + break; + case IXGBE_DEV_ID_E610_BACKPLANE: + case IXGBE_DEV_ID_E610_SFP: + case IXGBE_DEV_ID_E610_10G_T: + case IXGBE_DEV_ID_E610_2_5G_T: + case IXGBE_DEV_ID_E610_SGMII: + hw->mac.type = ixgbe_mac_E610; + hw->mvals = ixgbe_mvals_X550EM_a; + break; + default: + ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED; + ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, + "Unsupported device id: %x", + hw->device_id); + break; + } + + return ret_val; +} + +/** + * ixgbe_init_hw - Initialize the hardware + * @hw: pointer to hardware structure + * + * Initialize the hardware by resetting and then starting the hardware + **/ +s32 ixgbe_init_hw(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.init_hw, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_reset_hw - Performs a hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks and + * clears all interrupts, performs a PHY reset, and performs a MAC reset + **/ +s32 ixgbe_reset_hw(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.reset_hw, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_start_hw - Prepares hardware for Rx/Tx + * @hw: pointer to hardware structure + * + * Starts the hardware by filling the bus info structure and media type, + * clears all on chip counters, initializes receive address registers, + * multicast table, VLAN filter table, calls routine to setup link and + * flow control settings, and leaves transmit and receive units disabled + * and uninitialized. + **/ +s32 ixgbe_start_hw(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.start_hw, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_clear_hw_cntrs - Clear hardware counters + * @hw: pointer to hardware structure + * + * Clears all hardware statistics counters by reading them from the hardware + * Statistics counters are clear on read. + **/ +s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.clear_hw_cntrs, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_media_type - Get media type + * @hw: pointer to hardware structure + * + * Returns the media type (fiber, copper, backplane) + **/ +enum ixgbe_media_type ixgbe_get_media_type(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_media_type, (hw), + ixgbe_media_type_unknown); +} + +/** + * ixgbe_get_mac_addr - Get MAC address + * @hw: pointer to hardware structure + * @mac_addr: Adapter MAC address + * + * Reads the adapter's MAC address from the first Receive Address Register + * (RAR0) A reset of the adapter must have been performed prior to calling + * this function in order for the MAC address to have been loaded from the + * EEPROM into RAR0 + **/ +s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_mac_addr, + (hw, mac_addr), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_san_mac_addr - Get SAN MAC address + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Reads the SAN MAC address from the EEPROM, if it's available. This is + * per-port, so set_lan_id() must be called before reading the addresses. + **/ +s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_san_mac_addr, + (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_san_mac_addr - Write a SAN MAC address + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Writes A SAN MAC address to the EEPROM. + **/ +s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_san_mac_addr, + (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_device_caps - Get additional device capabilities + * @hw: pointer to hardware structure + * @device_caps: the EEPROM word for device capabilities + * + * Reads the extra device capabilities from the EEPROM + **/ +s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_device_caps, + (hw, device_caps), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_wwn_prefix - Get alternative WWNN/WWPN prefix from the EEPROM + * @hw: pointer to hardware structure + * @wwnn_prefix: the alternative WWNN prefix + * @wwpn_prefix: the alternative WWPN prefix + * + * This function will read the EEPROM from the alternative SAN MAC address + * block to check the support for the alternative WWNN/WWPN prefix support. + **/ +s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_wwn_prefix, + (hw, wwnn_prefix, wwpn_prefix), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_fcoe_boot_status - Get FCOE boot status from EEPROM + * @hw: pointer to hardware structure + * @bs: the fcoe boot status + * + * This function will read the FCOE boot status from the iSCSI FCOE block + **/ +s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_fcoe_boot_status, + (hw, bs), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_bus_info - Set PCI bus info + * @hw: pointer to hardware structure + * + * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure + **/ +s32 ixgbe_get_bus_info(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_bus_info, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_num_of_tx_queues - Get Tx queues + * @hw: pointer to hardware structure + * + * Returns the number of transmit queues for the given adapter. + **/ +u32 ixgbe_get_num_of_tx_queues(struct ixgbe_hw *hw) +{ + return hw->mac.max_tx_queues; +} + +/** + * ixgbe_get_num_of_rx_queues - Get Rx queues + * @hw: pointer to hardware structure + * + * Returns the number of receive queues for the given adapter. + **/ +u32 ixgbe_get_num_of_rx_queues(struct ixgbe_hw *hw) +{ + return hw->mac.max_rx_queues; +} + +/** + * ixgbe_stop_adapter - Disable Rx/Tx units + * @hw: pointer to hardware structure + * + * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, + * disables transmit and receive units. The adapter_stopped flag is used by + * the shared code and drivers to determine if the adapter is in a stopped + * state and should not touch the hardware. + **/ +s32 ixgbe_stop_adapter(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.stop_adapter, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_pba_string - Reads part number string from EEPROM + * @hw: pointer to hardware structure + * @pba_num: stores the part number string from the EEPROM + * @pba_num_size: part number string buffer length + * + * Reads the part number string from the EEPROM. + **/ +s32 ixgbe_read_pba_string(struct ixgbe_hw *hw, u8 *pba_num, u32 pba_num_size) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.read_pba_string, (hw, pba_num, + pba_num_size), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_identify_phy - Get PHY type + * @hw: pointer to hardware structure + * + * Determines the physical layer module found on the current adapter. + **/ +s32 ixgbe_identify_phy(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + + if (hw->phy.type == ixgbe_phy_unknown) { + status = ixgbe_call_func(hw, hw->phy.ops.identify, (hw), + IXGBE_NOT_IMPLEMENTED); + } + + return status; +} + +/** + * ixgbe_reset_phy - Perform a PHY reset + * @hw: pointer to hardware structure + **/ +s32 ixgbe_reset_phy(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + + if (hw->phy.type == ixgbe_phy_unknown) { + if (ixgbe_identify_phy(hw) != IXGBE_SUCCESS) + status = IXGBE_ERR_PHY; + } + + if (status == IXGBE_SUCCESS) { + status = ixgbe_call_func(hw, hw->phy.ops.reset, (hw), + IXGBE_NOT_IMPLEMENTED); + } + return status; +} + +/** + * ixgbe_get_phy_firmware_version - + * @hw: pointer to hardware structure + * @firmware_version: pointer to firmware version + **/ +s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, u16 *firmware_version) +{ + s32 status = IXGBE_SUCCESS; + + status = ixgbe_call_func(hw, hw->phy.ops.get_firmware_version, + (hw, firmware_version), + IXGBE_NOT_IMPLEMENTED); + return status; +} + +/** + * ixgbe_read_phy_reg - Read PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: type of device you want to communicate with + * @phy_data: Pointer to read data from PHY register + * + * Reads a value from a specified PHY register + **/ +s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data) +{ + if (hw->phy.id == 0) + ixgbe_identify_phy(hw); + + return ixgbe_call_func(hw, hw->phy.ops.read_reg, (hw, reg_addr, + device_type, phy_data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_phy_reg - Write PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: type of device you want to communicate with + * @phy_data: Data to write to the PHY register + * + * Writes a value to specified PHY register + **/ +s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data) +{ + if (hw->phy.id == 0) + ixgbe_identify_phy(hw); + + return ixgbe_call_func(hw, hw->phy.ops.write_reg, (hw, reg_addr, + device_type, phy_data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_setup_phy_link - Restart PHY autoneg + * @hw: pointer to hardware structure + * + * Restart autonegotiation and PHY and waits for completion. + **/ +s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->phy.ops.setup_link, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_setup_internal_phy - Configure integrated PHY + * @hw: pointer to hardware structure + * + * Reconfigure the integrated PHY in order to enable talk to the external PHY. + * Returns success if not implemented, since nothing needs to be done in this + * case. + */ +s32 ixgbe_setup_internal_phy(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->phy.ops.setup_internal_link, (hw), + IXGBE_SUCCESS); +} + +/** + * ixgbe_check_phy_link - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: link speed + * @link_up: true when link is up + * + * Reads a PHY register to determine if link is up and the current speed for + * the PHY. + **/ +s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up) +{ + return ixgbe_call_func(hw, hw->phy.ops.check_link, (hw, speed, + link_up), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_setup_phy_link_speed - Set auto advertise + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Sets the auto advertised capabilities + **/ +s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + return ixgbe_call_func(hw, hw->phy.ops.setup_link_speed, (hw, speed, + autoneg_wait_to_complete), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_phy_power - Control the phy power state + * @hw: pointer to hardware structure + * @on: true for on, false for off + */ +s32 ixgbe_set_phy_power(struct ixgbe_hw *hw, bool on) +{ + return ixgbe_call_func(hw, hw->phy.ops.set_phy_power, (hw, on), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_check_link - Get link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Reads the links register to determine if link is up and the current speed + **/ +s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + return ixgbe_call_func(hw, hw->mac.ops.check_link, (hw, speed, + link_up, link_up_wait_to_complete), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_disable_tx_laser - Disable Tx laser + * @hw: pointer to hardware structure + * + * If the driver needs to disable the laser on SFI optics. + **/ +void ixgbe_disable_tx_laser(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.disable_tx_laser) + hw->mac.ops.disable_tx_laser(hw); +} + +/** + * ixgbe_enable_tx_laser - Enable Tx laser + * @hw: pointer to hardware structure + * + * If the driver needs to enable the laser on SFI optics. + **/ +void ixgbe_enable_tx_laser(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.enable_tx_laser) + hw->mac.ops.enable_tx_laser(hw); +} + +/** + * ixgbe_flap_tx_laser - flap Tx laser to start autotry process + * @hw: pointer to hardware structure + * + * When the driver changes the link speeds that it can support then + * flap the tx laser to alert the link partner to start autotry + * process on its end. + **/ +void ixgbe_flap_tx_laser(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.flap_tx_laser) + hw->mac.ops.flap_tx_laser(hw); +} + +/** + * ixgbe_setup_link - Set link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Configures link settings. Restarts the link. + * Performs autonegotiation if needed. + **/ +s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw, speed, + autoneg_wait_to_complete), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_setup_mac_link - Set link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Configures link settings. Restarts the link. + * Performs autonegotiation if needed. + **/ +s32 ixgbe_setup_mac_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + return ixgbe_call_func(hw, hw->mac.ops.setup_mac_link, (hw, speed, + autoneg_wait_to_complete), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_link_capabilities - Returns link capabilities + * @hw: pointer to hardware structure + * @speed: link speed capabilities + * @autoneg: true when autoneg or autotry is enabled + * + * Determines the link capabilities of the current configuration. + **/ +s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *autoneg) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_link_capabilities, (hw, + speed, autoneg), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_led_on - Turn on LEDs + * @hw: pointer to hardware structure + * @index: led number to turn on + * + * Turns on the software controllable LEDs. + **/ +s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index) +{ + return ixgbe_call_func(hw, hw->mac.ops.led_on, (hw, index), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_led_off - Turn off LEDs + * @hw: pointer to hardware structure + * @index: led number to turn off + * + * Turns off the software controllable LEDs. + **/ +s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index) +{ + return ixgbe_call_func(hw, hw->mac.ops.led_off, (hw, index), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_blink_led_start - Blink LEDs + * @hw: pointer to hardware structure + * @index: led number to blink + * + * Blink LED based on index. + **/ +s32 ixgbe_blink_led_start(struct ixgbe_hw *hw, u32 index) +{ + return ixgbe_call_func(hw, hw->mac.ops.blink_led_start, (hw, index), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_blink_led_stop - Stop blinking LEDs + * @hw: pointer to hardware structure + * @index: led number to stop + * + * Stop blinking LED based on index. + **/ +s32 ixgbe_blink_led_stop(struct ixgbe_hw *hw, u32 index) +{ + return ixgbe_call_func(hw, hw->mac.ops.blink_led_stop, (hw, index), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_init_eeprom_params - Initialize EEPROM parameters + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. + **/ +s32 ixgbe_init_eeprom_params(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.init_params, (hw), + IXGBE_NOT_IMPLEMENTED); +} + + +/** + * ixgbe_write_eeprom - Write word to EEPROM + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be written to + * @data: 16 bit word to be written to the EEPROM + * + * Writes 16 bit value to EEPROM. If ixgbe_eeprom_update_checksum is not + * called after this function, the EEPROM will most likely contain an + * invalid checksum. + **/ +s32 ixgbe_write_eeprom(struct ixgbe_hw *hw, u16 offset, u16 data) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.write, (hw, offset, data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_eeprom_buffer - Write word(s) to EEPROM + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be written to + * @data: 16 bit word(s) to be written to the EEPROM + * @words: number of words + * + * Writes 16 bit word(s) to EEPROM. If ixgbe_eeprom_update_checksum is not + * called after this function, the EEPROM will most likely contain an + * invalid checksum. + **/ +s32 ixgbe_write_eeprom_buffer(struct ixgbe_hw *hw, u16 offset, u16 words, + u16 *data) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.write_buffer, + (hw, offset, words, data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_eeprom - Read word from EEPROM + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be read + * @data: read 16 bit value from EEPROM + * + * Reads 16 bit value from EEPROM + **/ +s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.read, (hw, offset, data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_eeprom_buffer - Read word(s) from EEPROM + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be read + * @data: read 16 bit word(s) from EEPROM + * @words: number of words + * + * Reads 16 bit word(s) from EEPROM + **/ +s32 ixgbe_read_eeprom_buffer(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.read_buffer, + (hw, offset, words, data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_validate_eeprom_checksum - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum + **/ +s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.validate_checksum, + (hw, checksum_val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_update_eeprom_checksum - Updates the EEPROM checksum + * @hw: pointer to hardware structure + **/ +s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->eeprom.ops.update_checksum, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_insert_mac_addr - Find a RAR for this mac address + * @hw: pointer to hardware structure + * @addr: Address to put into receive address register + * @vmdq: VMDq pool to assign + * + * Puts an ethernet address into a receive address register, or + * finds the rar that it is aleady in; adds to the pool list + **/ +s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) +{ + return ixgbe_call_func(hw, hw->mac.ops.insert_mac_addr, + (hw, addr, vmdq), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_rar - Set Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * @addr: Address to put into receive address register + * @vmdq: VMDq "set" + * @enable_addr: set flag that address is active + * + * Puts an ethernet address into a receive address register. + **/ +s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_rar, (hw, index, addr, vmdq, + enable_addr), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_clear_rar - Clear Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * + * Puts an ethernet address into a receive address register. + **/ +s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index) +{ + return ixgbe_call_func(hw, hw->mac.ops.clear_rar, (hw, index), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_vmdq - Associate a VMDq index with a receive address + * @hw: pointer to hardware structure + * @rar: receive address register index to associate with VMDq index + * @vmdq: VMDq set or pool index + **/ +s32 ixgbe_set_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_vmdq, (hw, rar, vmdq), + IXGBE_NOT_IMPLEMENTED); + +} + +/** + * ixgbe_set_vmdq_san_mac - Associate VMDq index 127 with a receive address + * @hw: pointer to hardware structure + * @vmdq: VMDq default pool index + **/ +s32 ixgbe_set_vmdq_san_mac(struct ixgbe_hw *hw, u32 vmdq) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_vmdq_san_mac, + (hw, vmdq), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_clear_vmdq - Disassociate a VMDq index from a receive address + * @hw: pointer to hardware structure + * @rar: receive address register index to disassociate with VMDq index + * @vmdq: VMDq set or pool index + **/ +s32 ixgbe_clear_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + return ixgbe_call_func(hw, hw->mac.ops.clear_vmdq, (hw, rar, vmdq), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_init_rx_addrs - Initializes receive address filters. + * @hw: pointer to hardware structure + * + * Places the MAC address in receive address register 0 and clears the rest + * of the receive address registers. Clears the multicast table. Assumes + * the receiver is in reset when the routine is called. + **/ +s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.init_rx_addrs, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_num_rx_addrs - Returns the number of RAR entries. + * @hw: pointer to hardware structure + **/ +u32 ixgbe_get_num_rx_addrs(struct ixgbe_hw *hw) +{ + return hw->mac.num_rar_entries; +} + +/** + * ixgbe_update_uc_addr_list - Updates the MAC's list of secondary addresses + * @hw: pointer to hardware structure + * @addr_list: the list of new multicast addresses + * @addr_count: number of addresses + * @func: iterator function to walk the multicast address list + * + * The given list replaces any existing list. Clears the secondary addrs from + * receive address registers. Uses unused receive address registers for the + * first secondary addresses, and falls back to promiscuous mode as needed. + **/ +s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr func) +{ + return ixgbe_call_func(hw, hw->mac.ops.update_uc_addr_list, (hw, + addr_list, addr_count, func), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_update_mc_addr_list - Updates the MAC's list of multicast addresses + * @hw: pointer to hardware structure + * @mc_addr_list: the list of new multicast addresses + * @mc_addr_count: number of addresses + * @func: iterator function to walk the multicast address list + * @clear: flag, when set clears the table beforehand + * + * The given list replaces any existing list. Clears the MC addrs from receive + * address registers and the multicast table. Uses unused receive address + * registers for the first multicast addresses, and hashes the rest into the + * multicast table. + **/ +s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, ixgbe_mc_addr_itr func, + bool clear) +{ + return ixgbe_call_func(hw, hw->mac.ops.update_mc_addr_list, (hw, + mc_addr_list, mc_addr_count, func, clear), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_enable_mc - Enable multicast address in RAR + * @hw: pointer to hardware structure + * + * Enables multicast address in RAR and the use of the multicast hash table. + **/ +s32 ixgbe_enable_mc(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.enable_mc, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_disable_mc - Disable multicast address in RAR + * @hw: pointer to hardware structure + * + * Disables multicast address in RAR and the use of the multicast hash table. + **/ +s32 ixgbe_disable_mc(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.disable_mc, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_clear_vfta - Clear VLAN filter table + * @hw: pointer to hardware structure + * + * Clears the VLAN filer table, and the VMDq index associated with the filter + **/ +s32 ixgbe_clear_vfta(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.clear_vfta, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_vfta - Set VLAN filter table + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN + * @vlvf_bypass: boolean flag indicating updating the default pool is okay + * + * Turn on/off specified VLAN in the VLAN filter table. + **/ +s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on, + bool vlvf_bypass) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_vfta, (hw, vlan, vind, + vlan_on, vlvf_bypass), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_vlvf - Set VLAN Pool Filter + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN in VLVF + * @vfta_delta: pointer to the difference between the current value of VFTA + * and the desired value + * @vfta: the desired value of the VFTA + * @vlvf_bypass: boolean flag indicating updating the default pool is okay + * + * Turn on/off specified bit in VLVF table. + **/ +s32 ixgbe_set_vlvf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on, + u32 *vfta_delta, u32 vfta, bool vlvf_bypass) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_vlvf, (hw, vlan, vind, + vlan_on, vfta_delta, vfta, vlvf_bypass), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_toggle_txdctl - Toggle VF's queues + * @hw: pointer to hardware structure + * @vind: VMDq pool index + * + * Enable and disable each queue in VF. + */ +s32 ixgbe_toggle_txdctl(struct ixgbe_hw *hw, u32 vind) +{ + return ixgbe_call_func(hw, hw->mac.ops.toggle_txdctl, (hw, + vind), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_fc_enable - Enable flow control + * @hw: pointer to hardware structure + * + * Configures the flow control settings based on SW configuration. + **/ +s32 ixgbe_fc_enable(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.fc_enable, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_setup_fc - Set up flow control + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + **/ +s32 ixgbe_setup_fc(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.setup_fc, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_fw_drv_ver - Try to send the driver version number FW + * @hw: pointer to hardware structure + * @maj: driver major number to be sent to firmware + * @min: driver minor number to be sent to firmware + * @build: driver build number to be sent to firmware + * @ver: driver version number to be sent to firmware + * @len: length of driver_ver string + * @driver_ver: driver string + **/ +s32 ixgbe_set_fw_drv_ver(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, + u8 ver, u16 len, char *driver_ver) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_fw_drv_ver, (hw, maj, min, + build, ver, len, driver_ver), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_fw_tsam_mode - Returns information whether TSAM is enabled + * @hw: pointer to hardware structure + * + * Checks Thermal Sensor Autonomous Mode by reading the value of the + * dedicated register. + * Returns True if TSAM is enabled, False if TSAM is disabled. + */ +bool ixgbe_get_fw_tsam_mode(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.get_fw_tsam_mode) + return hw->mac.ops.get_fw_tsam_mode(hw); + return false; +} + +/** + * ixgbe_get_thermal_sensor_data - Gathers thermal sensor data + * @hw: pointer to hardware structure + * + * Updates the temperatures in mac.thermal_sensor_data + **/ +s32 ixgbe_get_thermal_sensor_data(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_thermal_sensor_data, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds + * @hw: pointer to hardware structure + * + * Inits the thermal sensor thresholds according to the NVM map + **/ +s32 ixgbe_init_thermal_sensor_thresh(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.init_thermal_sensor_thresh, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_dmac_config - Configure DMA Coalescing registers. + * @hw: pointer to hardware structure + * + * Configure DMA coalescing. If enabling dmac, dmac is activated. + * When disabling dmac, dmac enable dmac bit is cleared. + **/ +s32 ixgbe_dmac_config(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.dmac_config, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_dmac_update_tcs - Configure DMA Coalescing registers. + * @hw: pointer to hardware structure + * + * Disables dmac, updates per TC settings, and then enable dmac. + **/ +s32 ixgbe_dmac_update_tcs(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.dmac_update_tcs, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_dmac_config_tcs - Configure DMA Coalescing registers. + * @hw: pointer to hardware structure + * + * Configure DMA coalescing threshold per TC and set high priority bit for + * FCOE TC. The dmac enable bit must be cleared before configuring. + **/ +s32 ixgbe_dmac_config_tcs(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.dmac_config_tcs, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_setup_eee - Enable/disable EEE support + * @hw: pointer to the HW structure + * @enable_eee: boolean flag to enable EEE + * + * Enable/disable EEE based on enable_ee flag. + * Auto-negotiation must be started after BASE-T EEE bits in PHY register 7.3C + * are modified. + * + **/ +s32 ixgbe_setup_eee(struct ixgbe_hw *hw, bool enable_eee) +{ + return ixgbe_call_func(hw, hw->mac.ops.setup_eee, (hw, enable_eee), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_source_address_pruning - Enable/Disable source address pruning + * @hw: pointer to hardware structure + * @enable: enable or disable source address pruning + * @pool: Rx pool - Rx pool to toggle source address pruning + **/ +void ixgbe_set_source_address_pruning(struct ixgbe_hw *hw, bool enable, + unsigned int pool) +{ + if (hw->mac.ops.set_source_address_pruning) + hw->mac.ops.set_source_address_pruning(hw, enable, pool); +} + +/** + * ixgbe_set_ethertype_anti_spoofing - Enable/Disable Ethertype anti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for Ethertype anti-spoofing + * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing + * + **/ +void ixgbe_set_ethertype_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) +{ + if (hw->mac.ops.set_ethertype_anti_spoofing) + hw->mac.ops.set_ethertype_anti_spoofing(hw, enable, vf); +} + +/** + * ixgbe_read_iosf_sb_reg - Read 32 bit PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: type of device you want to communicate with + * @phy_data: Pointer to read data from PHY register + * + * Reads a value from a specified PHY register + **/ +s32 ixgbe_read_iosf_sb_reg(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *phy_data) +{ + return ixgbe_call_func(hw, hw->mac.ops.read_iosf_sb_reg, (hw, reg_addr, + device_type, phy_data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_iosf_sb_reg - Write 32 bit register through IOSF Sideband + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: type of device you want to communicate with + * @phy_data: Data to write to the PHY register + * + * Writes a value to specified PHY register + **/ +s32 ixgbe_write_iosf_sb_reg(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 phy_data) +{ + return ixgbe_call_func(hw, hw->mac.ops.write_iosf_sb_reg, (hw, reg_addr, + device_type, phy_data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_disable_mdd - Disable malicious driver detection + * @hw: pointer to hardware structure + * + **/ +void ixgbe_disable_mdd(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.disable_mdd) + hw->mac.ops.disable_mdd(hw); +} + +/** + * ixgbe_enable_mdd - Enable malicious driver detection + * @hw: pointer to hardware structure + * + **/ +void ixgbe_enable_mdd(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.enable_mdd) + hw->mac.ops.enable_mdd(hw); +} + +/** + * ixgbe_mdd_event - Handle malicious driver detection event + * @hw: pointer to hardware structure + * @vf_bitmap: vf bitmap of malicious vfs + * + **/ +void ixgbe_mdd_event(struct ixgbe_hw *hw, u32 *vf_bitmap) +{ + if (hw->mac.ops.mdd_event) + hw->mac.ops.mdd_event(hw, vf_bitmap); +} + +/** + * ixgbe_restore_mdd_vf - Restore VF that was disabled during malicious driver + * detection event + * @hw: pointer to hardware structure + * @vf: vf index + * + **/ +void ixgbe_restore_mdd_vf(struct ixgbe_hw *hw, u32 vf) +{ + if (hw->mac.ops.restore_mdd_vf) + hw->mac.ops.restore_mdd_vf(hw, vf); +} + +/** + * ixgbe_fw_recovery_mode - Check if in FW NVM recovery mode + * @hw: pointer to hardware structure + * + **/ +bool ixgbe_fw_recovery_mode(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.fw_recovery_mode) + return hw->mac.ops.fw_recovery_mode(hw); + return false; +} + +/** + * ixgbe_fw_rollback_mode - Check if in FW NVM rollback mode + * @hw: pointer to hardware structure + * + * Return: true if the FW NVM is in rollback mode, otherwise false. + */ +bool ixgbe_fw_rollback_mode(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.fw_rollback_mode) + return hw->mac.ops.fw_rollback_mode(hw); + return false; +} + +/** + * ixgbe_enter_lplu - Transition to low power states + * @hw: pointer to hardware structure + * + * Configures Low Power Link Up on transition to low power states + * (from D0 to non-D0). + **/ +s32 ixgbe_enter_lplu(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->phy.ops.enter_lplu, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_handle_lasi - Handle external Base T PHY interrupt + * @hw: pointer to hardware structure + * + * Handle external Base T PHY interrupt. If high temperature + * failure alarm then return error, else if link status change + * then setup internal/external PHY link + * + * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature + * failure alarm, else return PHY access status. + */ +s32 ixgbe_handle_lasi(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->phy.ops.handle_lasi, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_analog_reg8 - Reads 8 bit analog register + * @hw: pointer to hardware structure + * @reg: analog register to read + * @val: read value + * + * Performs write operation to analog register specified. + **/ +s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val) +{ + return ixgbe_call_func(hw, hw->mac.ops.read_analog_reg8, (hw, reg, + val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_analog_reg8 - Writes 8 bit analog register + * @hw: pointer to hardware structure + * @reg: analog register to write + * @val: value to write + * + * Performs write operation to Atlas analog register specified. + **/ +s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val) +{ + return ixgbe_call_func(hw, hw->mac.ops.write_analog_reg8, (hw, reg, + val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_init_uta_tables - Initializes Unicast Table Arrays. + * @hw: pointer to hardware structure + * + * Initializes the Unicast Table Arrays to zero on device load. This + * is part of the Rx init addr execution path. + **/ +s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.init_uta_tables, (hw), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_i2c_byte - Reads 8 bit word over I2C at specified device address + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: I2C bus address to read from + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 *data) +{ + return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte, (hw, byte_offset, + dev_addr, data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_i2c_byte_unlocked - Reads 8 bit word via I2C from device address + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: I2C bus address to read from + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte_unlocked, + (hw, byte_offset, dev_addr, data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_link - Perform read operation on link device + * @hw: pointer to the hardware structure + * @addr: bus address to read from + * @reg: device register to read from + * @val: pointer to location to receive read value + * + * Returns an error code on error. + */ +s32 ixgbe_read_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val) +{ + return ixgbe_call_func(hw, hw->link.ops.read_link, (hw, addr, + reg, val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_link_unlocked - Perform read operation on link device + * @hw: pointer to the hardware structure + * @addr: bus address to read from + * @reg: device register to read from + * @val: pointer to location to receive read value + * + * Returns an error code on error. + **/ +s32 ixgbe_read_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val) +{ + return ixgbe_call_func(hw, hw->link.ops.read_link_unlocked, + (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_i2c_byte - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: I2C bus address to write to + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface + * at a specified device address. + **/ +s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 data) +{ + return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte, (hw, byte_offset, + dev_addr, data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_i2c_byte_unlocked - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: I2C bus address to write to + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface + * at a specified device address. + **/ +s32 ixgbe_write_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte_unlocked, + (hw, byte_offset, dev_addr, data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_link - Perform write operation on link device + * @hw: pointer to the hardware structure + * @addr: bus address to write to + * @reg: device register to write to + * @val: value to write + * + * Returns an error code on error. + */ +s32 ixgbe_write_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val) +{ + return ixgbe_call_func(hw, hw->link.ops.write_link, + (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_link_unlocked - Perform write operation on link device + * @hw: pointer to the hardware structure + * @addr: bus address to write to + * @reg: device register to write to + * @val: value to write + * + * Returns an error code on error. + **/ +s32 ixgbe_write_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val) +{ + return ixgbe_call_func(hw, hw->link.ops.write_link_unlocked, + (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to write + * @eeprom_data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, + u8 byte_offset, u8 eeprom_data) +{ + return ixgbe_call_func(hw, hw->phy.ops.write_i2c_eeprom, + (hw, byte_offset, eeprom_data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to read + * @eeprom_data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data) +{ + return ixgbe_call_func(hw, hw->phy.ops.read_i2c_eeprom, + (hw, byte_offset, eeprom_data), + IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_supported_physical_layer - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u64 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_supported_physical_layer, + (hw), IXGBE_PHYSICAL_LAYER_UNKNOWN); +} + +/** + * ixgbe_enable_rx_dma - Enables Rx DMA unit, dependent on device specifics + * @hw: pointer to hardware structure + * @regval: bitfield to write to the Rx DMA register + * + * Enables the Rx DMA unit of the device. + **/ +s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval) +{ + return ixgbe_call_func(hw, hw->mac.ops.enable_rx_dma, + (hw, regval), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_disable_sec_rx_path - Stops the receive data path + * @hw: pointer to hardware structure + * + * Stops the receive data path. + **/ +s32 ixgbe_disable_sec_rx_path(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.disable_sec_rx_path, + (hw), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_enable_sec_rx_path - Enables the receive data path + * @hw: pointer to hardware structure + * + * Enables the receive data path. + **/ +s32 ixgbe_enable_sec_rx_path(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.enable_sec_rx_path, + (hw), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_acquire_swfw_semaphore - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore through SW_FW_SYNC register for the specified + * function (CSR, PHY0, PHY1, EEPROM, Flash) + **/ +s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u32 mask) +{ + return ixgbe_call_func(hw, hw->mac.ops.acquire_swfw_sync, + (hw, mask), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_release_swfw_semaphore - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore through SW_FW_SYNC register for the specified + * function (CSR, PHY0, PHY1, EEPROM, Flash) + **/ +void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask) +{ + if (hw->mac.ops.release_swfw_sync) + hw->mac.ops.release_swfw_sync(hw, mask); +} + +/** + * ixgbe_init_swfw_semaphore - Clean up SWFW semaphore + * @hw: pointer to hardware structure + * + * Attempts to acquire the SWFW semaphore through SW_FW_SYNC register. + * Regardless of whether is succeeds or not it then release the semaphore. + * This is function is called to recover from catastrophic failures that + * may have left the semaphore locked. + **/ +void ixgbe_init_swfw_semaphore(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.init_swfw_sync) + hw->mac.ops.init_swfw_sync(hw); +} + +void ixgbe_disable_rx(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.disable_rx) + hw->mac.ops.disable_rx(hw); +} + +void ixgbe_enable_rx(struct ixgbe_hw *hw) +{ + if (hw->mac.ops.enable_rx) + hw->mac.ops.enable_rx(hw); +} + +/** + * ixgbe_set_rate_select_speed - Set module link speed + * @hw: pointer to hardware structure + * @speed: link speed to set + * + * Set module link speed via the rate select. + */ +void ixgbe_set_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed) +{ + if (hw->mac.ops.set_rate_select_speed) + hw->mac.ops.set_rate_select_speed(hw, speed); +} + +/** + * ixgbe_get_fw_version - get FW version + * @hw: pointer to hardware structure + * + * Get the current FW version. + * + * Return: the exit code of the operation or IXGBE_NOT_IMPLEMENTED + * if the function is not implemented. + */ +s32 ixgbe_get_fw_version(struct ixgbe_hw *hw) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_fw_version, + (hw), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_nvm_ver - get NVM version + * @hw: pointer to hardware structure + * @nvm: pointer to NVM info structure + * + * Get the current NVM version. + * + * Return: the exit code of the operation or IXGBE_NOT_IMPLEMENTED + * if the function is not implemented. + */ +s32 ixgbe_get_nvm_ver(struct ixgbe_hw* hw, struct ixgbe_nvm_info *nvm) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_nvm_version, + (hw, nvm), IXGBE_NOT_IMPLEMENTED); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.h new file mode 100644 index 0000000000..6e92eff8ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_api.h @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_API_H_ +#define _IXGBE_API_H_ + +#include "ixgbe_type.h" + +void ixgbe_dcb_get_rtrup2tc(struct ixgbe_hw *hw, u8 *map); + +s32 ixgbe_init_shared_code(struct ixgbe_hw *hw); + +extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_E610(struct ixgbe_hw *hw); + +s32 ixgbe_set_mac_type(struct ixgbe_hw *hw); +s32 ixgbe_init_hw(struct ixgbe_hw *hw); +s32 ixgbe_reset_hw(struct ixgbe_hw *hw); +s32 ixgbe_start_hw(struct ixgbe_hw *hw); +s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw); +enum ixgbe_media_type ixgbe_get_media_type(struct ixgbe_hw *hw); +s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr); +s32 ixgbe_get_bus_info(struct ixgbe_hw *hw); +u32 ixgbe_get_num_of_tx_queues(struct ixgbe_hw *hw); +u32 ixgbe_get_num_of_rx_queues(struct ixgbe_hw *hw); +s32 ixgbe_stop_adapter(struct ixgbe_hw *hw); +s32 ixgbe_read_pba_string(struct ixgbe_hw *hw, u8 *pba_num, u32 pba_num_size); + +s32 ixgbe_identify_phy(struct ixgbe_hw *hw); +s32 ixgbe_reset_phy(struct ixgbe_hw *hw); +s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data); +s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data); + +s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw); +s32 ixgbe_setup_internal_phy(struct ixgbe_hw *hw); +s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *link_up); +s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_set_phy_power(struct ixgbe_hw *, bool on); +void ixgbe_disable_tx_laser(struct ixgbe_hw *hw); +void ixgbe_enable_tx_laser(struct ixgbe_hw *hw); +void ixgbe_flap_tx_laser(struct ixgbe_hw *hw); +s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_setup_mac_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); +s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *autoneg); +s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_blink_led_start(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_blink_led_stop(struct ixgbe_hw *hw, u32 index); + +s32 ixgbe_init_eeprom_params(struct ixgbe_hw *hw); +s32 ixgbe_write_eeprom(struct ixgbe_hw *hw, u16 offset, u16 data); +s32 ixgbe_write_eeprom_buffer(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_eeprom_buffer(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); + +s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val); +s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw); + +s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); +s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr); +s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_set_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_set_vmdq_san_mac(struct ixgbe_hw *hw, u32 vmdq); +s32 ixgbe_clear_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw); +u32 ixgbe_get_num_rx_addrs(struct ixgbe_hw *hw); +s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr func); +s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, ixgbe_mc_addr_itr func, + bool clear); +void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr_list, u32 vmdq); +s32 ixgbe_enable_mc(struct ixgbe_hw *hw); +s32 ixgbe_disable_mc(struct ixgbe_hw *hw); +s32 ixgbe_clear_vfta(struct ixgbe_hw *hw); +s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, + u32 vind, bool vlan_on, bool vlvf_bypass); +s32 ixgbe_set_vlvf(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, u32 *vfta_delta, u32 vfta, + bool vlvf_bypass); +s32 ixgbe_toggle_txdctl(struct ixgbe_hw *hw, u32 vind); +s32 ixgbe_fc_enable(struct ixgbe_hw *hw); +s32 ixgbe_setup_fc(struct ixgbe_hw *hw); +s32 ixgbe_set_fw_drv_ver(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, + u8 ver, u16 len, char *driver_ver); +bool ixgbe_get_fw_tsam_mode(struct ixgbe_hw *hw); +s32 ixgbe_get_thermal_sensor_data(struct ixgbe_hw *hw); +s32 ixgbe_init_thermal_sensor_thresh(struct ixgbe_hw *hw); +void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr); +s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, + u16 *firmware_version); +s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val); +s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw); +s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data); +u64 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw); +s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval); +s32 ixgbe_disable_sec_rx_path(struct ixgbe_hw *hw); +s32 ixgbe_enable_sec_rx_path(struct ixgbe_hw *hw); +s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); +s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl); +s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl, + bool cloud_mode); +void ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common, + u8 queue); +s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input_mask, bool cloud_mode); +s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id, u8 queue, bool cloud_mode); +s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id); +s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + union ixgbe_atr_input *mask, + u16 soft_id, + u8 queue, + bool cloud_mode); +void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, + union ixgbe_atr_input *mask); +u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common); +bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); +s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 *data); +s32 ixgbe_read_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data); +s32 ixgbe_read_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val); +s32 ixgbe_read_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val); +s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 data); +void ixgbe_set_fdir_drop_queue_82599(struct ixgbe_hw *hw, u8 dropqueue); +s32 ixgbe_write_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data); +s32 ixgbe_write_link(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val); +s32 ixgbe_write_link_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val); +s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data); +s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); +s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); +s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps); +s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask); +void ixgbe_init_swfw_semaphore(struct ixgbe_hw *hw); +s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix); +s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs); +s32 ixgbe_dmac_config(struct ixgbe_hw *hw); +s32 ixgbe_dmac_update_tcs(struct ixgbe_hw *hw); +s32 ixgbe_dmac_config_tcs(struct ixgbe_hw *hw); +s32 ixgbe_setup_eee(struct ixgbe_hw *hw, bool enable_eee); +void ixgbe_set_source_address_pruning(struct ixgbe_hw *hw, bool enable, + unsigned int vf); +void ixgbe_set_ethertype_anti_spoofing(struct ixgbe_hw *hw, bool enable, + int vf); +s32 ixgbe_read_iosf_sb_reg(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *phy_data); +s32 ixgbe_write_iosf_sb_reg(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 phy_data); +void ixgbe_disable_mdd(struct ixgbe_hw *hw); +void ixgbe_enable_mdd(struct ixgbe_hw *hw); +void ixgbe_mdd_event(struct ixgbe_hw *hw, u32 *vf_bitmap); +void ixgbe_restore_mdd_vf(struct ixgbe_hw *hw, u32 vf); +bool ixgbe_fw_recovery_mode(struct ixgbe_hw *hw); +bool ixgbe_fw_rollback_mode(struct ixgbe_hw *hw); +s32 ixgbe_enter_lplu(struct ixgbe_hw *hw); +s32 ixgbe_handle_lasi(struct ixgbe_hw *hw); +void ixgbe_set_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed); +void ixgbe_disable_rx(struct ixgbe_hw *hw); +void ixgbe_enable_rx(struct ixgbe_hw *hw); +s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); +s32 ixgbe_get_fw_version(struct ixgbe_hw *hw); +s32 ixgbe_get_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm); +#endif /* _IXGBE_API_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.c new file mode 100644 index 0000000000..33918d20be --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.c @@ -0,0 +1,5239 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_common.h" +#include "ixgbe_phy.h" +#include "ixgbe_dcb.h" +#include "ixgbe_dcb_82599.h" +#include "ixgbe_api.h" + +STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); +STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); +STATIC void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); +STATIC s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw); +STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw); +STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, + u16 count); +STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); +STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); +STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); +STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw); + +STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); +STATIC s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, + u16 *san_mac_offset); +STATIC s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +STATIC s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +STATIC s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw, + u16 offset); + +/** + * ixgbe_init_ops_generic - Inits function ptrs + * @hw: pointer to the hardware structure + * + * Initialize the function pointers. + **/ +s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + struct ixgbe_mac_info *mac = &hw->mac; + u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + DEBUGFUNC("ixgbe_init_ops_generic"); + + /* EEPROM */ + eeprom->ops.init_params = ixgbe_init_eeprom_params_generic; + /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ + if (eec & IXGBE_EEC_PRES) { + eeprom->ops.read = ixgbe_read_eerd_generic; + eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_generic; + } else { + eeprom->ops.read = ixgbe_read_eeprom_bit_bang_generic; + eeprom->ops.read_buffer = + ixgbe_read_eeprom_buffer_bit_bang_generic; + } + eeprom->ops.write = ixgbe_write_eeprom_generic; + eeprom->ops.write_buffer = ixgbe_write_eeprom_buffer_bit_bang_generic; + eeprom->ops.validate_checksum = + ixgbe_validate_eeprom_checksum_generic; + eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_generic; + eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_generic; + eeprom->ops.read_pba_string = ixgbe_read_pba_string_generic; + + /* MAC */ + mac->ops.init_hw = ixgbe_init_hw_generic; + mac->ops.reset_hw = NULL; + mac->ops.start_hw = ixgbe_start_hw_generic; + mac->ops.clear_hw_cntrs = ixgbe_clear_hw_cntrs_generic; + mac->ops.get_media_type = NULL; + mac->ops.get_supported_physical_layer = NULL; + mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_generic; + mac->ops.get_mac_addr = ixgbe_get_mac_addr_generic; + mac->ops.stop_adapter = ixgbe_stop_adapter_generic; + mac->ops.get_bus_info = ixgbe_get_bus_info_generic; + mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie; + mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync; + mac->ops.release_swfw_sync = ixgbe_release_swfw_sync; + mac->ops.prot_autoc_read = prot_autoc_read_generic; + mac->ops.prot_autoc_write = prot_autoc_write_generic; + + /* LEDs */ + mac->ops.led_on = ixgbe_led_on_generic; + mac->ops.led_off = ixgbe_led_off_generic; + mac->ops.blink_led_start = ixgbe_blink_led_start_generic; + mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic; + mac->ops.init_led_link_act = ixgbe_init_led_link_act_generic; + + /* RAR, Multicast, VLAN */ + mac->ops.set_rar = ixgbe_set_rar_generic; + mac->ops.clear_rar = ixgbe_clear_rar_generic; + mac->ops.insert_mac_addr = NULL; + mac->ops.set_vmdq = NULL; + mac->ops.clear_vmdq = NULL; + mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic; + mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic; + mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic; + mac->ops.enable_mc = ixgbe_enable_mc_generic; + mac->ops.disable_mc = ixgbe_disable_mc_generic; + mac->ops.clear_vfta = NULL; + mac->ops.set_vfta = NULL; + mac->ops.set_vlvf = NULL; + mac->ops.init_uta_tables = NULL; + mac->ops.enable_rx = ixgbe_enable_rx_generic; + mac->ops.disable_rx = ixgbe_disable_rx_generic; + mac->ops.toggle_txdctl = ixgbe_toggle_txdctl_generic; + + /* Flow Control */ + mac->ops.fc_enable = ixgbe_fc_enable_generic; + mac->ops.setup_fc = ixgbe_setup_fc_generic; + mac->ops.fc_autoneg = ixgbe_fc_autoneg; + + /* Link */ + mac->ops.get_link_capabilities = NULL; + mac->ops.setup_link = NULL; + mac->ops.check_link = NULL; + mac->ops.dmac_config = NULL; + mac->ops.dmac_update_tcs = NULL; + mac->ops.dmac_config_tcs = NULL; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_device_supports_autoneg_fc - Check if device supports autonegotiation + * of flow control + * @hw: pointer to hardware structure + * + * This function returns true if the device supports flow control + * autonegotiation, and false if it does not. + * + **/ +bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) +{ + bool supported = false; + ixgbe_link_speed speed; + bool link_up; + + DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); + + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber_qsfp: + case ixgbe_media_type_fiber: + /* flow control autoneg block list */ + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_SFP: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_QSFP: + case IXGBE_DEV_ID_X550EM_A_QSFP_N: + case IXGBE_DEV_ID_E610_SFP: + supported = false; + break; + default: + hw->mac.ops.check_link(hw, &speed, &link_up, false); + /* if link is down, assume supported */ + if (link_up) + supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? + true : false; + else + supported = true; + } + + break; + case ixgbe_media_type_backplane: + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI) + supported = false; + else + supported = true; + break; + case ixgbe_media_type_copper: + /* only some copper devices support flow control autoneg */ + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: + case IXGBE_DEV_ID_X540T: + case IXGBE_DEV_ID_X540T1: + case IXGBE_DEV_ID_X550T: + case IXGBE_DEV_ID_X550T1: + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + case IXGBE_DEV_ID_E610_10G_T: + case IXGBE_DEV_ID_E610_2_5G_T: + supported = true; + break; + default: + supported = false; + } + default: + break; + } + + return supported; +} + +/** + * ixgbe_setup_fc_generic - Set up flow control + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + **/ +s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + u32 reg = 0, reg_bp = 0; + u16 reg_cu = 0; + bool locked = false; + + DEBUGFUNC("ixgbe_setup_fc_generic"); + + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* + * 10gig parts do not have a word in the EEPROM to determine the + * default flow control setting, so we explicitly set it to full. + */ + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + /* + * Set up the 1G and 10G flow control advertisement registers so the + * HW will be able to do fc autoneg once the cable is plugged in. If + * we link at 10G, the 1G advertisement is harmless and vice versa. + */ + switch (hw->phy.media_type) { + case ixgbe_media_type_backplane: + /* some MAC's need RMW protection on AUTOC */ + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, ®_bp); + if (ret_val != IXGBE_SUCCESS) + goto out; + + fallthrough; /* only backplane uses autoc */ + case ixgbe_media_type_fiber_qsfp: + case ixgbe_media_type_fiber: + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + + break; + case ixgbe_media_type_copper: + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®_cu); + break; + default: + break; + } + + /* + * The possible values of fc.requested_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.requested_mode) { + case ixgbe_fc_none: + /* Flow control completely disabled by software override. */ + reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + reg |= IXGBE_PCS1GANA_ASM_PAUSE; + reg &= ~IXGBE_PCS1GANA_SYM_PAUSE; + if (hw->phy.media_type == ixgbe_media_type_backplane) { + reg_bp |= IXGBE_AUTOC_ASM_PAUSE; + reg_bp &= ~IXGBE_AUTOC_SYM_PAUSE; + } else if (hw->phy.media_type == ixgbe_media_type_copper) { + reg_cu |= IXGBE_TAF_ASM_PAUSE; + reg_cu &= ~IXGBE_TAF_SYM_PAUSE; + } + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE, as such we fall + * through to the fc_full statement. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + reg |= IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE; + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp |= IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE; + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE; + break; + default: + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, + "Flow control param set incorrectly\n"); + ret_val = IXGBE_ERR_CONFIG; + goto out; + break; + } + + if (hw->mac.type < ixgbe_mac_X540) { + /* + * Enable auto-negotiation between the MAC & PHY; + * the MAC will advertise clause 37 flow control. + */ + IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); + + /* Disable AN timeout */ + if (hw->fc.strict_ieee) + reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; + + IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); + hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); + } + + /* + * AUTOC restart handles negotiation of 1G and 10G on backplane + * and copper. There is no need to set the PCS1GCTL register. + * + */ + if (hw->phy.media_type == ixgbe_media_type_backplane) { + reg_bp |= IXGBE_AUTOC_AN_RESTART; + ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked); + if (ret_val) + goto out; + } else if ((hw->phy.media_type == ixgbe_media_type_copper) && + (ixgbe_device_supports_autoneg_fc(hw))) { + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu); + } + + hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); +out: + return ret_val; +} + +/** + * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware by filling the bus info structure and media type, clears + * all on chip counters, initializes receive address registers, multicast + * table, VLAN filter table, calls routine to set up link and flow control + * settings, and leaves transmit and receive units disabled and uninitialized + **/ +s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) +{ + s32 ret_val; + u32 ctrl_ext; + u16 device_caps; + + DEBUGFUNC("ixgbe_start_hw_generic"); + + /* Set the media type */ + hw->phy.media_type = hw->mac.ops.get_media_type(hw); + + /* PHY ops initialization must be done in reset_hw() */ + + /* Clear the VLAN filter table */ + hw->mac.ops.clear_vfta(hw); + + /* Clear statistics registers */ + hw->mac.ops.clear_hw_cntrs(hw); + + /* Set No Snoop Disable */ + ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); + ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + IXGBE_WRITE_FLUSH(hw); + + /* Setup flow control */ + ret_val = ixgbe_setup_fc(hw); + if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED) { + hw_dbg(hw, "Flow control setup failed, returning %d\n", ret_val); + return ret_val; + } + + /* Cache bit indicating need for crosstalk fix */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + hw->mac.ops.get_device_caps(hw, &device_caps); + if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR) + hw->need_crosstalk_fix = false; + else + hw->need_crosstalk_fix = true; + break; + default: + hw->need_crosstalk_fix = false; + break; + } + + /* Clear adapter stopped flag */ + hw->adapter_stopped = false; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_start_hw_gen2 - Init sequence for common device family + * @hw: pointer to hw structure + * + * Performs the init sequence common to the second generation + * of 10 GbE devices. + * Devices in the second generation: + * 82599 + * X540 + **/ +void ixgbe_start_hw_gen2(struct ixgbe_hw *hw) +{ + u32 i; + u32 regval; + + /* Clear the rate limiters */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0); + } + IXGBE_WRITE_FLUSH(hw); + + /* Disable relaxed ordering */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); + regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); + } + + for (i = 0; i < hw->mac.max_rx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | + IXGBE_DCA_RXCTRL_HEAD_WRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } +} + +/** + * ixgbe_init_hw_generic - Generic hardware initialization + * @hw: pointer to hardware structure + * + * Initialize the hardware by resetting the hardware, filling the bus info + * structure and media type, clears all on chip counters, initializes receive + * address registers, multicast table, VLAN filter table, calls routine to set + * up link and flow control settings, and leaves transmit and receive units + * disabled and uninitialized + **/ +s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) +{ + s32 status; + + DEBUGFUNC("ixgbe_init_hw_generic"); + + /* Reset the hardware */ + status = hw->mac.ops.reset_hw(hw); + + if (status == IXGBE_SUCCESS || status == IXGBE_ERR_SFP_NOT_PRESENT) { + /* Start the HW */ + status = hw->mac.ops.start_hw(hw); + } + + /* Initialize the LED link active for LED blink support */ + if (hw->mac.ops.init_led_link_act) + hw->mac.ops.init_led_link_act(hw); + + if (status != IXGBE_SUCCESS) + hw_dbg(hw, "Failed to initialize HW, STATUS = %d\n", status); + + return status; +} + +/** + * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters + * @hw: pointer to hardware structure + * + * Clears all hardware statistics counters by reading them from the hardware + * Statistics counters are clear on read. + **/ +s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) +{ + u16 i = 0; + + DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); + + IXGBE_READ_REG(hw, IXGBE_CRCERRS); + IXGBE_READ_REG(hw, IXGBE_ILLERRC); + IXGBE_READ_REG(hw, IXGBE_ERRBC); + IXGBE_READ_REG(hw, IXGBE_MSPDC); + for (i = 0; i < 8; i++) + IXGBE_READ_REG(hw, IXGBE_MPC(i)); + + IXGBE_READ_REG(hw, IXGBE_MLFC); + IXGBE_READ_REG(hw, IXGBE_MRFC); + IXGBE_READ_REG(hw, IXGBE_RLEC); + IXGBE_READ_REG(hw, IXGBE_LXONTXC); + IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } else { + IXGBE_READ_REG(hw, IXGBE_LXONRXC); + IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + } + + for (i = 0; i < 8; i++) { + IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + } else { + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + } + } + if (hw->mac.type >= ixgbe_mac_82599EB) + for (i = 0; i < 8; i++) + IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); + IXGBE_READ_REG(hw, IXGBE_PRC64); + IXGBE_READ_REG(hw, IXGBE_PRC127); + IXGBE_READ_REG(hw, IXGBE_PRC255); + IXGBE_READ_REG(hw, IXGBE_PRC511); + IXGBE_READ_REG(hw, IXGBE_PRC1023); + IXGBE_READ_REG(hw, IXGBE_PRC1522); + IXGBE_READ_REG(hw, IXGBE_GPRC); + IXGBE_READ_REG(hw, IXGBE_BPRC); + IXGBE_READ_REG(hw, IXGBE_MPRC); + IXGBE_READ_REG(hw, IXGBE_GPTC); + IXGBE_READ_REG(hw, IXGBE_GORCL); + IXGBE_READ_REG(hw, IXGBE_GORCH); + IXGBE_READ_REG(hw, IXGBE_GOTCL); + IXGBE_READ_REG(hw, IXGBE_GOTCH); + if (hw->mac.type == ixgbe_mac_82598EB) + for (i = 0; i < 8; i++) + IXGBE_READ_REG(hw, IXGBE_RNBC(i)); + IXGBE_READ_REG(hw, IXGBE_RUC); + IXGBE_READ_REG(hw, IXGBE_RFC); + IXGBE_READ_REG(hw, IXGBE_ROC); + IXGBE_READ_REG(hw, IXGBE_RJC); + IXGBE_READ_REG(hw, IXGBE_MNGPRC); + IXGBE_READ_REG(hw, IXGBE_MNGPDC); + IXGBE_READ_REG(hw, IXGBE_MNGPTC); + IXGBE_READ_REG(hw, IXGBE_TORL); + IXGBE_READ_REG(hw, IXGBE_TORH); + IXGBE_READ_REG(hw, IXGBE_TPR); + IXGBE_READ_REG(hw, IXGBE_TPT); + IXGBE_READ_REG(hw, IXGBE_PTC64); + IXGBE_READ_REG(hw, IXGBE_PTC127); + IXGBE_READ_REG(hw, IXGBE_PTC255); + IXGBE_READ_REG(hw, IXGBE_PTC511); + IXGBE_READ_REG(hw, IXGBE_PTC1023); + IXGBE_READ_REG(hw, IXGBE_PTC1522); + IXGBE_READ_REG(hw, IXGBE_MPTC); + IXGBE_READ_REG(hw, IXGBE_BPTC); + for (i = 0; i < 16; i++) { + IXGBE_READ_REG(hw, IXGBE_QPRC(i)); + IXGBE_READ_REG(hw, IXGBE_QPTC(i)); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); + IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); + IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + } else { + IXGBE_READ_REG(hw, IXGBE_QBRC(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + } + } + + if (hw->mac.type == ixgbe_mac_X540 || + hw->mac.type == ixgbe_mac_X550 || + ixgbe_is_mac_E6xx(hw->mac.type)) { + if (!hw->phy.id) + ixgbe_identify_phy(hw); + if (hw->mac.type < ixgbe_mac_E610) { + hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL, + IXGBE_MDIO_PCS_DEV_TYPE, &i); + hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH, + IXGBE_MDIO_PCS_DEV_TYPE, &i); + hw->phy.ops.read_reg(hw, IXGBE_LDPCECL, + IXGBE_MDIO_PCS_DEV_TYPE, &i); + hw->phy.ops.read_reg(hw, IXGBE_LDPCECH, + IXGBE_MDIO_PCS_DEV_TYPE, &i); + } + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_pba_string_generic - Reads part number string from EEPROM + * @hw: pointer to hardware structure + * @pba_num: stores the part number string from the EEPROM + * @pba_num_size: part number string buffer length + * + * Reads the part number string from the EEPROM. + **/ +s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + u32 pba_num_size) +{ + s32 ret_val; + u16 data; + u16 pba_ptr; + u16 offset; + u16 length; + + DEBUGFUNC("ixgbe_read_pba_string_generic"); + + if (pba_num == NULL) { + hw_dbg(hw, "PBA string buffer was null\n"); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + + ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + + /* + * if data is not ptr guard the PBA must be in legacy format which + * means pba_ptr is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (data != IXGBE_PBANUM_PTR_GUARD) { + hw_dbg(hw, "NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + hw_dbg(hw, "PBA string buffer too small\n"); + return IXGBE_ERR_NO_SPACE; + } + + /* extract hex string from data and pba_ptr */ + pba_num[0] = (data >> 12) & 0xF; + pba_num[1] = (data >> 8) & 0xF; + pba_num[2] = (data >> 4) & 0xF; + pba_num[3] = data & 0xF; + pba_num[4] = (pba_ptr >> 12) & 0xF; + pba_num[5] = (pba_ptr >> 8) & 0xF; + pba_num[6] = '-'; + pba_num[7] = 0; + pba_num[8] = (pba_ptr >> 4) & 0xF; + pba_num[9] = pba_ptr & 0xF; + + /* put a null character on the end of our string */ + pba_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (pba_num[offset] < 0xA) + pba_num[offset] += '0'; + else if (pba_num[offset] < 0x10) + pba_num[offset] += 'A' - 0xA; + } + + return IXGBE_SUCCESS; + } + + ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + + if (length == 0xFFFF || length == 0 || length > hw->eeprom.word_size) { + hw_dbg(hw, "NVM PBA number section invalid length\n"); + return IXGBE_ERR_PBA_SECTION; + } + + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + hw_dbg(hw, "PBA string buffer too small\n"); + return IXGBE_ERR_NO_SPACE; + } + + /* trim pba length from start of string */ + pba_ptr++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + pba_num[offset * 2] = (u8)(data >> 8); + pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); + } + pba_num[offset * 2] = '\0'; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_mac_addr_generic - Generic get MAC address + * @hw: pointer to hardware structure + * @mac_addr: Adapter MAC address + * + * Reads the adapter's MAC address from first Receive Address Register (RAR0) + * A reset of the adapter must be performed prior to calling this function + * in order for the MAC address to have been loaded from the EEPROM into RAR0 + **/ +s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) +{ + u32 rar_high; + u32 rar_low; + u16 i; + + DEBUGFUNC("ixgbe_get_mac_addr_generic"); + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); + rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); + + for (i = 0; i < 4; i++) + mac_addr[i] = (u8)(rar_low >> (i*8)); + + for (i = 0; i < 2; i++) + mac_addr[i+4] = (u8)(rar_high >> (i*8)); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_pci_config_data_generic - Generic store PCI bus info + * @hw: pointer to hardware structure + * @link_status: the link status returned by the PCI config space + * + * Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure + **/ +void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status) +{ + struct ixgbe_mac_info *mac = &hw->mac; + + if (hw->bus.type == ixgbe_bus_type_unknown) + hw->bus.type = ixgbe_bus_type_pci_express; + + switch (link_status & IXGBE_PCI_LINK_WIDTH) { + case IXGBE_PCI_LINK_WIDTH_1: + hw->bus.width = ixgbe_bus_width_pcie_x1; + break; + case IXGBE_PCI_LINK_WIDTH_2: + hw->bus.width = ixgbe_bus_width_pcie_x2; + break; + case IXGBE_PCI_LINK_WIDTH_4: + hw->bus.width = ixgbe_bus_width_pcie_x4; + break; + case IXGBE_PCI_LINK_WIDTH_8: + hw->bus.width = ixgbe_bus_width_pcie_x8; + break; + default: + hw->bus.width = ixgbe_bus_width_unknown; + break; + } + + switch (link_status & IXGBE_PCI_LINK_SPEED) { + case IXGBE_PCI_LINK_SPEED_2500: + hw->bus.speed = ixgbe_bus_speed_2500; + break; + case IXGBE_PCI_LINK_SPEED_5000: + hw->bus.speed = ixgbe_bus_speed_5000; + break; + case IXGBE_PCI_LINK_SPEED_8000: + hw->bus.speed = ixgbe_bus_speed_8000; + break; + case IXGBE_PCI_LINK_SPEED_16000: + hw->bus.speed = ixgbe_bus_speed_16000; + break; + default: + hw->bus.speed = ixgbe_bus_speed_unknown; + break; + } + + mac->ops.set_lan_id(hw); +} + +/** + * ixgbe_get_bus_info_generic - Generic set PCI bus info + * @hw: pointer to hardware structure + * + * Gets the PCI bus info (speed, width, type) then calls helper function to + * store this data within the ixgbe_hw structure. + **/ +s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) +{ + u16 link_status; + + DEBUGFUNC("ixgbe_get_bus_info_generic"); + + /* Get the negotiated link width and speed from PCI config space */ + link_status = IXGBE_READ_PCIE_WORD(hw, ixgbe_is_mac_E6xx(hw->mac.type) ? + IXGBE_PCI_LINK_STATUS_E610 : + IXGBE_PCI_LINK_STATUS); + + ixgbe_set_pci_config_data_generic(hw, link_status); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices + * @hw: pointer to the HW structure + * + * Determines the LAN function id by reading memory-mapped registers and swaps + * the port value if requested, and set MAC instance for devices that share + * CS4227. + **/ +void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) +{ + struct ixgbe_bus_info *bus = &hw->bus; + u32 reg; + u16 ee_ctrl_4; + + DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); + + reg = IXGBE_READ_REG(hw, IXGBE_STATUS); + bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; + bus->lan_id = (u8)bus->func; + + /* check for a port swap */ + reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); + if (reg & IXGBE_FACTPS_LFS) + bus->func ^= 0x1; + + /* Get MAC instance from EEPROM for configuring CS4227 */ + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) { + hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4); + bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >> + IXGBE_EE_CTRL_4_INST_ID_SHIFT; + } +} + +/** + * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units + * @hw: pointer to hardware structure + * + * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, + * disables transmit and receive units. The adapter_stopped flag is used by + * the shared code and drivers to determine if the adapter is in a stopped + * state and should not touch the hardware. + **/ +s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) +{ + u32 reg_val; + u16 i; + + DEBUGFUNC("ixgbe_stop_adapter_generic"); + + /* + * Set the adapter_stopped flag so other driver functions stop touching + * the hardware + */ + hw->adapter_stopped = true; + + /* Disable the receive unit */ + ixgbe_disable_rx(hw); + + /* Clear interrupt mask to stop interrupts from being generated */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); + + /* Clear any pending interrupts, flush previous writes */ + IXGBE_READ_REG(hw, IXGBE_EICR); + + /* Disable the transmit unit. Each queue must be disabled. */ + for (i = 0; i < hw->mac.max_tx_queues; i++) + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH); + + /* Disable the receive unit by stopping each queue */ + for (i = 0; i < hw->mac.max_rx_queues; i++) { + reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); + reg_val &= ~IXGBE_RXDCTL_ENABLE; + reg_val |= IXGBE_RXDCTL_SWFLSH; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val); + } + + /* flush all queues disables */ + IXGBE_WRITE_FLUSH(hw); + msec_delay(2); + + /* + * Prevent the PCI-E bus from hanging by disabling PCI-E primary + * access and verify no pending requests + */ + return ixgbe_disable_pcie_primary(hw); +} + +/** + * ixgbe_init_led_link_act_generic - Store the LED index link/activity. + * @hw: pointer to hardware structure + * + * Store the index for the link active LED. This will be used to support + * blinking the LED. + **/ +s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + u32 led_reg, led_mode; + u8 i; + + led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + /* Get LED link active from the LEDCTL register */ + for (i = 0; i < 4; i++) { + led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i); + + if ((led_mode & IXGBE_LED_MODE_MASK_BASE) == + IXGBE_LED_LINK_ACTIVE) { + mac->led_link_act = i; + return IXGBE_SUCCESS; + } + } + + /* + * If LEDCTL register does not have the LED link active set, then use + * known MAC defaults. + */ + switch (hw->mac.type) { + case ixgbe_mac_X550EM_a: + case ixgbe_mac_X550EM_x: + mac->led_link_act = 1; + break; + default: + mac->led_link_act = 2; + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_led_on_generic - Turns on the software controllable LEDs. + * @hw: pointer to hardware structure + * @index: led number to turn on + **/ +s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + DEBUGFUNC("ixgbe_led_on_generic"); + + if (index > 3) + return IXGBE_ERR_PARAM; + + /* To turn on the LED, set mode to ON. */ + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_led_off_generic - Turns off the software controllable LEDs. + * @hw: pointer to hardware structure + * @index: led number to turn off + **/ +s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + DEBUGFUNC("ixgbe_led_off_generic"); + + if (index > 3) + return IXGBE_ERR_PARAM; + + /* To turn off the LED, set mode to OFF. */ + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_eeprom_params_generic - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. + **/ +s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 eec; + u16 eeprom_size; + + DEBUGFUNC("ixgbe_init_eeprom_params_generic"); + + if (eeprom->type == ixgbe_eeprom_uninitialized) { + eeprom->type = ixgbe_eeprom_none; + /* Set default semaphore delay to 10ms which is a well + * tested value */ + eeprom->semaphore_delay = 10; + /* Clear EEPROM page size, it will be initialized as needed */ + eeprom->word_page_size = 0; + + /* + * Check for EEPROM present first. + * If not present leave as none + */ + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + if (eec & IXGBE_EEC_PRES) { + eeprom->type = ixgbe_eeprom_spi; + + /* + * SPI EEPROM is assumed here. This code would need to + * change if a future EEPROM is not SPI. + */ + eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> + IXGBE_EEC_SIZE_SHIFT); + eeprom->word_size = 1 << (eeprom_size + + IXGBE_EEPROM_WORD_SIZE_SHIFT); + } + + if (eec & IXGBE_EEC_ADDR_SIZE) + eeprom->address_bits = 16; + else + eeprom->address_bits = 8; + hw_dbg(hw, "Eeprom params: type = %d, size = %d, address bits: " + "%d\n", eeprom->type, eeprom->word_size, + eeprom->address_bits); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to write + * @words: number of word(s) + * @data: 16 bit word(s) to write to EEPROM + * + * Reads 16 bit word(s) from EEPROM through bit-bang method + **/ +s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + s32 status = IXGBE_SUCCESS; + u16 i, count; + + DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang_generic"); + + hw->eeprom.ops.init_params(hw); + + if (words == 0) { + status = IXGBE_ERR_INVALID_ARGUMENT; + goto out; + } + + if ((u32)words > hw->eeprom.word_size - (u32)offset) { + status = IXGBE_ERR_EEPROM; + goto out; + } + + /* + * The EEPROM page size cannot be queried from the chip. We do lazy + * initialization. It is worth to do that when we write large buffer. + */ + if ((hw->eeprom.word_page_size == 0) && + (words > IXGBE_EEPROM_PAGE_SIZE_MAX)) + ixgbe_detect_eeprom_page_size_generic(hw, offset); + + /* + * We cannot hold synchronization semaphores for too long + * to avoid other entity starvation. However it is more efficient + * to read in bursts than synchronizing access for each word. + */ + for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) { + count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ? + IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i); + status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i, + count, &data[i]); + + if (status != IXGBE_SUCCESS) + break; + } + +out: + return status; +} + +/** + * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be written to + * @words: number of word(s) + * @data: 16 bit word(s) to be written to the EEPROM + * + * If ixgbe_eeprom_update_checksum is not called after this function, the + * EEPROM will most likely contain an invalid checksum. + **/ +STATIC s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + s32 status; + u16 word; + u16 page_size; + u16 i; + u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; + + DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang"); + + /* Prepare the EEPROM for writing */ + status = ixgbe_acquire_eeprom(hw); + + if (status == IXGBE_SUCCESS) { + if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { + ixgbe_release_eeprom(hw); + status = IXGBE_ERR_EEPROM; + } + } + + if (status == IXGBE_SUCCESS) { + for (i = 0; i < words; i++) { + ixgbe_standby_eeprom(hw); + + /* Send the WRITE ENABLE command (8 bit opcode ) */ + ixgbe_shift_out_eeprom_bits(hw, + IXGBE_EEPROM_WREN_OPCODE_SPI, + IXGBE_EEPROM_OPCODE_BITS); + + ixgbe_standby_eeprom(hw); + + /* + * Some SPI eeproms use the 8th address bit embedded + * in the opcode + */ + if ((hw->eeprom.address_bits == 8) && + ((offset + i) >= 128)) + write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; + + /* Send the Write command (8-bit opcode + addr) */ + ixgbe_shift_out_eeprom_bits(hw, write_opcode, + IXGBE_EEPROM_OPCODE_BITS); + ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2), + hw->eeprom.address_bits); + + page_size = hw->eeprom.word_page_size; + + /* Send the data in burst via SPI*/ + do { + word = data[i]; + word = (word >> 8) | (word << 8); + ixgbe_shift_out_eeprom_bits(hw, word, 16); + + if (page_size == 0) + break; + + /* do not wrap around page */ + if (((offset + i) & (page_size - 1)) == + (page_size - 1)) + break; + } while (++i < words); + + ixgbe_standby_eeprom(hw); + msec_delay(10); + } + /* Done with writing - release the EEPROM */ + ixgbe_release_eeprom(hw); + } + + return status; +} + +/** + * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be written to + * @data: 16 bit word to be written to the EEPROM + * + * If ixgbe_eeprom_update_checksum is not called after this function, the + * EEPROM will most likely contain an invalid checksum. + **/ +s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) +{ + s32 status; + + DEBUGFUNC("ixgbe_write_eeprom_generic"); + + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + goto out; + } + + status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data); + +out: + return status; +} + +/** + * ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be read + * @data: read 16 bit words(s) from EEPROM + * @words: number of word(s) + * + * Reads 16 bit word(s) from EEPROM through bit-bang method + **/ +s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + s32 status = IXGBE_SUCCESS; + u16 i, count; + + DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang_generic"); + + hw->eeprom.ops.init_params(hw); + + if (words == 0) { + status = IXGBE_ERR_INVALID_ARGUMENT; + goto out; + } + + if ((u32)words > hw->eeprom.word_size - (u32)offset) { + status = IXGBE_ERR_EEPROM; + goto out; + } + + /* + * We cannot hold synchronization semaphores for too long + * to avoid other entity starvation. However it is more efficient + * to read in bursts than synchronizing access for each word. + */ + for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) { + count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ? + IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i); + + status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i, + count, &data[i]); + + if (status != IXGBE_SUCCESS) + break; + } + +out: + return status; +} + +/** + * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be read + * @words: number of word(s) + * @data: read 16 bit word(s) from EEPROM + * + * Reads 16 bit word(s) from EEPROM through bit-bang method + **/ +STATIC s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + s32 status; + u16 word_in; + u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; + u16 i; + + DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang"); + + /* Prepare the EEPROM for reading */ + status = ixgbe_acquire_eeprom(hw); + + if (status == IXGBE_SUCCESS) { + if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { + ixgbe_release_eeprom(hw); + status = IXGBE_ERR_EEPROM; + } + } + + if (status == IXGBE_SUCCESS) { + for (i = 0; i < words; i++) { + ixgbe_standby_eeprom(hw); + /* + * Some SPI eeproms use the 8th address bit embedded + * in the opcode + */ + if ((hw->eeprom.address_bits == 8) && + ((offset + i) >= 128)) + read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; + + /* Send the READ command (opcode + addr) */ + ixgbe_shift_out_eeprom_bits(hw, read_opcode, + IXGBE_EEPROM_OPCODE_BITS); + ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2), + hw->eeprom.address_bits); + + /* Read the data. */ + word_in = ixgbe_shift_in_eeprom_bits(hw, 16); + data[i] = (word_in >> 8) | (word_in << 8); + } + + /* End this read operation */ + ixgbe_release_eeprom(hw); + } + + return status; +} + +/** + * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be read + * @data: read 16 bit value from EEPROM + * + * Reads 16 bit value from EEPROM through bit-bang method + **/ +s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 *data) +{ + s32 status; + + DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic"); + + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + goto out; + } + + status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); + +out: + return status; +} + +/** + * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @words: number of word(s) + * @data: 16 bit word(s) from the EEPROM + * + * Reads a 16 bit word(s) from the EEPROM using the EERD register. + **/ +s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + u32 eerd; + s32 status = IXGBE_SUCCESS; + u32 i; + + DEBUGFUNC("ixgbe_read_eerd_buffer_generic"); + + hw->eeprom.ops.init_params(hw); + + if (words == 0) { + status = IXGBE_ERR_INVALID_ARGUMENT; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words"); + goto out; + } + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset"); + goto out; + } + + for (i = 0; i < words; i++) { + eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | + IXGBE_EEPROM_RW_REG_START; + + IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); + status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); + + if (status == IXGBE_SUCCESS) { + data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >> + IXGBE_EEPROM_RW_REG_DATA); + } else { + hw_dbg(hw, "Eeprom read timed out\n"); + goto out; + } + } +out: + return status; +} + +/** + * ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be used as a scratch pad + * + * Discover EEPROM page size by writing marching data at given offset. + * This function is called only when we are writing a new large buffer + * at given offset so the data would be overwritten anyway. + **/ +STATIC s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw, + u16 offset) +{ + u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX]; + s32 status = IXGBE_SUCCESS; + u16 i; + + DEBUGFUNC("ixgbe_detect_eeprom_page_size_generic"); + + for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++) + data[i] = i; + + hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX; + status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, + IXGBE_EEPROM_PAGE_SIZE_MAX, data); + hw->eeprom.word_page_size = 0; + if (status != IXGBE_SUCCESS) + goto out; + + status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); + if (status != IXGBE_SUCCESS) + goto out; + + /* + * When writing in burst more than the actual page size + * EEPROM address wraps around current page. + */ + hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0]; + + hw_dbg(hw, "Detected EEPROM page size = %d words.", + hw->eeprom.word_page_size); +out: + return status; +} + +/** + * ixgbe_read_eerd_generic - Read EEPROM word using EERD + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the EERD register. + **/ +s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data); +} + +/** + * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @words: number of word(s) + * @data: word(s) write to the EEPROM + * + * Write a 16 bit word(s) to the EEPROM using the EEWR register. + **/ +s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + u32 eewr; + s32 status = IXGBE_SUCCESS; + u16 i; + + DEBUGFUNC("ixgbe_write_eewr_generic"); + + hw->eeprom.ops.init_params(hw); + + if (words == 0) { + status = IXGBE_ERR_INVALID_ARGUMENT; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words"); + goto out; + } + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset"); + goto out; + } + + for (i = 0; i < words; i++) { + eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | + (data[i] << IXGBE_EEPROM_RW_REG_DATA) | + IXGBE_EEPROM_RW_REG_START; + + status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Eeprom write EEWR timed out\n"); + goto out; + } + + IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr); + + status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Eeprom write EEWR timed out\n"); + goto out; + } + } + +out: + return status; +} + +/** + * ixgbe_write_eewr_generic - Write EEPROM word using EEWR + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the EEWR register. + **/ +s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data) +{ + return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data); +} + +/** + * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status + * @hw: pointer to hardware structure + * @ee_reg: EEPROM flag for polling + * + * Polls the status bit (bit 1) of the EERD or EEWR to determine when the + * read or write is done respectively. + **/ +s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) +{ + u32 i; + u32 reg; + s32 status = IXGBE_ERR_EEPROM; + + DEBUGFUNC("ixgbe_poll_eerd_eewr_done"); + + for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) { + if (ee_reg == IXGBE_NVM_POLL_READ) + reg = IXGBE_READ_REG(hw, IXGBE_EERD); + else + reg = IXGBE_READ_REG(hw, IXGBE_EEWR); + + if (reg & IXGBE_EEPROM_RW_REG_DONE) { + status = IXGBE_SUCCESS; + break; + } + usec_delay(5); + } + + if (i == IXGBE_EERD_EEWR_ATTEMPTS) + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "EEPROM read/write done polling timed out"); + + return status; +} + +/** + * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang + * @hw: pointer to hardware structure + * + * Prepares EEPROM for access using bit-bang method. This function should + * be called before issuing a command to the EEPROM. + **/ +STATIC s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u32 eec; + u32 i; + + DEBUGFUNC("ixgbe_acquire_eeprom"); + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) + != IXGBE_SUCCESS) + status = IXGBE_ERR_SWFW_SYNC; + + if (status == IXGBE_SUCCESS) { + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + /* Request EEPROM Access */ + eec |= IXGBE_EEC_REQ; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + + for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + if (eec & IXGBE_EEC_GNT) + break; + usec_delay(5); + } + + /* Release if grant not acquired */ + if (!(eec & IXGBE_EEC_GNT)) { + eec &= ~IXGBE_EEC_REQ; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + hw_dbg(hw, "Could not acquire EEPROM grant\n"); + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + status = IXGBE_ERR_EEPROM; + } + + /* Setup EEPROM for Read/Write */ + if (status == IXGBE_SUCCESS) { + /* Clear CS and SK */ + eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + IXGBE_WRITE_FLUSH(hw); + usec_delay(1); + } + } + return status; +} + +/** + * ixgbe_get_eeprom_semaphore - Get hardware semaphore + * @hw: pointer to hardware structure + * + * Sets the hardware semaphores so EEPROM access can occur for bit-bang method + **/ +STATIC s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_EEPROM; + u32 timeout = 2000; + u32 i; + u32 swsm; + + DEBUGFUNC("ixgbe_get_eeprom_semaphore"); + + /* Get SMBI software semaphore between device drivers first */ + for (i = 0; i < timeout; i++) { + /* + * If the SMBI bit is 0 when we read it, then the bit will be + * set and we have the semaphore + */ + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); + if (!(swsm & IXGBE_SWSM_SMBI)) { + status = IXGBE_SUCCESS; + break; + } + usec_delay(50); + } + + if (i == timeout) { + hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore " + "not granted.\n"); + /* + * this release is particularly important because our attempts + * above to get the semaphore may have succeeded, and if there + * was a timeout, we should unconditionally clear the semaphore + * bits to free the driver to make progress + */ + ixgbe_release_eeprom_semaphore(hw); + + usec_delay(50); + /* + * one last try + * If the SMBI bit is 0 when we read it, then the bit will be + * set and we have the semaphore + */ + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); + if (!(swsm & IXGBE_SWSM_SMBI)) + status = IXGBE_SUCCESS; + } + + /* Now get the semaphore between SW/FW through the SWESMBI bit */ + if (status == IXGBE_SUCCESS) { + for (i = 0; i < timeout; i++) { + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); + + /* Set the SW EEPROM semaphore bit to request access */ + swsm |= IXGBE_SWSM_SWESMBI; + IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm); + + /* + * If we set the bit successfully then we got the + * semaphore. + */ + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); + if (swsm & IXGBE_SWSM_SWESMBI) + break; + + usec_delay(50); + } + + /* + * Release semaphores and return error if SW EEPROM semaphore + * was not granted because we don't have access to the EEPROM + */ + if (i >= timeout) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "SWESMBI Software EEPROM semaphore not granted.\n"); + ixgbe_release_eeprom_semaphore(hw); + status = IXGBE_ERR_EEPROM; + } + } else { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "Software semaphore SMBI between device drivers " + "not granted.\n"); + } + + return status; +} + +/** + * ixgbe_release_eeprom_semaphore - Release hardware semaphore + * @hw: pointer to hardware structure + * + * This function clears hardware semaphore bits. + **/ +STATIC void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) +{ + u32 swsm; + + DEBUGFUNC("ixgbe_release_eeprom_semaphore"); + + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); + + /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ + swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); + IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_ready_eeprom - Polls for EEPROM ready + * @hw: pointer to hardware structure + **/ +STATIC s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 i; + u8 spi_stat_reg; + + DEBUGFUNC("ixgbe_ready_eeprom"); + + /* + * Read "Status Register" repeatedly until the LSB is cleared. The + * EEPROM will signal that the command has been completed by clearing + * bit 0 of the internal status register. If it's not cleared within + * 5 milliseconds, then error out. + */ + for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { + ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, + IXGBE_EEPROM_OPCODE_BITS); + spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); + if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) + break; + + usec_delay(5); + ixgbe_standby_eeprom(hw); + }; + + /* + * On some parts, SPI write time could vary from 0-20mSec on 3.3V + * devices (and only 0-5mSec on 5V devices) + */ + if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { + hw_dbg(hw, "SPI EEPROM Status error\n"); + status = IXGBE_ERR_EEPROM; + } + + return status; +} + +/** + * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state + * @hw: pointer to hardware structure + **/ +STATIC void ixgbe_standby_eeprom(struct ixgbe_hw *hw) +{ + u32 eec; + + DEBUGFUNC("ixgbe_standby_eeprom"); + + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + /* Toggle CS to flush commands */ + eec |= IXGBE_EEC_CS; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + IXGBE_WRITE_FLUSH(hw); + usec_delay(1); + eec &= ~IXGBE_EEC_CS; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + IXGBE_WRITE_FLUSH(hw); + usec_delay(1); +} + +/** + * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. + * @hw: pointer to hardware structure + * @data: data to send to the EEPROM + * @count: number of bits to shift out + **/ +STATIC void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, + u16 count) +{ + u32 eec; + u32 mask; + u32 i; + + DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); + + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + /* + * Mask is used to shift "count" bits of "data" out to the EEPROM + * one bit at a time. Determine the starting bit based on count + */ + mask = 0x01 << (count - 1); + + for (i = 0; i < count; i++) { + /* + * A "1" is shifted out to the EEPROM by setting bit "DI" to a + * "1", and then raising and then lowering the clock (the SK + * bit controls the clock input to the EEPROM). A "0" is + * shifted out to the EEPROM by setting "DI" to "0" and then + * raising and then lowering the clock. + */ + if (data & mask) + eec |= IXGBE_EEC_DI; + else + eec &= ~IXGBE_EEC_DI; + + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + IXGBE_WRITE_FLUSH(hw); + + usec_delay(1); + + ixgbe_raise_eeprom_clk(hw, &eec); + ixgbe_lower_eeprom_clk(hw, &eec); + + /* + * Shift mask to signify next bit of data to shift in to the + * EEPROM + */ + mask = mask >> 1; + }; + + /* We leave the "DI" bit set to "0" when we leave this routine. */ + eec &= ~IXGBE_EEC_DI; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM + * @hw: pointer to hardware structure + * @count: number of bits to shift + **/ +STATIC u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) +{ + u32 eec; + u32 i; + u16 data = 0; + + DEBUGFUNC("ixgbe_shift_in_eeprom_bits"); + + /* + * In order to read a register from the EEPROM, we need to shift + * 'count' bits in from the EEPROM. Bits are "shifted in" by raising + * the clock input to the EEPROM (setting the SK bit), and then reading + * the value of the "DO" bit. During this "shifting in" process the + * "DI" bit should always be clear. + */ + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); + + for (i = 0; i < count; i++) { + data = data << 1; + ixgbe_raise_eeprom_clk(hw, &eec); + + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + eec &= ~(IXGBE_EEC_DI); + if (eec & IXGBE_EEC_DO) + data |= 1; + + ixgbe_lower_eeprom_clk(hw, &eec); + } + + return data; +} + +/** + * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. + * @hw: pointer to hardware structure + * @eec: EEC register's current value + **/ +STATIC void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) +{ + DEBUGFUNC("ixgbe_raise_eeprom_clk"); + + /* + * Raise the clock input to the EEPROM + * (setting the SK bit), then delay + */ + *eec = *eec | IXGBE_EEC_SK; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec); + IXGBE_WRITE_FLUSH(hw); + usec_delay(1); +} + +/** + * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. + * @hw: pointer to hardware structure + * @eec: EEC's current value + **/ +STATIC void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) +{ + DEBUGFUNC("ixgbe_lower_eeprom_clk"); + + /* + * Lower the clock input to the EEPROM (clearing the SK bit), then + * delay + */ + *eec = *eec & ~IXGBE_EEC_SK; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec); + IXGBE_WRITE_FLUSH(hw); + usec_delay(1); +} + +/** + * ixgbe_release_eeprom - Release EEPROM, release semaphores + * @hw: pointer to hardware structure + **/ +STATIC void ixgbe_release_eeprom(struct ixgbe_hw *hw) +{ + u32 eec; + + DEBUGFUNC("ixgbe_release_eeprom"); + + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + eec |= IXGBE_EEC_CS; /* Pull CS high */ + eec &= ~IXGBE_EEC_SK; /* Lower SCK */ + + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + IXGBE_WRITE_FLUSH(hw); + + usec_delay(1); + + /* Stop requesting EEPROM access */ + eec &= ~IXGBE_EEC_REQ; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec); + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + + /* Delay before attempt to obtain semaphore again to allow FW access */ + msec_delay(hw->eeprom.semaphore_delay); +} + +/** + * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum + * @hw: pointer to hardware structure + * + * Returns a negative error code on error, or the 16-bit checksum + **/ +s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) +{ + u16 i; + u16 j; + u16 checksum = 0; + u16 length = 0; + u16 pointer = 0; + u16 word = 0; + + DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); + + /* Include 0x0-0x3F in the checksum */ + for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { + if (hw->eeprom.ops.read(hw, i, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + checksum += word; + } + + /* Include all data from pointers except for the fw pointer */ + for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { + if (hw->eeprom.ops.read(hw, i, &pointer)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + + /* If the pointer seems invalid */ + if (pointer == 0xFFFF || pointer == 0) + continue; + + if (hw->eeprom.ops.read(hw, pointer, &length)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + + if (length == 0xFFFF || length == 0) + continue; + + for (j = pointer + 1; j <= pointer + length; j++) { + if (hw->eeprom.ops.read(hw, j, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + checksum += word; + } + } + + checksum = (u16)IXGBE_EEPROM_SUM - checksum; + + return (s32)checksum; +} + +/** + * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If the + * caller does not need checksum_val, the value can be NULL. + **/ +s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, + u16 *checksum_val) +{ + s32 status; + u16 checksum; + u16 read_checksum = 0; + + DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) + return status; + + checksum = (u16)(status & 0xffff); + + status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + /* Verify read checksum from EEPROM is the same as + * calculated checksum + */ + if (read_checksum != checksum) + status = IXGBE_ERR_EEPROM_CHECKSUM; + + /* If the user cares, return the calculated checksum */ + if (checksum_val) + *checksum_val = checksum; + + return status; +} + +/** + * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum + * @hw: pointer to hardware structure + **/ +s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) +{ + s32 status; + u16 checksum; + + DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) + return status; + + checksum = (u16)(status & 0xffff); + + status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum); + + return status; +} + +/** + * ixgbe_validate_mac_addr - Validate MAC address + * @mac_addr: pointer to MAC address. + * + * Tests a MAC address to ensure it is a valid Individual Address. + **/ +s32 ixgbe_validate_mac_addr(u8 *mac_addr) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_validate_mac_addr"); + + /* Make sure it is not a multicast address */ + if (IXGBE_IS_MULTICAST(mac_addr)) { + status = IXGBE_ERR_INVALID_MAC_ADDR; + /* Not a broadcast address */ + } else if (IXGBE_IS_BROADCAST(mac_addr)) { + status = IXGBE_ERR_INVALID_MAC_ADDR; + /* Reject the zero address */ + } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && + mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { + status = IXGBE_ERR_INVALID_MAC_ADDR; + } + return status; +} + +/** + * ixgbe_set_rar_generic - Set Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * @addr: Address to put into receive address register + * @vmdq: VMDq "set" or "pool" index + * @enable_addr: set flag that address is active + * + * Puts an ethernet address into a receive address register. + **/ +s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr) +{ + u32 rar_low, rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_set_rar_generic"); + + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, + "RAR index %d is out of range.\n", index); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + /* setup VMDq pool selection before this RAR gets enabled */ + hw->mac.ops.set_vmdq(hw, index, vmdq); + + /* + * HW expects these in little endian so we reverse the byte + * order from network order (big endian) to little endian + */ + rar_low = ((u32)addr[0] | + ((u32)addr[1] << 8) | + ((u32)addr[2] << 16) | + ((u32)addr[3] << 24)); + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); + rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); + + if (enable_addr != 0) + rar_high |= IXGBE_RAH_AV; + + IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_rar_generic - Remove Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * + * Clears an ethernet address from a receive address register. + **/ +s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_clear_rar_generic"); + + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, + "RAR index %d is out of range.\n", index); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); + + IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_rx_addrs_generic - Initializes receive address filters. + * @hw: pointer to hardware structure + * + * Places the MAC address in receive address register 0 and clears the rest + * of the receive address registers. Clears the multicast table. Assumes + * the receiver is in reset when the routine is called. + **/ +s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) +{ + u32 i; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_init_rx_addrs_generic"); + + /* + * If the current mac address is valid, assume it is a software override + * to the permanent address. + * Otherwise, use the permanent address from the eeprom. + */ + if (ixgbe_validate_mac_addr(hw->mac.addr) == + IXGBE_ERR_INVALID_MAC_ADDR) { + /* Get the MAC address from the RAR0 for later reference */ + hw->mac.ops.get_mac_addr(hw, hw->mac.addr); + + hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ", + hw->mac.addr[0], hw->mac.addr[1], + hw->mac.addr[2]); + hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3], + hw->mac.addr[4], hw->mac.addr[5]); + } else { + /* Setup the receive address. */ + hw_dbg(hw, "Overriding MAC Address in RAR[0]\n"); + hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ", + hw->mac.addr[0], hw->mac.addr[1], + hw->mac.addr[2]); + hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3], + hw->mac.addr[4], hw->mac.addr[5]); + + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + } + + /* clear VMDq pool/queue selection for RAR 0 */ + hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); + + hw->addr_ctrl.overflow_promisc = 0; + + hw->addr_ctrl.rar_used_count = 1; + + /* Zero out the other receive addresses. */ + hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1); + for (i = 1; i < rar_entries; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); + } + + /* Clear the MTA */ + hw->addr_ctrl.mta_in_use = 0; + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); + + hw_dbg(hw, " Clearing MTA\n"); + for (i = 0; i < hw->mac.mcft_size; i++) + IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); + + ixgbe_init_uta_tables(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_add_uc_addr - Adds a secondary unicast address. + * @hw: pointer to hardware structure + * @addr: new address + * @vmdq: VMDq "set" or "pool" index + * + * Adds it to unused receive address register or goes into promiscuous mode. + **/ +void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) +{ + u32 rar_entries = hw->mac.num_rar_entries; + u32 rar; + + DEBUGFUNC("ixgbe_add_uc_addr"); + + hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + + /* + * Place this address in the RAR if there is room, + * else put the controller into promiscuous mode + */ + if (hw->addr_ctrl.rar_used_count < rar_entries) { + rar = hw->addr_ctrl.rar_used_count; + hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); + hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar); + hw->addr_ctrl.rar_used_count++; + } else { + hw->addr_ctrl.overflow_promisc++; + } + + hw_dbg(hw, "ixgbe_add_uc_addr Complete\n"); +} + +/** + * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses + * @hw: pointer to hardware structure + * @addr_list: the list of new addresses + * @addr_count: number of addresses + * @next: iterator function to walk the address list + * + * The given list replaces any existing list. Clears the secondary addrs from + * receive address registers. Uses unused receive address registers for the + * first secondary addresses, and falls back to promiscuous mode as needed. + * + * Drivers using secondary unicast addresses must set user_set_promisc when + * manually putting the device into promiscuous mode. + **/ +s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr next) +{ + u8 *addr; + u32 i; + u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; + u32 uc_addr_in_use; + u32 fctrl; + u32 vmdq; + + DEBUGFUNC("ixgbe_update_uc_addr_list_generic"); + + /* + * Clear accounting of old secondary address list, + * don't count RAR[0] + */ + uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; + hw->addr_ctrl.rar_used_count -= uc_addr_in_use; + hw->addr_ctrl.overflow_promisc = 0; + + /* Zero out the other receive addresses */ + hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use+1); + for (i = 0; i < uc_addr_in_use; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0); + IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0); + } + + /* Add the new addresses */ + for (i = 0; i < addr_count; i++) { + hw_dbg(hw, " Adding the secondary addresses:\n"); + addr = next(hw, &addr_list, &vmdq); + ixgbe_add_uc_addr(hw, addr, vmdq); + } + + if (hw->addr_ctrl.overflow_promisc) { + /* enable promisc if not already in overflow or set by user */ + if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { + hw_dbg(hw, " Entering address overflow promisc mode\n"); + fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + fctrl |= IXGBE_FCTRL_UPE; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + } + } else { + /* only disable if set by overflow, not by user */ + if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { + hw_dbg(hw, " Leaving address overflow promisc mode\n"); + fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + fctrl &= ~IXGBE_FCTRL_UPE; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + } + } + + hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n"); + return IXGBE_SUCCESS; +} + +/** + * ixgbe_mta_vector - Determines bit-vector in multicast table to set + * @hw: pointer to hardware structure + * @mc_addr: the multicast address + * + * Extracts the 12 bits, from a multicast address, to determine which + * bit-vector to set in the multicast table. The hardware uses 12 bits, from + * incoming rx multicast addresses, to determine the bit-vector to check in + * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set + * by the MO field of the MCSTCTRL. The MO field is set during initialization + * to mc_filter_type. + **/ +STATIC s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) +{ + u32 vector = 0; + + DEBUGFUNC("ixgbe_mta_vector"); + + switch (hw->mac.mc_filter_type) { + case 0: /* use bits [47:36] of the address */ + vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); + break; + case 1: /* use bits [46:35] of the address */ + vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); + break; + case 2: /* use bits [45:34] of the address */ + vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); + break; + case 3: /* use bits [43:32] of the address */ + vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); + break; + default: /* Invalid mc_filter_type */ + hw_dbg(hw, "MC filter type param set incorrectly\n"); + ASSERT(0); + break; + } + + /* vector can only be 12-bits or boundary will be exceeded */ + vector &= 0xFFF; + return vector; +} + +/** + * ixgbe_set_mta - Set bit-vector in multicast table + * @hw: pointer to hardware structure + * @mc_addr: Multicast address + * + * Sets the bit-vector in the multicast table. + **/ +void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) +{ + u32 vector; + u32 vector_bit; + u32 vector_reg; + + DEBUGFUNC("ixgbe_set_mta"); + + hw->addr_ctrl.mta_in_use++; + + vector = ixgbe_mta_vector(hw, mc_addr); + hw_dbg(hw, " bit-vector = 0x%03X\n", vector); + + /* + * The MTA is a register array of 128 32-bit registers. It is treated + * like an array of 4096 bits. We want to set bit + * BitArray[vector_value]. So we figure out what register the bit is + * in, read it, OR in the new bit, then write back the new value. The + * register is determined by the upper 7 bits of the vector value and + * the bit within that register are determined by the lower 5 bits of + * the value. + */ + vector_reg = (vector >> 5) & 0x7F; + vector_bit = vector & 0x1F; + hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); +} + +/** + * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses + * @hw: pointer to hardware structure + * @mc_addr_list: the list of new multicast addresses + * @mc_addr_count: number of addresses + * @next: iterator function to walk the multicast address list + * @clear: flag, when set clears the table beforehand + * + * When the clear flag is set, the given list replaces any existing list. + * Hashes the given addresses into the multicast table. + **/ +s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, ixgbe_mc_addr_itr next, + bool clear) +{ + u32 i; + u32 vmdq; + + DEBUGFUNC("ixgbe_update_mc_addr_list_generic"); + + /* + * Set the new number of MC addresses that we are being requested to + * use. + */ + hw->addr_ctrl.num_mc_addrs = mc_addr_count; + hw->addr_ctrl.mta_in_use = 0; + + /* Clear mta_shadow */ + if (clear) { + hw_dbg(hw, " Clearing MTA\n"); + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); + } + + /* Update mta_shadow */ + for (i = 0; i < mc_addr_count; i++) { + hw_dbg(hw, " Adding the multicast addresses:\n"); + ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); + } + + /* Enable mta */ + for (i = 0; i < hw->mac.mcft_size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, + hw->mac.mta_shadow[i]); + + if (hw->addr_ctrl.mta_in_use > 0) + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, + IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); + + hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n"); + return IXGBE_SUCCESS; +} + +/** + * ixgbe_enable_mc_generic - Enable multicast address in RAR + * @hw: pointer to hardware structure + * + * Enables multicast address in RAR and the use of the multicast hash table. + **/ +s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; + + DEBUGFUNC("ixgbe_enable_mc_generic"); + + if (a->mta_in_use > 0) + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | + hw->mac.mc_filter_type); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_disable_mc_generic - Disable multicast address in RAR + * @hw: pointer to hardware structure + * + * Disables multicast address in RAR and the use of the multicast hash table. + **/ +s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; + + DEBUGFUNC("ixgbe_disable_mc_generic"); + + if (a->mta_in_use > 0) + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fc_enable_generic - Enable flow control + * @hw: pointer to hardware structure + * + * Enable flow control according to the current settings. + **/ +s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + u32 mflcn_reg, fccfg_reg; + u32 reg; + u32 fcrtl, fcrth; + int i; + + DEBUGFUNC("ixgbe_fc_enable_generic"); + + /* Validate the water mark configuration */ + if (!hw->fc.pause_time) { + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* Low water mark of zero causes XOFF floods */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && + hw->fc.high_water[i]) { + if (!hw->fc.low_water[i] || + hw->fc.low_water[i] >= hw->fc.high_water[i]) { + hw_dbg(hw, "Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + } + } + + /* Negotiate the fc mode to use */ + hw->mac.ops.fc_autoneg(hw); + + /* Disable any previous flow control settings */ + mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); + mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); + + fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); + fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); + + /* + * The possible values of fc.current_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.current_mode) { + case ixgbe_fc_none: + /* + * Flow control is disabled by software override or autoneg. + * The code below will actually disable it in the HW. + */ + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + mflcn_reg |= IXGBE_MFLCN_RFCE; + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; + break; + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + mflcn_reg |= IXGBE_MFLCN_RFCE; + fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; + break; + default: + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, + "Flow control param set incorrectly\n"); + ret_val = IXGBE_ERR_CONFIG; + goto out; + break; + } + + /* Set 802.3x based flow control settings. */ + mflcn_reg |= IXGBE_MFLCN_DPF; + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); + IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); + + + /* Set up and enable Rx high/low water mark thresholds, enable XON. */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && + hw->fc.high_water[i]) { + fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); + fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; + } else { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); + /* + * In order to prevent Tx hangs when the internal Tx + * switch is enabled we must set the high water mark + * to the Rx packet buffer size - 24KB. This allows + * the Tx switch to function even under heavy Rx + * workloads. + */ + fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576; + } + + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth); + } + + /* Configure pause time (2 TCs per register) */ + reg = hw->fc.pause_time * 0x00010001; + for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + +out: + return ret_val; +} + +/** + * ixgbe_negotiate_fc - Negotiate flow control + * @hw: pointer to hardware structure + * @adv_reg: flow control advertised settings + * @lp_reg: link partner's flow control settings + * @adv_sym: symmetric pause bit in advertisement + * @adv_asm: asymmetric pause bit in advertisement + * @lp_sym: symmetric pause bit in link partner advertisement + * @lp_asm: asymmetric pause bit in link partner advertisement + * + * Find the intersection between advertised settings and link partner's + * advertised settings + **/ +s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) +{ + if ((!(adv_reg)) || (!(lp_reg))) { + ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED, + "Local or link partner's advertised flow control " + "settings are NULL. Local: %x, link partner: %x\n", + adv_reg, lp_reg); + return IXGBE_ERR_FC_NOT_NEGOTIATED; + } + + if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { + /* + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise RX + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. + */ + if (hw->fc.requested_mode == ixgbe_fc_full) { + hw->fc.current_mode = ixgbe_fc_full; + hw_dbg(hw, "Flow Control = FULL.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_rx_pause; + hw_dbg(hw, "Flow Control=RX PAUSE frames only\n"); + } + } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && + (lp_reg & lp_sym) && (lp_reg & lp_asm)) { + hw->fc.current_mode = ixgbe_fc_tx_pause; + hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n"); + } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && + !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { + hw->fc.current_mode = ixgbe_fc_rx_pause; + hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_none; + hw_dbg(hw, "Flow Control = NONE.\n"); + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber + * @hw: pointer to hardware structure + * + * Enable flow control according on 1 gig fiber. + **/ +STATIC s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) +{ + u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; + s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + + /* + * On multispeed fiber at 1g, bail out if + * - link is up but AN did not complete, or if + * - link is up and AN completed but timed out + */ + + linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || + (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + hw_dbg(hw, "Auto-Negotiation did not complete or timed out\n"); + goto out; + } + + pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); + + ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg, + pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE, + IXGBE_PCS1GANA_ASM_PAUSE, + IXGBE_PCS1GANA_SYM_PAUSE, + IXGBE_PCS1GANA_ASM_PAUSE); + +out: + return ret_val; +} + +/** + * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +STATIC s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) +{ + u32 links2, anlp1_reg, autoc_reg, links; + s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + + /* + * On backplane, bail out if + * - backplane autoneg was not completed, or if + * - we are 82599 and link partner is not AN enabled + */ + links = IXGBE_READ_REG(hw, IXGBE_LINKS); + if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); + goto out; + } + + if (hw->mac.type == ixgbe_mac_82599EB) { + links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); + if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { + hw_dbg(hw, "Link partner is not AN enabled\n"); + goto out; + } + } + /* + * Read the 10g AN autoc and LP ability registers and resolve + * local flow control settings accordingly + */ + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); + + ret_val = ixgbe_negotiate_fc(hw, autoc_reg, + anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE, + IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE); + +out: + return ret_val; +} + +/** + * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +STATIC s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) +{ + u16 technology_ability_reg = 0; + u16 lp_technology_ability_reg = 0; + + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &technology_ability_reg); + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &lp_technology_ability_reg); + + return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg, + (u32)lp_technology_ability_reg, + IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE, + IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE); +} + +/** + * ixgbe_fc_autoneg - Configure flow control + * @hw: pointer to hardware structure + * + * Compares our advertised flow control capabilities to those advertised by + * our link partner, and determines the proper flow control mode to use. + **/ +void ixgbe_fc_autoneg(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + ixgbe_link_speed speed; + bool link_up; + + DEBUGFUNC("ixgbe_fc_autoneg"); + + /* + * AN should have completed when the cable was plugged in. + * Look for reasons to bail out. Bail out if: + * - FC autoneg is disabled, or if + * - link is not up. + */ + if (hw->fc.disable_fc_autoneg) { + /* TODO: This should be just an informative log */ + ERROR_REPORT1(IXGBE_ERROR_CAUTION, + "Flow control autoneg is disabled"); + goto out; + } + + hw->mac.ops.check_link(hw, &speed, &link_up, false); + if (!link_up) { + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); + goto out; + } + + switch (hw->phy.media_type) { + /* Autoneg flow control on fiber adapters */ + case ixgbe_media_type_fiber_qsfp: + case ixgbe_media_type_fiber: + if (speed == IXGBE_LINK_SPEED_1GB_FULL) + ret_val = ixgbe_fc_autoneg_fiber(hw); + break; + + /* Autoneg flow control on backplane adapters */ + case ixgbe_media_type_backplane: + ret_val = ixgbe_fc_autoneg_backplane(hw); + break; + + /* Autoneg flow control on copper adapters */ + case ixgbe_media_type_copper: + if (ixgbe_device_supports_autoneg_fc(hw)) + ret_val = ixgbe_fc_autoneg_copper(hw); + break; + + default: + break; + } + +out: + if (ret_val == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = true; + } else { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + } +} + +/* + * ixgbe_pcie_timeout_poll - Return number of times to poll for completion + * @hw: pointer to hardware structure + * + * System-wide timeout range is encoded in PCIe Device Control2 register. + * + * Add 10% to specified maximum and return the number of times to poll for + * completion timeout, in units of 100 microsec. Never return less than + * 800 = 80 millisec. + */ +STATIC u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw) +{ + s16 devctl2; + u32 pollcnt; + + devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2); + devctl2 &= IXGBE_PCIDEVCTRL2_TIMEO_MASK; + + switch (devctl2) { + case IXGBE_PCIDEVCTRL2_65_130ms: + pollcnt = 1300; /* 130 millisec */ + break; + case IXGBE_PCIDEVCTRL2_260_520ms: + pollcnt = 5200; /* 520 millisec */ + break; + case IXGBE_PCIDEVCTRL2_1_2s: + pollcnt = 20000; /* 2 sec */ + break; + case IXGBE_PCIDEVCTRL2_4_8s: + pollcnt = 80000; /* 8 sec */ + break; + case IXGBE_PCIDEVCTRL2_17_34s: + pollcnt = 34000; /* 34 sec */ + break; + case IXGBE_PCIDEVCTRL2_50_100us: /* 100 microsecs */ + case IXGBE_PCIDEVCTRL2_1_2ms: /* 2 millisecs */ + case IXGBE_PCIDEVCTRL2_16_32ms: /* 32 millisec */ + case IXGBE_PCIDEVCTRL2_16_32ms_def: /* 32 millisec default */ + default: + pollcnt = 800; /* 80 millisec minimum */ + break; + } + + /* add 10% to spec maximum */ + return (pollcnt * 11) / 10; +} + +/** + * ixgbe_disable_pcie_primary - Disable PCI-express primary access + * @hw: pointer to hardware structure + * + * Disables PCI-Express primary access and verifies there are no pending + * requests. IXGBE_ERR_PRIMARY_REQUESTS_PENDING is returned if primary disable + * bit hasn't caused the primary requests to be disabled, else IXGBE_SUCCESS + * is returned signifying primary requests disabled. + **/ +s32 ixgbe_disable_pcie_primary(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u32 i, poll; + u16 value; + + DEBUGFUNC("ixgbe_disable_pcie_primary"); + + /* Always set this bit to ensure any future transactions are blocked */ + IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); + + /* Exit if primary requests are blocked */ + if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) || + IXGBE_REMOVED(hw->hw_addr)) + goto out; + + /* Poll for primary request bit to clear */ + for (i = 0; i < IXGBE_PCI_PRIMARY_DISABLE_TIMEOUT; i++) { + usec_delay(100); + if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) + goto out; + } + + /* + * Two consecutive resets are required via CTRL.RST per datasheet + * 5.2.5.3.2 Primary Disable. We set a flag to inform the reset routine + * of this need. The first reset prevents new primary requests from + * being issued by our device. We then must wait 1usec or more for any + * remaining completions from the PCIe bus to trickle in, and then reset + * again to clear out any effects they may have had on our device. + */ + hw_dbg(hw, "GIO Primary Disable bit didn't clear - requesting resets\n"); + hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + + if (hw->mac.type >= ixgbe_mac_X550) + goto out; + + /* + * Before proceeding, make sure that the PCIe block does not have + * transactions pending. + */ + poll = ixgbe_pcie_timeout_poll(hw); + for (i = 0; i < poll; i++) { + usec_delay(100); + value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS); + if (IXGBE_REMOVED(hw->hw_addr)) + goto out; + if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) + goto out; + } + + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PCIe transaction pending bit also did not clear.\n"); + status = IXGBE_ERR_PRIMARY_REQUESTS_PENDING; + +out: + return status; +} + +/** + * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore through the GSSR register for the specified + * function (CSR, PHY0, PHY1, EEPROM, Flash) + **/ +s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask) +{ + u32 gssr = 0; + u32 swmask = mask; + u32 fwmask = mask << 5; + u32 timeout = 200; + u32 i; + + DEBUGFUNC("ixgbe_acquire_swfw_sync"); + + for (i = 0; i < timeout; i++) { + /* + * SW NVM semaphore bit is used for access to all + * SW_FW_SYNC bits (not just NVM) + */ + if (ixgbe_get_eeprom_semaphore(hw)) + return IXGBE_ERR_SWFW_SYNC; + + gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); + if (!(gssr & (fwmask | swmask))) { + gssr |= swmask; + IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); + ixgbe_release_eeprom_semaphore(hw); + return IXGBE_SUCCESS; + } else { + /* Resource is currently in use by FW or SW */ + ixgbe_release_eeprom_semaphore(hw); + msec_delay(5); + } + } + + /* If time expired clear the bits holding the lock and retry */ + if (gssr & (fwmask | swmask)) + ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask)); + + msec_delay(5); + return IXGBE_ERR_SWFW_SYNC; +} + +/** + * ixgbe_release_swfw_sync - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore through the GSSR register for the specified + * function (CSR, PHY0, PHY1, EEPROM, Flash) + **/ +void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask) +{ + u32 gssr; + u32 swmask = mask; + + DEBUGFUNC("ixgbe_release_swfw_sync"); + + ixgbe_get_eeprom_semaphore(hw); + + gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); + gssr &= ~swmask; + IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); + + ixgbe_release_eeprom_semaphore(hw); +} + +/** + * ixgbe_disable_sec_rx_path_generic - Stops the receive data path + * @hw: pointer to hardware structure + * + * Stops the receive data path and waits for the HW to internally empty + * the Rx security block + **/ +s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw) +{ +#define IXGBE_MAX_SECRX_POLL 4000 + + int i; + int secrxreg; + + DEBUGFUNC("ixgbe_disable_sec_rx_path_generic"); + + secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); + secrxreg |= IXGBE_SECRXCTRL_RX_DIS; + IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg); + for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) { + secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT); + if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY) + break; + else + /* Use interrupt-safe sleep just in case */ + usec_delay(10); + } + + /* For informational purposes only */ + if (i >= IXGBE_MAX_SECRX_POLL) + hw_dbg(hw, "Rx unit being enabled before security " + "path fully disabled. Continuing with init.\n"); + + return IXGBE_SUCCESS; +} + +/** + * prot_autoc_read_generic - Hides MAC differences needed for AUTOC read + * @hw: pointer to hardware structure + * @locked: bool to indicate whether the SW/FW lock was taken + * @reg_val: Value we read from AUTOC + * + * The default case requires no protection so just to the register read. + */ +s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val) +{ + *locked = false; + *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC); + return IXGBE_SUCCESS; +} + +/** + * prot_autoc_write_generic - Hides MAC differences needed for AUTOC write + * @hw: pointer to hardware structure + * @reg_val: value to write to AUTOC + * @locked: bool to indicate whether the SW/FW lock was already taken by + * previous read. + * + * The default case requires no protection so just to the register write. + */ +s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked) +{ + UNREFERENCED_1PARAMETER(locked); + + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_val); + return IXGBE_SUCCESS; +} + +/** + * ixgbe_enable_sec_rx_path_generic - Enables the receive data path + * @hw: pointer to hardware structure + * + * Enables the receive data path. + **/ +s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw) +{ + u32 secrxreg; + + DEBUGFUNC("ixgbe_enable_sec_rx_path_generic"); + + secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); + secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS; + IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit + * @hw: pointer to hardware structure + * @regval: register value to write to RXCTRL + * + * Enables the Rx DMA unit + **/ +s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) +{ + DEBUGFUNC("ixgbe_enable_rx_dma_generic"); + + if (regval & IXGBE_RXCTRL_RXEN) + ixgbe_enable_rx(hw); + else + ixgbe_disable_rx(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_blink_led_start_generic - Blink LED based on index. + * @hw: pointer to hardware structure + * @index: led number to blink + **/ +s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) +{ + ixgbe_link_speed speed = 0; + bool link_up = 0; + u32 autoc_reg = 0; + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + s32 ret_val = IXGBE_SUCCESS; + bool locked = false; + + DEBUGFUNC("ixgbe_blink_led_start_generic"); + + if (index > 3) + return IXGBE_ERR_PARAM; + + /* + * Link must be up to auto-blink the LEDs; + * Force it if link is down. + */ + hw->mac.ops.check_link(hw, &speed, &link_up, false); + + if (!link_up) { + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); + if (ret_val != IXGBE_SUCCESS) + goto out; + + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + autoc_reg |= IXGBE_AUTOC_FLU; + + ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked); + if (ret_val != IXGBE_SUCCESS) + goto out; + + IXGBE_WRITE_FLUSH(hw); + msec_delay(10); + } + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg |= IXGBE_LED_BLINK(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + +out: + return ret_val; +} + +/** + * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. + * @hw: pointer to hardware structure + * @index: led number to stop blinking + **/ +s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 autoc_reg = 0; + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + s32 ret_val = IXGBE_SUCCESS; + bool locked = false; + + DEBUGFUNC("ixgbe_blink_led_stop_generic"); + + if (index > 3) + return IXGBE_ERR_PARAM; + + ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); + if (ret_val != IXGBE_SUCCESS) + goto out; + + autoc_reg &= ~IXGBE_AUTOC_FLU; + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + + ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked); + if (ret_val != IXGBE_SUCCESS) + goto out; + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg &= ~IXGBE_LED_BLINK(index); + led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + +out: + return ret_val; +} + +/** + * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM + * @hw: pointer to hardware structure + * @san_mac_offset: SAN MAC address offset + * + * This function will read the EEPROM location for the SAN MAC address + * pointer, and returns the value at that location. This is used in both + * get and set mac_addr routines. + **/ +STATIC s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, + u16 *san_mac_offset) +{ + s32 ret_val; + + DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); + + /* + * First read the EEPROM pointer to see if the MAC addresses are + * available. + */ + ret_val = hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, + san_mac_offset); + if (ret_val) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom at offset %d failed", + IXGBE_SAN_MAC_ADDR_PTR); + } + + return ret_val; +} + +/** + * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Reads the SAN MAC address from the EEPROM, if it's available. This is + * per-port, so set_lan_id() must be called before reading the addresses. + * set_lan_id() is called by identify_sfp(), but this cannot be relied + * upon for non-SFP connections, so we must call it here. + **/ +s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + u16 san_mac_data, san_mac_offset; + u8 i; + s32 ret_val; + + DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); + + /* + * First read the EEPROM pointer to see if the MAC addresses are + * available. If they're not, no point in calling set_lan_id() here. + */ + ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); + if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF) + goto san_mac_addr_out; + + /* make sure we know which port we need to program */ + hw->mac.ops.set_lan_id(hw); + /* apply the port offset to the address offset */ + (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : + (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); + for (i = 0; i < 3; i++) { + ret_val = hw->eeprom.ops.read(hw, san_mac_offset, + &san_mac_data); + if (ret_val) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", + san_mac_offset); + goto san_mac_addr_out; + } + san_mac_addr[i * 2] = (u8)(san_mac_data); + san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); + san_mac_offset++; + } + return IXGBE_SUCCESS; + +san_mac_addr_out: + /* + * No addresses available in this EEPROM. It's not an + * error though, so just wipe the local address and return. + */ + for (i = 0; i < 6; i++) + san_mac_addr[i] = 0xFF; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Write a SAN MAC address to the EEPROM. + **/ +s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + s32 ret_val; + u16 san_mac_data, san_mac_offset; + u8 i; + + DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); + + /* Look for SAN mac address pointer. If not defined, return */ + ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); + if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF) + return IXGBE_ERR_NO_SAN_ADDR_PTR; + + /* Make sure we know which port we need to write */ + hw->mac.ops.set_lan_id(hw); + /* Apply the port offset to the address offset */ + (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : + (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); + + for (i = 0; i < 3; i++) { + san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8); + san_mac_data |= (u16)(san_mac_addr[i * 2]); + hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); + san_mac_offset++; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count + * @hw: pointer to hardware structure + * + * Read PCIe configuration space, and get the MSI-X vector count from + * the capabilities table. + **/ +u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) +{ + u16 msix_count = 1; + u16 max_msix_count; + u16 pcie_offset; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS; + max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598; + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; + max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; + break; + case ixgbe_mac_E610: + pcie_offset = IXGBE_PCIE_MSIX_LKV_CAPS; + max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; + break; + default: + return msix_count; + } + + DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); + msix_count = IXGBE_READ_PCIE_WORD(hw, pcie_offset); + if (IXGBE_REMOVED(hw->hw_addr)) + msix_count = 0; + msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; + + /* MSI-X count is zero-based in HW */ + msix_count++; + + if (msix_count > max_msix_count) + msix_count = max_msix_count; + + return msix_count; +} + +/** + * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address + * @hw: pointer to hardware structure + * @addr: Address to put into receive address register + * @vmdq: VMDq pool to assign + * + * Puts an ethernet address into a receive address register, or + * finds the rar that it is aleady in; adds to the pool list + **/ +s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) +{ + static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF; + u32 first_empty_rar = NO_EMPTY_RAR_FOUND; + u32 rar; + u32 rar_low, rar_high; + u32 addr_low, addr_high; + + DEBUGFUNC("ixgbe_insert_mac_addr_generic"); + + /* swap bytes for HW little endian */ + addr_low = addr[0] | (addr[1] << 8) + | (addr[2] << 16) + | (addr[3] << 24); + addr_high = addr[4] | (addr[5] << 8); + + /* + * Either find the mac_id in rar or find the first empty space. + * rar_highwater points to just after the highest currently used + * rar in order to shorten the search. It grows when we add a new + * rar to the top. + */ + for (rar = 0; rar < hw->mac.rar_highwater; rar++) { + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + + if (((IXGBE_RAH_AV & rar_high) == 0) + && first_empty_rar == NO_EMPTY_RAR_FOUND) { + first_empty_rar = rar; + } else if ((rar_high & 0xFFFF) == addr_high) { + rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar)); + if (rar_low == addr_low) + break; /* found it already in the rars */ + } + } + + if (rar < hw->mac.rar_highwater) { + /* already there so just add to the pool bits */ + ixgbe_set_vmdq(hw, rar, vmdq); + } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { + /* stick it into first empty RAR slot we found */ + rar = first_empty_rar; + ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); + } else if (rar == hw->mac.rar_highwater) { + /* add it to the top of the list and inc the highwater mark */ + ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); + hw->mac.rar_highwater++; + } else if (rar >= hw->mac.num_rar_entries) { + return IXGBE_ERR_INVALID_MAC_ADDR; + } + + /* + * If we found rar[0], make sure the default pool bit (we use pool 0) + * remains cleared to be sure default pool packets will get delivered + */ + if (rar == 0) + ixgbe_clear_vmdq(hw, rar, 0); + + return rar; +} + +/** + * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to disassociate + * @vmdq: VMDq pool index to remove from the rar + **/ +s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 mpsar_lo, mpsar_hi; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_clear_vmdq_generic"); + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, + "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + + if (IXGBE_REMOVED(hw->hw_addr)) + goto done; + + if (!mpsar_lo && !mpsar_hi) + goto done; + + if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { + if (mpsar_lo) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); + mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + } + if (mpsar_hi) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); + mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + } + } else if (vmdq < 32) { + mpsar_lo &= ~(1 << vmdq); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); + } else { + mpsar_hi &= ~(1 << (vmdq - 32)); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); + } + + /* was that the last pool using this rar? */ + if (mpsar_lo == 0 && mpsar_hi == 0 && + rar != 0 && rar != hw->mac.san_mac_rar_index) + hw->mac.ops.clear_rar(hw, rar); +done: + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq pool index + **/ +s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 mpsar; + u32 rar_entries = hw->mac.num_rar_entries; + + DEBUGFUNC("ixgbe_set_vmdq_generic"); + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, + "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + if (vmdq < 32) { + mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + mpsar |= 1 << vmdq; + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); + } else { + mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + mpsar |= 1 << (vmdq - 32); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_vmdq_san_mac_generic - Associate default VMDq pool index with + * a rx address + * @hw: pointer to hardware struct + * @vmdq: VMDq pool index + * + * This function should only be involved in the IOV mode. + * In IOV mode, Default pool is next pool after the number of + * VFs advertized and not 0. + * MPSAR table needs to be updated for SAN_MAC RAR [hw->mac.san_mac_rar_index] + **/ +s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq) +{ + u32 rar = hw->mac.san_mac_rar_index; + + DEBUGFUNC("ixgbe_set_vmdq_san_mac"); + + if (vmdq < 32) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 1 << vmdq); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); + } else { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 1 << (vmdq - 32)); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array + * @hw: pointer to hardware structure + **/ +s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) +{ + int i; + + DEBUGFUNC("ixgbe_init_uta_tables_generic"); + hw_dbg(hw, " Clearing UTA\n"); + + for (i = 0; i < 128; i++) + IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vlvf_bypass: true to find vlanid only, false returns first empty slot if + * vlanid not found + * + * + * return the VLVF index where this VLAN id should be placed + * + **/ +s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass) +{ + s32 regindex, first_empty_slot; + u32 bits; + + /* short cut the special case */ + if (vlan == 0) + return 0; + + /* if vlvf_bypass is set we don't want to use an empty slot, we + * will simply bypass the VLVF if there are no entries present in the + * VLVF that contain our VLAN + */ + first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0; + + /* add VLAN enable bit for comparison */ + vlan |= IXGBE_VLVF_VIEN; + + /* Search for the vlan id in the VLVF entries. Save off the first empty + * slot found along the way. + * + * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1 + */ + for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) { + bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); + if (bits == vlan) + return regindex; + if (!first_empty_slot && !bits) + first_empty_slot = regindex; + } + + /* If we are here then we didn't find the VLAN. Return first empty + * slot we found during our search, else error. + */ + if (!first_empty_slot) + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "No space in VLVF.\n"); + + return first_empty_slot ? first_empty_slot : IXGBE_ERR_NO_SPACE; +} + +/** + * ixgbe_set_vfta_generic - Set VLAN filter table + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN + * @vlvf_bypass: boolean flag indicating updating default pool is okay + * + * Turn on/off specified VLAN in the VLAN filter table. + **/ +s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, bool vlvf_bypass) +{ + u32 regidx, vfta_delta, vfta; + s32 ret_val; + + DEBUGFUNC("ixgbe_set_vfta_generic"); + + if (vlan > 4095 || vind > 63) + return IXGBE_ERR_PARAM; + + /* + * this is a 2 part operation - first the VFTA, then the + * VLVF and VLVFB if VT Mode is set + * We don't write the VFTA until we know the VLVF part succeeded. + */ + + /* Part 1 + * The VFTA is a bitstring made up of 128 32-bit registers + * that enable the particular VLAN id, much like the MTA: + * bits[11-5]: which register + * bits[4-0]: which bit in the register + */ + regidx = vlan / 32; + vfta_delta = 1 << (vlan % 32); + vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx)); + + /* + * vfta_delta represents the difference between the current value + * of vfta and the value we want in the register. Since the diff + * is an XOR mask we can just update the vfta using an XOR + */ + vfta_delta &= vlan_on ? ~vfta : vfta; + vfta ^= vfta_delta; + + /* Part 2 + * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF + */ + ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, &vfta_delta, + vfta, vlvf_bypass); + if (ret_val != IXGBE_SUCCESS) { + if (vlvf_bypass) + goto vfta_update; + return ret_val; + } + +vfta_update: + /* Update VFTA now that we are ready for traffic */ + if (vfta_delta) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_vlvf_generic - Set VLAN Pool Filter + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VLVFB + * @vlan_on: boolean flag to turn on/off VLAN in VLVF + * @vfta_delta: pointer to the difference between the current value of VFTA + * and the desired value + * @vfta: the desired value of the VFTA + * @vlvf_bypass: boolean flag indicating updating default pool is okay + * + * Turn on/off specified bit in VLVF table. + **/ +s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, u32 *vfta_delta, u32 vfta, + bool vlvf_bypass) +{ + u32 bits; + s32 vlvf_index; + + DEBUGFUNC("ixgbe_set_vlvf_generic"); + + if (vlan > 4095 || vind > 63) + return IXGBE_ERR_PARAM; + + /* If VT Mode is set + * Either vlan_on + * make sure the vlan is in VLVF + * set the vind bit in the matching VLVFB + * Or !vlan_on + * clear the pool bit and possibly the vind + */ + if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE)) + return IXGBE_SUCCESS; + + vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass); + if (vlvf_index < 0) + return vlvf_index; + + bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32)); + + /* set the pool bit */ + bits |= 1 << (vind % 32); + if (vlan_on) + goto vlvf_update; + + /* clear the pool bit */ + bits ^= 1 << (vind % 32); + + if (!bits && + !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) { + /* Clear VFTA first, then disable VLVF. Otherwise + * we run the risk of stray packets leaking into + * the PF via the default pool + */ + if (*vfta_delta) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(vlan / 32), vfta); + + /* disable VLVF and clear remaining bit from pool */ + IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0); + + return IXGBE_SUCCESS; + } + + /* If there are still bits set in the VLVFB registers + * for the VLAN ID indicated we need to see if the + * caller is requesting that we clear the VFTA entry bit. + * If the caller has requested that we clear the VFTA + * entry bit but there are still pools/VFs using this VLAN + * ID entry then ignore the request. We're not worried + * about the case where we're turning the VFTA VLAN ID + * entry bit on, only when requested to turn it off as + * there may be multiple pools and/or VFs using the + * VLAN ID entry. In that case we cannot clear the + * VFTA bit until all pools/VFs using that VLAN ID have also + * been cleared. This will be indicated by "bits" being + * zero. + */ + *vfta_delta = 0; + +vlvf_update: + /* record pool change and enable VLAN ID if not already enabled */ + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits); + IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_vfta_generic - Clear VLAN filter table + * @hw: pointer to hardware structure + * + * Clears the VLAN filer table, and the VMDq index associated with the filter + **/ +s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) +{ + u32 offset; + + DEBUGFUNC("ixgbe_clear_vfta_generic"); + + for (offset = 0; offset < hw->mac.vft_size; offset++) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); + + for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { + IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_toggle_txdctl_generic - Toggle VF's queues + * @hw: pointer to hardware structure + * @vf_number: VF index + * + * Enable and disable each queue in VF. + */ +s32 ixgbe_toggle_txdctl_generic(struct ixgbe_hw *hw, u32 vf_number) +{ + u8 queue_count, i; + u32 offset, reg; + + if (vf_number > 63) + return IXGBE_ERR_PARAM; + + /* + * Determine number of queues by checking + * number of virtual functions + */ + reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + switch (reg & IXGBE_GCR_EXT_VT_MODE_MASK) { + case IXGBE_GCR_EXT_VT_MODE_64: + queue_count = 2; + break; + case IXGBE_GCR_EXT_VT_MODE_32: + queue_count = 4; + break; + case IXGBE_GCR_EXT_VT_MODE_16: + queue_count = 8; + break; + default: + return IXGBE_ERR_CONFIG; + } + + /* Toggle queues */ + for (i = 0; i < queue_count; ++i) { + /* Calculate offset of current queue */ + offset = queue_count * vf_number + i; + + /* Enable queue */ + reg = IXGBE_READ_REG(hw, IXGBE_PVFTXDCTL(offset)); + reg |= IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(offset), reg); + IXGBE_WRITE_FLUSH(hw); + + /* Disable queue */ + reg = IXGBE_READ_REG(hw, IXGBE_PVFTXDCTL(offset)); + reg &= ~IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(offset), reg); + IXGBE_WRITE_FLUSH(hw); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix + * @hw: pointer to hardware structure + * + * Contains the logic to identify if we need to verify link for the + * crosstalk fix + **/ +static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw) +{ + + /* Does FW say we need the fix */ + if (!hw->need_crosstalk_fix) + return false; + + /* Only consider SFP+ PHYs i.e. media type fiber */ + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_fiber_qsfp: + break; + default: + return false; + } + + return true; +} + +/** + * ixgbe_check_mac_link_generic - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Reads the links register to determine if link is up and the current speed + **/ +s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + u32 links_reg, links_orig; + u32 i; + + DEBUGFUNC("ixgbe_check_mac_link_generic"); + + /* If Crosstalk fix enabled do the sanity check of making sure + * the SFP+ cage is full. + */ + if (ixgbe_need_crosstalk_fix(hw)) { + u32 sfp_cage_full; + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP2; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP0; + break; + default: + /* sanity check - No SFP+ devices here */ + sfp_cage_full = false; + break; + } + + if (!sfp_cage_full) { + *link_up = false; + *speed = IXGBE_LINK_SPEED_UNKNOWN; + return IXGBE_SUCCESS; + } + } + + /* clear the old state */ + links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); + + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + + if (links_orig != links_reg) { + hw_dbg(hw, "LINKS changed from %08X to %08X\n", + links_orig, links_reg); + } + + if (link_up_wait_to_complete) { + for (i = 0; i < hw->mac.max_link_up_time; i++) { + if (links_reg & IXGBE_LINKS_UP) { + *link_up = true; + break; + } else { + *link_up = false; + } + msec_delay(100); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + } + } else { + if (links_reg & IXGBE_LINKS_UP) { + if (ixgbe_need_crosstalk_fix(hw)) { + /* Check the link state again after a delay + * to filter out spurious link up + * notifications. + */ + msec_delay(5); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + if (!(links_reg & IXGBE_LINKS_UP)) { + *link_up = false; + *speed = IXGBE_LINK_SPEED_UNKNOWN; + return IXGBE_SUCCESS; + } + + } + *link_up = true; + } else { + *link_up = false; + } + } + + switch (links_reg & IXGBE_LINKS_SPEED_82599) { + case IXGBE_LINKS_SPEED_10G_82599: + *speed = IXGBE_LINK_SPEED_10GB_FULL; + if (hw->mac.type >= ixgbe_mac_X550) { + if (links_reg & IXGBE_LINKS_SPEED_NON_STD) + *speed = IXGBE_LINK_SPEED_2_5GB_FULL; + } + break; + case IXGBE_LINKS_SPEED_1G_82599: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + case IXGBE_LINKS_SPEED_100_82599: + if (links_reg & IXGBE_LINKS_SPEED_NON_STD && + (hw->mac.type == ixgbe_mac_X550 || + ixgbe_is_mac_E6xx(hw->mac.type))) + *speed = IXGBE_LINK_SPEED_5GB_FULL; + else + *speed = IXGBE_LINK_SPEED_100_FULL; + break; + case IXGBE_LINKS_SPEED_10_X550EM_A: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || + hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) + *speed = IXGBE_LINK_SPEED_10_FULL; + break; + default: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from + * the EEPROM + * @hw: pointer to hardware structure + * @wwnn_prefix: the alternative WWNN prefix + * @wwpn_prefix: the alternative WWPN prefix + * + * This function will read the EEPROM from the alternative SAN MAC address + * block to check the support for the alternative WWNN/WWPN prefix support. + **/ +s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix) +{ + u16 offset, caps; + u16 alt_san_mac_blk_offset; + + DEBUGFUNC("ixgbe_get_wwn_prefix_generic"); + + /* clear output first */ + *wwnn_prefix = 0xFFFF; + *wwpn_prefix = 0xFFFF; + + /* check if alternative SAN MAC is supported */ + offset = IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR; + if (hw->eeprom.ops.read(hw, offset, &alt_san_mac_blk_offset)) + goto wwn_prefix_err; + + if ((alt_san_mac_blk_offset == 0) || + (alt_san_mac_blk_offset == 0xFFFF)) + goto wwn_prefix_out; + + /* check capability in alternative san mac address block */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; + if (hw->eeprom.ops.read(hw, offset, &caps)) + goto wwn_prefix_err; + if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) + goto wwn_prefix_out; + + /* get the corresponding prefix for WWNN/WWPN */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; + if (hw->eeprom.ops.read(hw, offset, wwnn_prefix)) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", offset); + } + + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; + if (hw->eeprom.ops.read(hw, offset, wwpn_prefix)) + goto wwn_prefix_err; + +wwn_prefix_out: + return IXGBE_SUCCESS; + +wwn_prefix_err: + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", offset); + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM + * @hw: pointer to hardware structure + * @bs: the fcoe boot status + * + * This function will read the FCOE boot status from the iSCSI FCOE block + **/ +s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs) +{ + u16 offset, caps, flags; + s32 status; + + DEBUGFUNC("ixgbe_get_fcoe_boot_status_generic"); + + /* clear output first */ + *bs = ixgbe_fcoe_bootstatus_unavailable; + + /* check if FCOE IBA block is present */ + offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR; + status = hw->eeprom.ops.read(hw, offset, &caps); + if (status != IXGBE_SUCCESS) + goto out; + + if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE)) + goto out; + + /* check if iSCSI FCOE block is populated */ + status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset); + if (status != IXGBE_SUCCESS) + goto out; + + if ((offset == 0) || (offset == 0xFFFF)) + goto out; + + /* read fcoe flags in iSCSI FCOE block */ + offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET; + status = hw->eeprom.ops.read(hw, offset, &flags); + if (status != IXGBE_SUCCESS) + goto out; + + if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE) + *bs = ixgbe_fcoe_bootstatus_enabled; + else + *bs = ixgbe_fcoe_bootstatus_disabled; + +out: + return status; +} + +/** + * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for MAC anti-spoofing + * @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing + * + **/ +void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) +{ + int vf_target_reg = vf >> 3; + int vf_target_shift = vf % 8; + u32 pfvfspoof; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); + if (enable) + pfvfspoof |= (1 << vf_target_shift); + else + pfvfspoof &= ~(1 << vf_target_shift); + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); +} + +/** + * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for VLAN anti-spoofing + * @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing + * + **/ +void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) +{ + int vf_target_reg = vf >> 3; + int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT; + u32 pfvfspoof; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); + if (enable) + pfvfspoof |= (1 << vf_target_shift); + else + pfvfspoof &= ~(1 << vf_target_shift); + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); +} + +/** + * ixgbe_get_device_caps_generic - Get additional device capabilities + * @hw: pointer to hardware structure + * @device_caps: the EEPROM word with the extra device capabilities + * + * This function will read the EEPROM location for the device capabilities, + * and return the word through device_caps. + **/ +s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps) +{ + DEBUGFUNC("ixgbe_get_device_caps_generic"); + + hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_calculate_checksum - Calculate checksum for buffer + * @buffer: pointer to EEPROM + * @length: size of EEPROM to calculate a checksum for + * Calculates the checksum for some buffer on a specified length. The + * checksum calculated is returned. + **/ +u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) +{ + u32 i; + u8 sum = 0; + + DEBUGFUNC("ixgbe_calculate_checksum"); + + if (!buffer) + return 0; + + for (i = 0; i < length; i++) + sum += buffer[i]; + + return (u8) (0 - sum); +} + +/** + * ixgbe_hic_unlocked - Issue command to manageability block unlocked + * @hw: pointer to the HW structure + * @buffer: command to write and where the return status will be placed + * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion + * + * Communicates with the manageability block. On success return IXGBE_SUCCESS + * else returns semaphore error when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * + * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held + * by the caller. + **/ +s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, + u32 timeout) +{ + u32 hicr, i, fwsts; + u16 dword_len; + + DEBUGFUNC("ixgbe_hic_unlocked"); + + if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + hw_dbg(hw, "Buffer length failure buffersize=%d.\n", length); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Set bit 9 of FWSTS clearing FW reset indication */ + fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); + IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI); + + /* Check that the host interface is enabled. */ + hicr = IXGBE_READ_REG(hw, IXGBE_HICR); + if (!(hicr & IXGBE_HICR_EN)) { + hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n"); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Calculate length in DWORDs. We must be DWORD aligned */ + if (length % sizeof(u32)) { + hw_dbg(hw, "Buffer length failure, not aligned to dword"); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + dword_len = length >> 2; + + /* The device driver writes the relevant command block + * into the ram area. + */ + for (i = 0; i < dword_len; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, + i, IXGBE_CPU_TO_LE32(buffer[i])); + + /* Setting this bit tells the ARC that a new command is pending. */ + IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); + + for (i = 0; i < timeout; i++) { + hicr = IXGBE_READ_REG(hw, IXGBE_HICR); + if (!(hicr & IXGBE_HICR_C)) + break; + msec_delay(1); + } + + /* For each command except "Apply Update" perform + * status checks in the HICR registry. + */ + if ((buffer[0] & IXGBE_HOST_INTERFACE_MASK_CMD) == + IXGBE_HOST_INTERFACE_APPLY_UPDATE_CMD) + return IXGBE_SUCCESS; + + /* Check command completion */ + if ((timeout && i == timeout) || + !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { + ERROR_REPORT1(IXGBE_ERROR_CAUTION, + "Command has failed with no status valid.\n"); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_host_interface_command - Issue command to manageability block + * @hw: pointer to the HW structure + * @buffer: contains the command to write and where the return status will + * be placed + * @length: length of buffer, must be multiple of 4 bytes + * @timeout: time in ms to wait for command completion + * @return_data: read and return data from the buffer (true) or not (false) + * Needed because FW structures are big endian and decoding of + * these fields can be 8 bit or 16 bit based on command. Decoding + * is not easily understood without making a table of commands. + * So we will leave this up to the caller to read back the data + * in these cases. + * + * Communicates with the manageability block. On success return IXGBE_SUCCESS + * else returns semaphore error when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, + u32 length, u32 timeout, bool return_data) +{ + u32 hdr_size = sizeof(struct ixgbe_hic_hdr); + struct ixgbe_hic_hdr *resp = (struct ixgbe_hic_hdr *)buffer; + u16 buf_len; + s32 status; + u32 bi; + u32 dword_len; + + DEBUGFUNC("ixgbe_host_interface_command"); + + if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + hw_dbg(hw, "Buffer length failure buffersize=%d.\n", length); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + /* Take management host interface semaphore */ + status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); + if (status) + return status; + + status = ixgbe_hic_unlocked(hw, buffer, length, timeout); + if (status) + goto rel_out; + + if (!return_data) + goto rel_out; + + /* Calculate length in DWORDs */ + dword_len = hdr_size >> 2; + + /* first pull in the header so we know the buffer length */ + for (bi = 0; bi < dword_len; bi++) { + buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); + IXGBE_LE32_TO_CPUS(&buffer[bi]); + } + + /* + * If there is any thing in data position pull it in + * Read Flash command requires reading buffer length from + * two byes instead of one byte + */ + if (resp->cmd == 0x30 || resp->cmd == 0x31) { + for (; bi < dword_len + 2; bi++) { + buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, + bi); + IXGBE_LE32_TO_CPUS(&buffer[bi]); + } + buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3) + & 0xF00) | resp->buf_len; + hdr_size += (2 << 2); + } else { + buf_len = resp->buf_len; + } + if (!buf_len) + goto rel_out; + + if (length < buf_len + hdr_size) { + hw_dbg(hw, "Buffer not large enough for reply message.\n"); + status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; + } + + /* Calculate length in DWORDs, add 3 for odd lengths */ + dword_len = (buf_len + 3) >> 2; + + /* Pull in the rest of the buffer (bi is where we left off) */ + for (; bi <= dword_len; bi++) { + buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); + IXGBE_LE32_TO_CPUS(&buffer[bi]); + } + +rel_out: + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); + + return status; +} + +/** + * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware + * @hw: pointer to the HW structure + * @maj: driver version major number + * @min: driver version minor number + * @build: driver version build number + * @sub: driver version sub build number + * @len: unused + * @driver_ver: unused + * + * Sends driver version number to firmware through the manageability + * block. On success return IXGBE_SUCCESS + * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 sub, u16 len, + const char *driver_ver) +{ + struct ixgbe_hic_drv_info fw_cmd; + int i; + s32 ret_val = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_set_fw_drv_ver_generic"); + UNREFERENCED_2PARAMETER(len, driver_ver); + + fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; + fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; + fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; + fw_cmd.port_num = (u8)hw->bus.func; + fw_cmd.ver_maj = maj; + fw_cmd.ver_min = min; + fw_cmd.ver_build = build; + fw_cmd.ver_sub = sub; + fw_cmd.hdr.checksum = 0; + fw_cmd.pad = 0; + fw_cmd.pad2 = 0; + fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd, + (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); + + for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { + ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, + sizeof(fw_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + true); + if (ret_val != IXGBE_SUCCESS) + continue; + + if (fw_cmd.hdr.cmd_or_resp.ret_status == + FW_CEM_RESP_STATUS_SUCCESS) + ret_val = IXGBE_SUCCESS; + else + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + + break; + } + + return ret_val; +} + +/** + * ixgbe_set_rxpba_generic - Initialize Rx packet buffer + * @hw: pointer to hardware structure + * @num_pb: number of packet buffers to allocate + * @headroom: reserve n KB of headroom + * @strategy: packet buffer allocation strategy + **/ +void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom, + int strategy) +{ + u32 pbsize = hw->mac.rx_pb_size; + int i = 0; + u32 rxpktsize, txpktsize, txpbthresh; + + /* Reserve headroom */ + pbsize -= headroom; + + if (!num_pb) + num_pb = 1; + + /* Divide remaining packet buffer space amongst the number of packet + * buffers requested using supplied strategy. + */ + switch (strategy) { + case PBA_STRATEGY_WEIGHTED: + /* ixgbe_dcb_pba_80_48 strategy weight first half of packet + * buffer with 5/8 of the packet buffer space. + */ + rxpktsize = (pbsize * 5) / (num_pb * 4); + pbsize -= rxpktsize * (num_pb / 2); + rxpktsize <<= IXGBE_RXPBSIZE_SHIFT; + for (; i < (num_pb / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + fallthrough; /* configure remaining packet buffers */ + case PBA_STRATEGY_EQUAL: + rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT; + for (; i < num_pb; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + break; + default: + break; + } + + /* Only support an equally distributed Tx packet buffer strategy. */ + txpktsize = IXGBE_TXPBSIZE_MAX / num_pb; + txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX; + for (i = 0; i < num_pb; i++) { + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize); + IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh); + } + + /* Clear unused TCs, if any, to zero buffer size*/ + for (; i < IXGBE_MAX_PB; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0); + } +} + +/** + * ixgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo + * @hw: pointer to the hardware structure + * + * The 82599 and x540 MACs can experience issues if TX work is still pending + * when a reset occurs. This function prevents this by flushing the PCIe + * buffers on the system. + **/ +void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) +{ + u32 gcr_ext, hlreg0, i, poll; + u16 value; + + /* + * If double reset is not requested then all transactions should + * already be clear and as such there is no work to do + */ + if (!(hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED)) + return; + + /* + * Set loopback enable to prevent any transmits from being sent + * should the link come up. This assumes that the RXCTRL.RXEN bit + * has already been cleared. + */ + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK); + + /* Wait for a last completion before clearing buffers */ + IXGBE_WRITE_FLUSH(hw); + msec_delay(3); + + /* + * Before proceeding, make sure that the PCIe block does not have + * transactions pending. + */ + poll = ixgbe_pcie_timeout_poll(hw); + for (i = 0; i < poll; i++) { + usec_delay(100); + value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS); + if (IXGBE_REMOVED(hw->hw_addr)) + goto out; + if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) + goto out; + } + +out: + /* initiate cleaning flow for buffers in the PCIe transaction layer */ + gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, + gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR); + + /* Flush all writes and allow 20usec for all transactions to clear */ + IXGBE_WRITE_FLUSH(hw); + usec_delay(20); + + /* restore previous register values */ + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); +} + +STATIC const u8 ixgbe_emc_temp_data[4] = { + IXGBE_EMC_INTERNAL_DATA, + IXGBE_EMC_DIODE1_DATA, + IXGBE_EMC_DIODE2_DATA, + IXGBE_EMC_DIODE3_DATA +}; +STATIC const u8 ixgbe_emc_therm_limit[4] = { + IXGBE_EMC_INTERNAL_THERM_LIMIT, + IXGBE_EMC_DIODE1_THERM_LIMIT, + IXGBE_EMC_DIODE2_THERM_LIMIT, + IXGBE_EMC_DIODE3_THERM_LIMIT +}; + +/** + * ixgbe_get_thermal_sensor_data_generic - Gathers thermal sensor data + * @hw: pointer to hardware structure + * + * Returns the thermal sensor data structure + **/ +s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 ets_offset; + u16 ets_cfg; + u16 ets_sensor; + u8 num_sensors; + u8 sensor_index; + u8 sensor_location; + u8 i; + struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; + + DEBUGFUNC("ixgbe_get_thermal_sensor_data_generic"); + + /* Only support thermal sensors attached to 82599 physical port 0 */ + if ((hw->mac.type != ixgbe_mac_82599EB) || + (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) { + status = IXGBE_NOT_IMPLEMENTED; + goto out; + } + + status = hw->eeprom.ops.read(hw, IXGBE_ETS_CFG, &ets_offset); + if (status) + goto out; + + if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) { + status = IXGBE_NOT_IMPLEMENTED; + goto out; + } + + status = hw->eeprom.ops.read(hw, ets_offset, &ets_cfg); + if (status) + goto out; + + if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT) + != IXGBE_ETS_TYPE_EMC) { + status = IXGBE_NOT_IMPLEMENTED; + goto out; + } + + num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK); + if (num_sensors > IXGBE_MAX_SENSORS) + num_sensors = IXGBE_MAX_SENSORS; + + for (i = 0; i < num_sensors; i++) { + status = hw->eeprom.ops.read(hw, (ets_offset + 1 + i), + &ets_sensor); + if (status) + goto out; + + sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >> + IXGBE_ETS_DATA_INDEX_SHIFT); + sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >> + IXGBE_ETS_DATA_LOC_SHIFT); + + if (sensor_location != 0) { + status = hw->phy.ops.read_i2c_byte(hw, + ixgbe_emc_temp_data[sensor_index], + IXGBE_I2C_THERMAL_SENSOR_ADDR, + &data->sensor[i].temp); + if (status) + goto out; + } + } +out: + return status; +} + +/** + * ixgbe_init_thermal_sensor_thresh_generic - Inits thermal sensor thresholds + * @hw: pointer to hardware structure + * + * Inits the thermal sensor thresholds according to the NVM map + * and save off the threshold and location values into mac.thermal_sensor_data + **/ +s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 offset; + u16 ets_offset; + u16 ets_cfg; + u16 ets_sensor; + u8 low_thresh_delta; + u8 num_sensors; + u8 sensor_index; + u8 sensor_location; + u8 therm_limit; + u8 i; + struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; + + DEBUGFUNC("ixgbe_init_thermal_sensor_thresh_generic"); + + memset(data, 0, sizeof(struct ixgbe_thermal_sensor_data)); + + /* Only support thermal sensors attached to 82599 physical port 0 */ + if ((hw->mac.type != ixgbe_mac_82599EB) || + (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) + return IXGBE_NOT_IMPLEMENTED; + + offset = IXGBE_ETS_CFG; + if (hw->eeprom.ops.read(hw, offset, &ets_offset)) + goto eeprom_err; + if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) + return IXGBE_NOT_IMPLEMENTED; + + offset = ets_offset; + if (hw->eeprom.ops.read(hw, offset, &ets_cfg)) + goto eeprom_err; + if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT) + != IXGBE_ETS_TYPE_EMC) + return IXGBE_NOT_IMPLEMENTED; + + low_thresh_delta = ((ets_cfg & IXGBE_ETS_LTHRES_DELTA_MASK) >> + IXGBE_ETS_LTHRES_DELTA_SHIFT); + num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK); + + for (i = 0; i < num_sensors; i++) { + offset = ets_offset + 1 + i; + if (hw->eeprom.ops.read(hw, offset, &ets_sensor)) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", + offset); + continue; + } + sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >> + IXGBE_ETS_DATA_INDEX_SHIFT); + sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >> + IXGBE_ETS_DATA_LOC_SHIFT); + therm_limit = ets_sensor & IXGBE_ETS_DATA_HTHRESH_MASK; + + hw->phy.ops.write_i2c_byte(hw, + ixgbe_emc_therm_limit[sensor_index], + IXGBE_I2C_THERMAL_SENSOR_ADDR, therm_limit); + + if ((i < IXGBE_MAX_SENSORS) && (sensor_location != 0)) { + data->sensor[i].location = sensor_location; + data->sensor[i].caution_thresh = therm_limit; + data->sensor[i].max_op_thresh = therm_limit - + low_thresh_delta; + } + } + return status; + +eeprom_err: + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", offset); + return IXGBE_NOT_IMPLEMENTED; +} + +/** + * ixgbe_get_orom_version - Return option ROM from EEPROM + * + * @hw: pointer to hardware structure + * @nvm_ver: pointer to output structure + * + * if valid option ROM version, nvm_ver->or_valid set to true + * else nvm_ver->or_valid is false. + **/ +void ixgbe_get_orom_version(struct ixgbe_hw *hw, + struct ixgbe_nvm_version *nvm_ver) +{ + u16 offset, eeprom_cfg_blkh, eeprom_cfg_blkl; + + nvm_ver->or_valid = false; + /* Option Rom may or may not be present. Start with pointer */ + hw->eeprom.ops.read(hw, NVM_OROM_OFFSET, &offset); + + /* make sure offset is valid */ + if ((offset == 0x0) || (offset == NVM_INVALID_PTR)) + return; + + hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_HI, &eeprom_cfg_blkh); + hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_LOW, &eeprom_cfg_blkl); + + /* option rom exists and is valid */ + if ((eeprom_cfg_blkl | eeprom_cfg_blkh) == 0x0 || + eeprom_cfg_blkl == NVM_VER_INVALID || + eeprom_cfg_blkh == NVM_VER_INVALID) + return; + + nvm_ver->or_valid = true; + nvm_ver->or_major = eeprom_cfg_blkl >> NVM_OROM_SHIFT; + nvm_ver->or_build = (eeprom_cfg_blkl << NVM_OROM_SHIFT) | + (eeprom_cfg_blkh >> NVM_OROM_SHIFT); + nvm_ver->or_patch = eeprom_cfg_blkh & NVM_OROM_PATCH_MASK; +} + +/** + * ixgbe_get_oem_prod_version - Return OEM Product version + * + * @hw: pointer to hardware structure + * @nvm_ver: pointer to output structure + * + * if valid OEM product version, nvm_ver->oem_valid set to true + * else nvm_ver->oem_valid is false. + **/ +void ixgbe_get_oem_prod_version(struct ixgbe_hw *hw, + struct ixgbe_nvm_version *nvm_ver) +{ + u16 rel_num, prod_ver, mod_len, cap, offset; + + nvm_ver->oem_valid = false; + hw->eeprom.ops.read(hw, NVM_OEM_PROD_VER_PTR, &offset); + + /* Return is offset to OEM Product Version block is invalid */ + if (offset == 0x0 || offset == NVM_INVALID_PTR) + return; + + /* Read product version block */ + hw->eeprom.ops.read(hw, offset, &mod_len); + hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_CAP_OFF, &cap); + + /* Return if OEM product version block is invalid */ + if (mod_len != NVM_OEM_PROD_VER_MOD_LEN || + (cap & NVM_OEM_PROD_VER_CAP_MASK) != 0x0) + return; + + hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_L, &prod_ver); + hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_H, &rel_num); + + /* Return if version is invalid */ + if ((rel_num | prod_ver) == 0x0 || + rel_num == NVM_VER_INVALID || prod_ver == NVM_VER_INVALID) + return; + + nvm_ver->oem_major = prod_ver >> NVM_VER_SHIFT; + nvm_ver->oem_minor = prod_ver & NVM_VER_MASK; + nvm_ver->oem_release = rel_num; + nvm_ver->oem_valid = true; +} + +/** + * ixgbe_get_etk_id() - Read ETK ID from NVM and store it into @nvm_ver + * @hw: device hardware handle + * @nvm_ver: output container; fills @etk_id field + * + * Reads two 16-bit words from NVM, determines the word order using + * NVM_ETK_VALID, and assembles the 32-bit ETK ID. + */ +void ixgbe_get_etk_id(struct ixgbe_hw *hw, struct ixgbe_nvm_version *nvm_ver) +{ + u16 etk_id_l, etk_id_h; + u32 lo, hi; + + if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_LOW, &etk_id_l)) + etk_id_l = NVM_VER_INVALID; + if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_HI, &etk_id_h)) + etk_id_h = NVM_VER_INVALID; + + /* The word order for the version format is determined by high order + * word bit 15. + */ + lo = (etk_id_h & NVM_ETK_VALID) ? etk_id_l : etk_id_h; + hi = (etk_id_h & NVM_ETK_VALID) ? etk_id_h : etk_id_l; + + /* Ensure LHS is u32 so shift occurs in unsigned 32-bit + * to avoid implicit u16 -> int promotion by compiler. + */ + nvm_ver->etk_id = (hi << NVM_ETK_SHIFT) | lo; +} + +/** + * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg + * @hw: pointer to hardware structure + * @map: pointer to u8 arr for returning map + * + * Read the rtrup2tc HW register and resolve its content into map + **/ +void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map) +{ + u32 reg, i; + + reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC); + for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) + map[i] = IXGBE_RTRUP2TC_UP_MASK & + (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT)); + return; +} + +void ixgbe_disable_rx_generic(struct ixgbe_hw *hw) +{ + u32 pfdtxgswc; + u32 rxctrl; + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + if (hw->mac.type != ixgbe_mac_82598EB) { + pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) { + pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben = true; + } else { + hw->mac.set_lben = false; + } + } + rxctrl &= ~IXGBE_RXCTRL_RXEN; + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); + } +} + +void ixgbe_enable_rx_generic(struct ixgbe_hw *hw) +{ + u32 pfdtxgswc; + u32 rxctrl; + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, (rxctrl | IXGBE_RXCTRL_RXEN)); + + if (hw->mac.type != ixgbe_mac_82598EB) { + if (hw->mac.set_lben) { + pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + pfdtxgswc |= IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben = false; + } + } +} + +/** + * ixgbe_mng_present - returns true when management capability is present + * @hw: pointer to hardware structure + */ +bool ixgbe_mng_present(struct ixgbe_hw *hw) +{ + u32 fwsm; + + if (hw->mac.type < ixgbe_mac_82599EB) + return false; + + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); + + return !!(fwsm & IXGBE_FWSM_FW_MODE_PT); +} + +/** + * ixgbe_mng_enabled - Is the manageability engine enabled? + * @hw: pointer to hardware structure + * + * Returns true if the manageability engine is enabled. + **/ +bool ixgbe_mng_enabled(struct ixgbe_hw *hw) +{ + u32 fwsm, manc, factps; + + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); + if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT) + return false; + + manc = IXGBE_READ_REG(hw, IXGBE_MANC); + if (!(manc & IXGBE_MANC_RCV_TCO_EN)) + return false; + + if (hw->mac.type <= ixgbe_mac_X540) { + factps = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); + if (factps & IXGBE_FACTPS_MNGCG) + return false; + } + + return true; +} + +/** + * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Set the link speed in the MAC and/or PHY register and restarts link. + **/ +s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; + ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN; + s32 status = IXGBE_SUCCESS; + u32 speedcnt = 0; + u32 i = 0; + bool autoneg, link_up = false; + + DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber"); + + /* Mask off requested but non-supported speeds */ + status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg); + if (status != IXGBE_SUCCESS) + return status; + + speed &= link_speed; + + /* Try each speed one by one, highest priority first. We do this in + * software because 10Gb fiber doesn't support speed autonegotiation. + */ + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + speedcnt++; + highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; + + /* Set the module link speed */ + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + ixgbe_set_rate_select_speed(hw, + IXGBE_LINK_SPEED_10GB_FULL); + break; + case ixgbe_media_type_fiber_qsfp: + /* QSFP module automatically detects MAC link speed */ + break; + default: + hw_dbg(hw, "Unexpected media type.\n"); + break; + } + + /* Allow module to change analog characteristics (1G->10G) */ + msec_delay(40); + + status = ixgbe_setup_mac_link(hw, + IXGBE_LINK_SPEED_10GB_FULL, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + return status; + + /* Flap the Tx laser if it has not already been done */ + ixgbe_flap_tx_laser(hw); + + /* Wait for the controller to acquire link. Per IEEE 802.3ap, + * Section 73.10.2, we may have to wait up to 500ms if KR is + * attempted. 82599 uses the same timing for 10g SFI. + */ + for (i = 0; i < 5; i++) { + /* Wait for the link partner to also set speed */ + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, + &link_up, false); + if (status != IXGBE_SUCCESS) + return status; + + if (link_up) + goto out; + } + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + speedcnt++; + if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) + highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; + + /* Set the module link speed */ + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + ixgbe_set_rate_select_speed(hw, + IXGBE_LINK_SPEED_1GB_FULL); + break; + case ixgbe_media_type_fiber_qsfp: + /* QSFP module automatically detects link speed */ + break; + default: + hw_dbg(hw, "Unexpected media type.\n"); + break; + } + + /* Allow module to change analog characteristics (10G->1G) */ + msec_delay(40); + + status = ixgbe_setup_mac_link(hw, + IXGBE_LINK_SPEED_1GB_FULL, + autoneg_wait_to_complete); + if (status != IXGBE_SUCCESS) + return status; + + /* Flap the Tx laser if it has not already been done */ + ixgbe_flap_tx_laser(hw); + + /* Wait for the link partner to also set speed */ + msec_delay(100); + + /* If we have link, just jump out */ + status = ixgbe_check_link(hw, &link_speed, &link_up, false); + if (status != IXGBE_SUCCESS) + return status; + + if (link_up) + goto out; + } + + /* We didn't get link. Configure back to the highest speed we tried, + * (if there was more than one). We call ourselves back with just the + * single highest speed that the user requested. + */ + if (speedcnt > 1) + status = ixgbe_setup_mac_link_multispeed_fiber(hw, + highest_link_speed, + autoneg_wait_to_complete); + +out: + /* Set autoneg_advertised value based on input link speed */ + hw->phy.autoneg_advertised = 0; + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + return status; +} + +/** + * ixgbe_set_soft_rate_select_speed - Set module link speed + * @hw: pointer to hardware structure + * @speed: link speed to set + * + * Set module link speed via the soft rate select. + */ +void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw, + ixgbe_link_speed speed) +{ + s32 status; + u8 rs, eeprom_data; + + switch (speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + /* one bit mask same as setting on */ + rs = IXGBE_SFF_SOFT_RS_SELECT_10G; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + rs = IXGBE_SFF_SOFT_RS_SELECT_1G; + break; + default: + hw_dbg(hw, "Invalid fixed module speed\n"); + return; + } + + /* Set RS0 */ + status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + &eeprom_data); + if (status) { + hw_dbg(hw, "Failed to read Rx Rate Select RS0\n"); + goto out; + } + + eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs; + + status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + eeprom_data); + if (status) { + hw_dbg(hw, "Failed to write Rx Rate Select RS0\n"); + goto out; + } + + /* Set RS1 */ + status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + &eeprom_data); + if (status) { + hw_dbg(hw, "Failed to read Rx Rate Select RS1\n"); + goto out; + } + + eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs; + + status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB, + IXGBE_I2C_EEPROM_DEV_ADDR2, + eeprom_data); + if (status) { + hw_dbg(hw, "Failed to write Rx Rate Select RS1\n"); + goto out; + } +out: + return; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.h new file mode 100644 index 0000000000..a9101b2c76 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_common.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_COMMON_H_ +#define _IXGBE_COMMON_H_ + +#include "ixgbe_type.h" + +void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map); + +u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw); +s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); +s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw); +s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw); +void ixgbe_start_hw_gen2(struct ixgbe_hw *hw); +s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw); +s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, + u32 pba_num_size); +s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr); +s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw); +void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status); +void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw); +s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw); + +s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw); + +s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); +s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); +s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data); +s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 *data); +s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); +s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, + u16 *checksum_val); +s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); +s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); + +s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr); +s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw); +s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, + ixgbe_mc_addr_itr func, bool clear); +s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr func); +s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); +s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); +s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); +s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw); +s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw); + +s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw); +bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg(struct ixgbe_hw *hw); +s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw); + +s32 ixgbe_validate_mac_addr(u8 *mac_addr); +s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask); +s32 ixgbe_disable_pcie_primary(struct ixgbe_hw *hw); + +s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *, u32 *reg_val); +s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked); + +s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); + +s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr); +s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr); + +s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq); +s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); +s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); +s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw); +s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, + u32 vind, bool vlan_on, bool vlvf_bypass); +s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on, u32 *vfta_delta, u32 vfta, + bool vlvf_bypass); +s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); +s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass); +s32 ixgbe_toggle_txdctl_generic(struct ixgbe_hw *hw, u32 vind); + +s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); + +s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix); + +s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs); +void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); +void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); +s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); +void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom, + int strategy); +s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 ver, u16 len, const char *str); +u8 ixgbe_calculate_checksum(u8 *buffer, u32 length); +s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, + u32 length, u32 timeout, bool return_data); +s32 ixgbe_hic_unlocked(struct ixgbe_hw *, u32 *buffer, u32 length, u32 timeout); +s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *); +s32 ixgbe_fw_phy_activity(struct ixgbe_hw *, u16 activity, + u32 (*data)[FW_PHY_ACT_DATA_COUNT]); +void ixgbe_clear_tx_pending(struct ixgbe_hw *hw); + +extern s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw); +extern void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw); +bool ixgbe_mng_present(struct ixgbe_hw *hw); +bool ixgbe_mng_enabled(struct ixgbe_hw *hw); + +#define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8 +#define IXGBE_EMC_INTERNAL_DATA 0x00 +#define IXGBE_EMC_INTERNAL_THERM_LIMIT 0x20 +#define IXGBE_EMC_DIODE1_DATA 0x01 +#define IXGBE_EMC_DIODE1_THERM_LIMIT 0x19 +#define IXGBE_EMC_DIODE2_DATA 0x23 +#define IXGBE_EMC_DIODE2_THERM_LIMIT 0x1A +#define IXGBE_EMC_DIODE3_DATA 0x2A +#define IXGBE_EMC_DIODE3_THERM_LIMIT 0x30 + +s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw); +s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw); + +void ixgbe_get_etk_id(struct ixgbe_hw *hw, struct ixgbe_nvm_version *nvm_ver); +void ixgbe_get_oem_prod_version(struct ixgbe_hw *hw, + struct ixgbe_nvm_version *nvm_ver); +void ixgbe_get_orom_version(struct ixgbe_hw *hw, + struct ixgbe_nvm_version *nvm_ver); +void ixgbe_disable_rx_generic(struct ixgbe_hw *hw); +void ixgbe_enable_rx_generic(struct ixgbe_hw *hw); +s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw, + ixgbe_link_speed speed); +#endif /* IXGBE_COMMON */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.c new file mode 100644 index 0000000000..00fecdbe23 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.c @@ -0,0 +1,702 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_dcb.h" +#include "ixgbe_dcb_82598.h" +#include "ixgbe_dcb_82599.h" + +/** + * ixgbe_dcb_calculate_tc_credits - This calculates the ieee traffic class + * credits from the configured bandwidth percentages. Credits + * are the smallest unit programmable into the underlying + * hardware. The IEEE 802.1Qaz specification do not use bandwidth + * groups so this is much simplified from the CEE case. + * @bw: bandwidth index by traffic class + * @refill: refill credits index by traffic class + * @max: max credits by traffic class + * @max_frame_size: maximum frame size + */ +s32 ixgbe_dcb_calculate_tc_credits(u8 *bw, u16 *refill, u16 *max, + int max_frame_size) +{ + int min_percent = 100; + int min_credit, multiplier; + int i; + + min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) / + IXGBE_DCB_CREDIT_QUANTUM; + + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + if (bw[i] < min_percent && bw[i]) + min_percent = bw[i]; + } + + multiplier = (min_credit / min_percent) + 1; + + /* Find out the hw credits for each TC */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + int val = min(bw[i] * multiplier, IXGBE_DCB_MAX_CREDIT_REFILL); + + if (val < min_credit) + val = min_credit; + refill[i] = (u16)val; + + max[i] = bw[i] ? (bw[i]*IXGBE_DCB_MAX_CREDIT)/100 : min_credit; + } + + return 0; +} + +/** + * ixgbe_dcb_calculate_tc_credits_cee - Calculates traffic class credits + * @hw: pointer to hardware structure + * @dcb_config: Struct containing DCB settings + * @max_frame_size: Maximum frame size + * @direction: Configuring either Tx or Rx + * + * This function calculates the credits allocated to each traffic class. + * It should be called only after the rules are checked by + * ixgbe_dcb_check_config_cee(). + */ +s32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config, + u32 max_frame_size, u8 direction) +{ + struct ixgbe_dcb_tc_path *p; + u32 min_multiplier = 0; + u16 min_percent = 100; + s32 ret_val = IXGBE_SUCCESS; + /* Initialization values default for Tx settings */ + u32 min_credit = 0; + u32 credit_refill = 0; + u32 credit_max = 0; + u16 link_percentage = 0; + u8 bw_percent = 0; + u8 i; + + if (dcb_config == NULL) { + ret_val = IXGBE_ERR_CONFIG; + goto out; + } + + min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) / + IXGBE_DCB_CREDIT_QUANTUM; + + /* Find smallest link percentage */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + p = &dcb_config->tc_config[i].path[direction]; + bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; + link_percentage = p->bwg_percent; + + link_percentage = (link_percentage * bw_percent) / 100; + + if (link_percentage && link_percentage < min_percent) + min_percent = link_percentage; + } + + /* + * The ratio between traffic classes will control the bandwidth + * percentages seen on the wire. To calculate this ratio we use + * a multiplier. It is required that the refill credits must be + * larger than the max frame size so here we find the smallest + * multiplier that will allow all bandwidth percentages to be + * greater than the max frame size. + */ + min_multiplier = (min_credit / min_percent) + 1; + + /* Find out the link percentage for each TC first */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + p = &dcb_config->tc_config[i].path[direction]; + bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; + + link_percentage = p->bwg_percent; + /* Must be careful of integer division for very small nums */ + link_percentage = (link_percentage * bw_percent) / 100; + if (p->bwg_percent > 0 && link_percentage == 0) + link_percentage = 1; + + /* Save link_percentage for reference */ + p->link_percent = (u8)link_percentage; + + /* Calculate credit refill ratio using multiplier */ + credit_refill = min(link_percentage * min_multiplier, + (u32)IXGBE_DCB_MAX_CREDIT_REFILL); + + /* Refill at least minimum credit */ + if (credit_refill < min_credit) + credit_refill = min_credit; + + p->data_credits_refill = (u16)credit_refill; + + /* Calculate maximum credit for the TC */ + credit_max = (link_percentage * IXGBE_DCB_MAX_CREDIT) / 100; + + /* + * Adjustment based on rule checking, if the percentage + * of a TC is too small, the maximum credit may not be + * enough to send out a jumbo frame in data plane arbitration. + */ + if (credit_max < min_credit) + credit_max = min_credit; + + if (direction == IXGBE_DCB_TX_CONFIG) { + /* + * Adjustment based on rule checking, if the + * percentage of a TC is too small, the maximum + * credit may not be enough to send out a TSO + * packet in descriptor plane arbitration. + */ + if (credit_max && (credit_max < + IXGBE_DCB_MIN_TSO_CREDIT) + && (hw->mac.type == ixgbe_mac_82598EB)) + credit_max = IXGBE_DCB_MIN_TSO_CREDIT; + + dcb_config->tc_config[i].desc_credits_max = + (u16)credit_max; + } + + p->data_credits_max = (u16)credit_max; + } + +out: + return ret_val; +} + +/** + * ixgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info + * @cfg: dcb configuration to unpack into hardware consumable fields + * @map: user priority to traffic class map + * @pfc_up: u8 to store user priority PFC bitmask + * + * This unpacks the dcb configuration PFC info which is stored per + * traffic class into a 8bit user priority bitmask that can be + * consumed by hardware routines. The priority to tc map must be + * updated before calling this routine to use current up-to maps. + */ +void ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *cfg, u8 *map, u8 *pfc_up) +{ + struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; + int up; + + /* + * If the TC for this user priority has PFC enabled then set the + * matching bit in 'pfc_up' to reflect that PFC is enabled. + */ + for (*pfc_up = 0, up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) { + if (tc_config[map[up]].pfc != ixgbe_dcb_pfc_disabled) + *pfc_up |= 1 << up; + } +} + +void ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *cfg, int direction, + u16 *refill) +{ + struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; + int tc; + + for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) + refill[tc] = tc_config[tc].path[direction].data_credits_refill; +} + +void ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *cfg, u16 *max) +{ + struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; + int tc; + + for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) + max[tc] = tc_config[tc].desc_credits_max; +} + +void ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *cfg, int direction, + u8 *bwgid) +{ + struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; + int tc; + + for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) + bwgid[tc] = tc_config[tc].path[direction].bwg_id; +} + +void ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *cfg, int direction, + u8 *tsa) +{ + struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; + int tc; + + for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) + tsa[tc] = tc_config[tc].path[direction].tsa; +} + +u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up) +{ + struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0]; + u8 prio_mask = 1 << up; + u8 tc = cfg->num_tcs.pg_tcs; + + /* If tc is 0 then DCB is likely not enabled or supported */ + if (!tc) + goto out; + + /* + * Test from maximum TC to 1 and report the first match we find. If + * we find no match we can assume that the TC is 0 since the TC must + * be set for all user priorities + */ + for (tc--; tc; tc--) { + if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap) + break; + } +out: + return tc; +} + +void ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *cfg, int direction, + u8 *map) +{ + u8 up; + + for (up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) + map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up); +} + +/** + * ixgbe_dcb_check_config_cee - Struct containing DCB settings. + * @dcb_config: Pointer to DCB config structure + * + * This function checks DCB rules for DCB settings. + * The following rules are checked: + * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%. + * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth + * Group must total 100. + * 3. A Traffic Class should not be set to both Link Strict Priority + * and Group Strict Priority. + * 4. Link strict Bandwidth Groups can only have link strict traffic classes + * with zero bandwidth. + */ +s32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *dcb_config) +{ + struct ixgbe_dcb_tc_path *p; + s32 ret_val = IXGBE_SUCCESS; + u8 i, j, bw = 0, bw_id; + u8 bw_sum[2][IXGBE_DCB_MAX_BW_GROUP]; + bool link_strict[2][IXGBE_DCB_MAX_BW_GROUP]; + + memset(bw_sum, 0, sizeof(bw_sum)); + memset(link_strict, 0, sizeof(link_strict)); + + /* First Tx, then Rx */ + for (i = 0; i < 2; i++) { + /* Check each traffic class for rule violation */ + for (j = 0; j < IXGBE_DCB_MAX_TRAFFIC_CLASS; j++) { + p = &dcb_config->tc_config[j].path[i]; + + bw = p->bwg_percent; + bw_id = p->bwg_id; + + if (bw_id >= IXGBE_DCB_MAX_BW_GROUP) { + ret_val = IXGBE_ERR_CONFIG; + goto err_config; + } + if (p->tsa == ixgbe_dcb_tsa_strict) { + link_strict[i][bw_id] = true; + /* Link strict should have zero bandwidth */ + if (bw) { + ret_val = IXGBE_ERR_CONFIG; + goto err_config; + } + } else if (!bw) { + /* + * Traffic classes without link strict + * should have non-zero bandwidth. + */ + ret_val = IXGBE_ERR_CONFIG; + goto err_config; + } + bw_sum[i][bw_id] += bw; + } + + bw = 0; + + /* Check each bandwidth group for rule violation */ + for (j = 0; j < IXGBE_DCB_MAX_BW_GROUP; j++) { + bw += dcb_config->bw_percentage[i][j]; + /* + * Sum of bandwidth percentages of all traffic classes + * within a Bandwidth Group must total 100 except for + * link strict group (zero bandwidth). + */ + if (link_strict[i][j]) { + if (bw_sum[i][j]) { + /* + * Link strict group should have zero + * bandwidth. + */ + ret_val = IXGBE_ERR_CONFIG; + goto err_config; + } + } else if (bw_sum[i][j] != IXGBE_DCB_BW_PERCENT && + bw_sum[i][j] != 0) { + ret_val = IXGBE_ERR_CONFIG; + goto err_config; + } + } + + if (bw != IXGBE_DCB_BW_PERCENT) { + ret_val = IXGBE_ERR_CONFIG; + goto err_config; + } + } + +err_config: + + return ret_val; +} + +/** + * ixgbe_dcb_get_tc_stats - Returns status of each traffic class + * @hw: pointer to hardware structure + * @stats: pointer to statistics structure + * @tc_count: Number of elements in bwg_array. + * + * This function returns the status data for each of the Traffic Classes in use. + */ +s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, + u8 tc_count) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class + * @hw: pointer to hardware structure + * @stats: pointer to statistics structure + * @tc_count: Number of elements in bwg_array. + * + * This function returns the CBFC status data for each of the Traffic Classes. + */ +s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, + u8 tc_count) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure Rx Data Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; + u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; + u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; + u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; + u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 }; + + ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max_cee(dcb_config, max); + ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); + ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); + ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid, + tsa, map); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure Tx Descriptor Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + + ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max_cee(dcb_config, max); + ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); + ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, + bwgid, tsa); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, + bwgid, tsa); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure Tx Data Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; + u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + + ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max_cee(dcb_config, max); + ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); + ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); + ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, + bwgid, tsa); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, + bwgid, tsa, + map); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_config_pfc_cee - Config priority flow control + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure Priority Flow Control for each traffic class. + */ +s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + u8 pfc_en; + u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; + + ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); + ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_config_tc_stats - Config traffic class statistics + * @hw: pointer to hardware structure + * + * Configure queue statistics registers, all queues belonging to same traffic + * class uses a single set of queue statistics counters. + */ +s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_tc_stats_82598(hw); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL); + break; + default: + break; + } + return ret; +} + +/** + * ixgbe_dcb_hw_config_cee - Config and enable DCB + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure dcb settings and enable dcb mode. + */ +s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + s32 ret = IXGBE_NOT_IMPLEMENTED; + u8 pfc_en; + u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; + u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + + /* Unpack CEE standard containers */ + ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max_cee(dcb_config, max); + ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); + ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); + ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed, + refill, max, bwgid, tsa); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ixgbe_dcb_config_82599(hw, dcb_config); + ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, + refill, max, bwgid, + tsa, map); + + ixgbe_dcb_config_tc_stats_82599(hw, dcb_config); + break; + default: + break; + } + + if (!ret && dcb_config->pfc_mode_enable) { + ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); + ret = ixgbe_dcb_config_pfc(hw, pfc_en, map); + } + + return ret; +} + +/* Helper routines to abstract HW specifics from DCB netlink ops */ +s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map) +{ + int ret = IXGBE_ERR_PARAM; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); + break; + default: + break; + } + return ret; +} + +s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, + u8 *bwg_id, u8 *tsa, u8 *map) +{ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); + ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, + tsa); + ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, + tsa); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, + tsa, map); + ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, + tsa); + ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, + tsa, map); + break; + default: + break; + } + return 0; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.h new file mode 100644 index 0000000000..08ce6c8dd6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb.h @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_DCB_H_ +#define _IXGBE_DCB_H_ + +#include "ixgbe_type.h" + +/* DCB defines */ +/* DCB credit calculation defines */ +#define IXGBE_DCB_CREDIT_QUANTUM 64 +#define IXGBE_DCB_MAX_CREDIT_REFILL 511 /* 0x1FF * 64B = 32704B */ +#define IXGBE_DCB_MAX_TSO_SIZE (32 * 1024) /* Max TSO pkt size in DCB*/ +#define IXGBE_DCB_MAX_CREDIT 4095 /* Maximum credit supported: 256KB * 1024 / 64B */ + +/* 513 for 32KB TSO packet */ +#define IXGBE_DCB_MIN_TSO_CREDIT \ + ((IXGBE_DCB_MAX_TSO_SIZE / IXGBE_DCB_CREDIT_QUANTUM) + 1) + +/* DCB configuration defines */ +#define IXGBE_DCB_MAX_USER_PRIORITY 8 +#define IXGBE_DCB_MAX_BW_GROUP 8 +#define IXGBE_DCB_BW_PERCENT 100 + +#define IXGBE_DCB_TX_CONFIG 0 +#define IXGBE_DCB_RX_CONFIG 1 + +/* DCB capability defines */ +#define IXGBE_DCB_PG_SUPPORT 0x00000001 +#define IXGBE_DCB_PFC_SUPPORT 0x00000002 +#define IXGBE_DCB_BCN_SUPPORT 0x00000004 +#define IXGBE_DCB_UP2TC_SUPPORT 0x00000008 +#define IXGBE_DCB_GSP_SUPPORT 0x00000010 + +struct ixgbe_dcb_support { + u32 capabilities; /* DCB capabilities */ + + /* Each bit represents a number of TCs configurable in the hw. + * If 8 traffic classes can be configured, the value is 0x80. */ + u8 traffic_classes; + u8 pfc_traffic_classes; +}; + +enum ixgbe_dcb_tsa { + ixgbe_dcb_tsa_ets = 0, + ixgbe_dcb_tsa_group_strict_cee, + ixgbe_dcb_tsa_strict +}; + +/* Traffic class bandwidth allocation per direction */ +struct ixgbe_dcb_tc_path { + u8 bwg_id; /* Bandwidth Group (BWG) ID */ + u8 bwg_percent; /* % of BWG's bandwidth */ + u8 link_percent; /* % of link bandwidth */ + u8 up_to_tc_bitmap; /* User Priority to Traffic Class mapping */ + u16 data_credits_refill; /* Credit refill amount in 64B granularity */ + u16 data_credits_max; /* Max credits for a configured packet buffer + * in 64B granularity.*/ + enum ixgbe_dcb_tsa tsa; /* Link or Group Strict Priority */ +}; + +enum ixgbe_dcb_pfc { + ixgbe_dcb_pfc_disabled = 0, + ixgbe_dcb_pfc_enabled, + ixgbe_dcb_pfc_enabled_txonly, + ixgbe_dcb_pfc_enabled_rxonly +}; + +/* Traffic class configuration */ +struct ixgbe_dcb_tc_config { + struct ixgbe_dcb_tc_path path[2]; /* One each for Tx/Rx */ + enum ixgbe_dcb_pfc pfc; /* Class based flow control setting */ + + u16 desc_credits_max; /* For Tx Descriptor arbitration */ + u8 tc; /* Traffic class (TC) */ +}; + +enum ixgbe_dcb_pba { + /* PBA[0-7] each use 64KB FIFO */ + ixgbe_dcb_pba_equal = PBA_STRATEGY_EQUAL, + /* PBA[0-3] each use 80KB, PBA[4-7] each use 48KB */ + ixgbe_dcb_pba_80_48 = PBA_STRATEGY_WEIGHTED +}; + +struct ixgbe_dcb_num_tcs { + u8 pg_tcs; + u8 pfc_tcs; +}; + +struct ixgbe_dcb_config { + struct ixgbe_dcb_tc_config tc_config[IXGBE_DCB_MAX_TRAFFIC_CLASS]; + struct ixgbe_dcb_support support; + struct ixgbe_dcb_num_tcs num_tcs; + u8 bw_percentage[2][IXGBE_DCB_MAX_BW_GROUP]; /* One each for Tx/Rx */ + bool pfc_mode_enable; + bool round_robin_enable; + + enum ixgbe_dcb_pba rx_pba_cfg; + + u32 dcb_cfg_version; /* Not used...OS-specific? */ + u32 link_speed; /* For bandwidth allocation validation purpose */ + bool vt_mode; +}; + +/* DCB driver APIs */ + +/* DCB rule checking */ +s32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *); + +/* DCB credits calculation */ +s32 ixgbe_dcb_calculate_tc_credits(u8 *, u16 *, u16 *, int); +s32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *, + struct ixgbe_dcb_config *, u32, u8); + +/* DCB PFC */ +s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *, u8, u8 *); +s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *, struct ixgbe_dcb_config *); + +/* DCB stats */ +s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *); +s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8); +s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8); + +/* DCB config arbiters */ +s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *, + struct ixgbe_dcb_config *); +s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *, + struct ixgbe_dcb_config *); +s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *, + struct ixgbe_dcb_config *); + +/* DCB unpack routines */ +void ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *, u8 *, u8 *); +void ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *, int, u16 *); +void ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *, u16 *); +void ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *, int, u8 *); +void ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *, int, u8 *); +void ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *, int, u8 *); +u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *, int, u8); + +/* DCB initialization */ +s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, u16 *, u16 *, u8 *, u8 *, u8 *); +s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *, struct ixgbe_dcb_config *); +#endif /* _IXGBE_DCB_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.c new file mode 100644 index 0000000000..afb9a5e089 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.c @@ -0,0 +1,340 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_dcb.h" +#include "ixgbe_dcb_82598.h" + +/** + * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class + * @hw: pointer to hardware structure + * @stats: pointer to statistics structure + * @tc_count: Number of elements in bwg_array. + * + * This function returns the status data for each of the Traffic Classes in use. + */ +s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw, + struct ixgbe_hw_stats *stats, + u8 tc_count) +{ + int tc; + + DEBUGFUNC("dcb_get_tc_stats"); + + if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS) + return IXGBE_ERR_PARAM; + + /* Statistics pertaining to each traffic class */ + for (tc = 0; tc < tc_count; tc++) { + /* Transmitted Packets */ + stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); + /* Transmitted Bytes */ + stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc)); + /* Received Packets */ + stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); + /* Received Bytes */ + stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc)); + +#if 0 + /* Can we get rid of these?? Consequently, getting rid + * of the tc_stats structure. + */ + tc_stats_array[up]->in_overflow_discards = 0; + tc_stats_array[up]->out_overflow_discards = 0; +#endif + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data + * @hw: pointer to hardware structure + * @stats: pointer to statistics structure + * @tc_count: Number of elements in bwg_array. + * + * This function returns the CBFC status data for each of the Traffic Classes. + */ +s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw, + struct ixgbe_hw_stats *stats, + u8 tc_count) +{ + int tc; + + DEBUGFUNC("dcb_get_pfc_stats"); + + if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS) + return IXGBE_ERR_PARAM; + + for (tc = 0; tc < tc_count; tc++) { + /* Priority XOFF Transmitted */ + stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); + /* Priority XOFF Received */ + stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc)); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter + * @hw: pointer to hardware structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * + * Configure Rx Data Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill, + u16 *max, u8 *tsa) +{ + u32 reg = 0; + u32 credit_refill = 0; + u32 credit_max = 0; + u8 i = 0; + + reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA; + IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg); + + reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + /* Enable Arbiter */ + reg &= ~IXGBE_RMCS_ARBDIS; + /* Enable Receive Recycle within the BWG */ + reg |= IXGBE_RMCS_RRM; + /* Enable Deficit Fixed Priority arbitration*/ + reg |= IXGBE_RMCS_DFP; + + IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); + + /* Configure traffic class credits and priority */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + credit_refill = refill[i]; + credit_max = max[i]; + + reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); + + if (tsa[i] == ixgbe_dcb_tsa_strict) + reg |= IXGBE_RT2CR_LSP; + + IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); + } + + reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + reg |= IXGBE_RDRXCTL_RDMTS_1_2; + reg |= IXGBE_RDRXCTL_MPBEN; + reg |= IXGBE_RDRXCTL_MCEN; + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); + + reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + /* Make sure there is enough descriptors before arbitration */ + reg &= ~IXGBE_RXCTRL_DMBYPS; + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter + * @hw: pointer to hardware structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * + * Configure Tx Descriptor Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, u16 *max, u8 *bwg_id, + u8 *tsa) +{ + u32 reg, max_credits; + u8 i; + + reg = IXGBE_READ_REG(hw, IXGBE_DPMCS); + + /* Enable arbiter */ + reg &= ~IXGBE_DPMCS_ARBDIS; + reg |= IXGBE_DPMCS_TSOEF; + + /* Configure Max TSO packet size 34KB including payload and headers */ + reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); + + IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg); + + /* Configure traffic class credits and priority */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + max_credits = max[i]; + reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; + reg |= (u32)(refill[i]); + reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; + + if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee) + reg |= IXGBE_TDTQ2TCCR_GSP; + + if (tsa[i] == ixgbe_dcb_tsa_strict) + reg |= IXGBE_TDTQ2TCCR_LSP; + + IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter + * @hw: pointer to hardware structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * + * Configure Tx Data Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, u16 *max, u8 *bwg_id, + u8 *tsa) +{ + u32 reg; + u8 i; + + reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS); + /* Enable Data Plane Arbiter */ + reg &= ~IXGBE_PDPMCS_ARBDIS; + /* Enable DFP and Transmit Recycle Mode */ + reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM); + + IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg); + + /* Configure traffic class credits and priority */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + reg = refill[i]; + reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; + reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; + + if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee) + reg |= IXGBE_TDPT2TCCR_GSP; + + if (tsa[i] == ixgbe_dcb_tsa_strict) + reg |= IXGBE_TDPT2TCCR_LSP; + + IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); + } + + /* Enable Tx packet buffer division */ + reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL); + reg |= IXGBE_DTXCTL_ENDBUBD; + IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_pfc_82598 - Config priority flow control + * @hw: pointer to hardware structure + * @pfc_en: enabled pfc bitmask + * + * Configure Priority Flow Control for each traffic class. + */ +s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) +{ + u32 fcrtl, reg; + u8 i; + + /* Enable Transmit Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + reg &= ~IXGBE_RMCS_TFCE_802_3X; + reg |= IXGBE_RMCS_TFCE_PRIORITY; + IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); + + /* Enable Receive Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); + reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); + + if (pfc_en) + reg |= IXGBE_FCTRL_RPFCE; + + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); + + /* Configure PFC Tx thresholds per TC */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + if (!(pfc_en & (1 << i))) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); + continue; + } + + fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; + reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); + } + + /* Configure pause time */ + reg = hw->fc.pause_time | (hw->fc.pause_time << 16); + for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics + * @hw: pointer to hardware structure + * + * Configure queue statistics registers, all queues belonging to same traffic + * class uses a single set of queue statistics counters. + */ +s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) +{ + u32 reg = 0; + u8 i = 0; + u8 j = 0; + + /* Receive Queues stats setting - 8 queues per statistics reg */ + for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) { + reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i)); + reg |= ((0x1010101) * j); + IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); + reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1)); + reg |= ((0x1010101) * j); + IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg); + } + /* Transmit Queues stats setting - 4 queues per statistics reg*/ + for (i = 0; i < 8; i++) { + reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i)); + reg |= ((0x1010101) * i); + IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_hw_config_82598 - Config and enable DCB + * @hw: pointer to hardware structure + * @link_speed: unused + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * + * Configure dcb settings and enable dcb mode. + */ +s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed, + u16 *refill, u16 *max, u8 *bwg_id, + u8 *tsa) +{ + UNREFERENCED_1PARAMETER(link_speed); + + ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); + ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, + tsa); + ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, + tsa); + ixgbe_dcb_config_tc_stats_82598(hw); + + return IXGBE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.h new file mode 100644 index 0000000000..d457c29138 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82598.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_DCB_82598_H_ +#define _IXGBE_DCB_82598_H_ + +/* DCB register definitions */ + +#define IXGBE_DPMCS_MTSOS_SHIFT 16 +#define IXGBE_DPMCS_TDPAC 0x00000001 /* 0 Round Robin, + * 1 DFP - Deficit Fixed Priority */ +#define IXGBE_DPMCS_TRM 0x00000010 /* Transmit Recycle Mode */ +#define IXGBE_DPMCS_ARBDIS 0x00000040 /* DCB arbiter disable */ +#define IXGBE_DPMCS_TSOEF 0x00080000 /* TSO Expand Factor: 0=x4, 1=x2 */ + +#define IXGBE_RUPPBMR_MQA 0x80000000 /* Enable UP to queue mapping */ + +#define IXGBE_RT2CR_MCL_SHIFT 12 /* Offset to Max Credit Limit setting */ +#define IXGBE_RT2CR_LSP 0x80000000 /* LSP enable bit */ + +#define IXGBE_RDRXCTL_MPBEN 0x00000010 /* DMA config for multiple packet + * buffers enable */ +#define IXGBE_RDRXCTL_MCEN 0x00000040 /* DMA config for multiple cores + * (RSS) enable */ + +#define IXGBE_TDTQ2TCCR_MCL_SHIFT 12 +#define IXGBE_TDTQ2TCCR_BWG_SHIFT 9 +#define IXGBE_TDTQ2TCCR_GSP 0x40000000 +#define IXGBE_TDTQ2TCCR_LSP 0x80000000 + +#define IXGBE_TDPT2TCCR_MCL_SHIFT 12 +#define IXGBE_TDPT2TCCR_BWG_SHIFT 9 +#define IXGBE_TDPT2TCCR_GSP 0x40000000 +#define IXGBE_TDPT2TCCR_LSP 0x80000000 + +#define IXGBE_PDPMCS_TPPAC 0x00000020 /* 0 Round Robin, + * 1 DFP - Deficit Fixed Priority */ +#define IXGBE_PDPMCS_ARBDIS 0x00000040 /* Arbiter disable */ +#define IXGBE_PDPMCS_TRM 0x00000100 /* Transmit Recycle Mode enable */ + +#define IXGBE_DTXCTL_ENDBUBD 0x00000004 /* Enable DBU buffer division */ + +#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */ +#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */ +#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */ +#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */ + +/* DCB driver APIs */ + +/* DCB PFC */ +s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, u8); + +/* DCB stats */ +s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *); +s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *, + struct ixgbe_hw_stats *, u8); +s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *, + struct ixgbe_hw_stats *, u8); + +/* DCB config arbiters */ +s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *, u16 *, u16 *, + u8 *, u8 *); +s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *, u16 *, u16 *, + u8 *, u8 *); +s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *, u16 *, u16 *, u8 *); + +/* DCB initialization */ +s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *, int, u16 *, u16 *, u8 *, u8 *); +#endif /* _IXGBE_DCB_82958_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.c new file mode 100644 index 0000000000..a65d04223e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.c @@ -0,0 +1,578 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_dcb.h" +#include "ixgbe_dcb_82599.h" + +/** + * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class + * @hw: pointer to hardware structure + * @stats: pointer to statistics structure + * @tc_count: Number of elements in bwg_array. + * + * This function returns the status data for each of the Traffic Classes in use. + */ +s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw, + struct ixgbe_hw_stats *stats, + u8 tc_count) +{ + int tc; + + DEBUGFUNC("dcb_get_tc_stats"); + + if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS) + return IXGBE_ERR_PARAM; + + /* Statistics pertaining to each traffic class */ + for (tc = 0; tc < tc_count; tc++) { + /* Transmitted Packets */ + stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); + /* Transmitted Bytes (read low first to prevent missed carry) */ + stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(tc)); + stats->qbtc[tc] += + (((u64)(IXGBE_READ_REG(hw, IXGBE_QBTC_H(tc)))) << 32); + /* Received Packets */ + stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); + /* Received Bytes (read low first to prevent missed carry) */ + stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(tc)); + stats->qbrc[tc] += + (((u64)(IXGBE_READ_REG(hw, IXGBE_QBRC_H(tc)))) << 32); + + /* Received Dropped Packet */ + stats->qprdc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRDC(tc)); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data + * @hw: pointer to hardware structure + * @stats: pointer to statistics structure + * @tc_count: Number of elements in bwg_array. + * + * This function returns the CBFC status data for each of the Traffic Classes. + */ +s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw, + struct ixgbe_hw_stats *stats, + u8 tc_count) +{ + int tc; + + DEBUGFUNC("dcb_get_pfc_stats"); + + if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS) + return IXGBE_ERR_PARAM; + + for (tc = 0; tc < tc_count; tc++) { + /* Priority XOFF Transmitted */ + stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); + /* Priority XOFF Received */ + stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc)); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter + * @hw: pointer to hardware structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * @map: priority to tc assignments indexed by priority + * + * Configure Rx Packet Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, + u16 *max, u8 *bwg_id, u8 *tsa, + u8 *map) +{ + u32 reg = 0; + u32 credit_refill = 0; + u32 credit_max = 0; + u8 i = 0; + + /* + * Disable the arbiter before changing parameters + * (always enable recycle mode; WSP) + */ + reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC | IXGBE_RTRPCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg); + + /* + * map all UPs to TCs. up_to_tc_bitmap for each TC has corresponding + * bits sets for the UPs that needs to be mappped to that TC. + * e.g if priorities 6 and 7 are to be mapped to a TC then the + * up_to_tc_bitmap value for that TC will be 11000000 in binary. + */ + reg = 0; + for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) + reg |= (map[i] << (i * IXGBE_RTRUP2TC_UP_SHIFT)); + + IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg); + + /* Configure traffic class credits and priority */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + credit_refill = refill[i]; + credit_max = max[i]; + reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT); + + reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT; + + if (tsa[i] == ixgbe_dcb_tsa_strict) + reg |= IXGBE_RTRPT4C_LSP; + + IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg); + } + + /* + * Configure Rx packet plane (recycle mode; WSP) and + * enable arbiter + */ + reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC; + IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter + * @hw: pointer to hardware structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * + * Configure Tx Descriptor Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, + u16 *max, u8 *bwg_id, u8 *tsa) +{ + u32 reg, max_credits; + u8 i; + + /* Clear the per-Tx queue credits; we use per-TC instead */ + for (i = 0; i < 128; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); + IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0); + } + + /* Configure traffic class credits and priority */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + max_credits = max[i]; + reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT; + reg |= (u32)(refill[i]); + reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT; + + if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee) + reg |= IXGBE_RTTDT2C_GSP; + + if (tsa[i] == ixgbe_dcb_tsa_strict) + reg |= IXGBE_RTTDT2C_LSP; + + IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg); + } + + /* + * Configure Tx descriptor plane (recycle mode; WSP) and + * enable arbiter + */ + reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter + * @hw: pointer to hardware structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * @map: priority to tc assignments indexed by priority + * + * Configure Tx Packet Arbiter and credits for each traffic class. + */ +s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, + u16 *max, u8 *bwg_id, u8 *tsa, + u8 *map) +{ + u32 reg; + u8 i; + + /* + * Disable the arbiter before changing parameters + * (always enable recycle mode; SP; arb delay) + */ + reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM | + (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT) | + IXGBE_RTTPCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg); + + /* + * map all UPs to TCs. up_to_tc_bitmap for each TC has corresponding + * bits sets for the UPs that needs to be mappped to that TC. + * e.g if priorities 6 and 7 are to be mapped to a TC then the + * up_to_tc_bitmap value for that TC will be 11000000 in binary. + */ + reg = 0; + for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) + reg |= (map[i] << (i * IXGBE_RTTUP2TC_UP_SHIFT)); + + IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg); + + /* Configure traffic class credits and priority */ + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + reg = refill[i]; + reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT; + reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT; + + if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee) + reg |= IXGBE_RTTPT2C_GSP; + + if (tsa[i] == ixgbe_dcb_tsa_strict) + reg |= IXGBE_RTTPT2C_LSP; + + IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg); + } + + /* + * Configure Tx packet plane (recycle mode; SP; arb delay) and + * enable arbiter + */ + reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM | + (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT); + IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_pfc_82599 - Configure priority flow control + * @hw: pointer to hardware structure + * @pfc_en: enabled pfc bitmask + * @map: priority to tc assignments indexed by priority + * + * Configure Priority Flow Control (PFC) for each traffic class. + */ +s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *map) +{ + u32 i, j, fcrtl, reg; + u8 max_tc = 0; + + /* Enable Transmit Priority Flow Control */ + IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY); + + /* Enable Receive Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); + reg |= IXGBE_MFLCN_DPF; + + /* + * X540 supports per TC Rx priority flow control. So + * clear all TCs and only enable those that should be + * enabled. + */ + reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); + + if (hw->mac.type >= ixgbe_mac_X540) + reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; + + if (pfc_en) + reg |= IXGBE_MFLCN_RPFCE; + + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); + + for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) { + if (map[i] > max_tc) + max_tc = map[i]; + } + + + /* Configure PFC Tx thresholds per TC */ + for (i = 0; i <= max_tc; i++) { + int enabled = 0; + + for (j = 0; j < IXGBE_DCB_MAX_USER_PRIORITY; j++) { + if ((map[j] == i) && (pfc_en & (1 << j))) { + enabled = 1; + break; + } + } + + if (enabled) { + reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; + fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); + } else { + /* + * In order to prevent Tx hangs when the internal Tx + * switch is enabled we must set the high water mark + * to the Rx packet buffer size - 24KB. This allows + * the Tx switch to function even under heavy Rx + * workloads. + */ + reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); + } + + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); + } + + for (; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0); + } + + /* Configure pause time (2 TCs per register) */ + reg = hw->fc.pause_time | (hw->fc.pause_time << 16); + for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure queue statistics registers, all queues belonging to same traffic + * class uses a single set of queue statistics counters. + */ +s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + u32 reg = 0; + u8 i = 0; + u8 tc_count = 8; + bool vt_mode = false; + + if (dcb_config != NULL) { + tc_count = dcb_config->num_tcs.pg_tcs; + vt_mode = dcb_config->vt_mode; + } + + if (!((tc_count == 8 && vt_mode == false) || tc_count == 4)) + return IXGBE_ERR_PARAM; + + if (tc_count == 8 && vt_mode == false) { + /* + * Receive Queues stats setting + * 32 RQSMR registers, each configuring 4 queues. + * + * Set all 16 queues of each TC to the same stat + * with TC 'n' going to stat 'n'. + */ + for (i = 0; i < 32; i++) { + reg = 0x01010101 * (i / 4); + IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); + } + /* + * Transmit Queues stats setting + * 32 TQSM registers, each controlling 4 queues. + * + * Set all queues of each TC to the same stat + * with TC 'n' going to stat 'n'. + * Tx queues are allocated non-uniformly to TCs: + * 32, 32, 16, 16, 8, 8, 8, 8. + */ + for (i = 0; i < 32; i++) { + if (i < 8) + reg = 0x00000000; + else if (i < 16) + reg = 0x01010101; + else if (i < 20) + reg = 0x02020202; + else if (i < 24) + reg = 0x03030303; + else if (i < 26) + reg = 0x04040404; + else if (i < 28) + reg = 0x05050505; + else if (i < 30) + reg = 0x06060606; + else + reg = 0x07070707; + IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg); + } + } else if (tc_count == 4 && vt_mode == false) { + /* + * Receive Queues stats setting + * 32 RQSMR registers, each configuring 4 queues. + * + * Set all 16 queues of each TC to the same stat + * with TC 'n' going to stat 'n'. + */ + for (i = 0; i < 32; i++) { + if (i % 8 > 3) + /* In 4 TC mode, odd 16-queue ranges are + * not used. + */ + continue; + reg = 0x01010101 * (i / 8); + IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); + } + /* + * Transmit Queues stats setting + * 32 TQSM registers, each controlling 4 queues. + * + * Set all queues of each TC to the same stat + * with TC 'n' going to stat 'n'. + * Tx queues are allocated non-uniformly to TCs: + * 64, 32, 16, 16. + */ + for (i = 0; i < 32; i++) { + if (i < 16) + reg = 0x00000000; + else if (i < 24) + reg = 0x01010101; + else if (i < 28) + reg = 0x02020202; + else + reg = 0x03030303; + IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg); + } + } else if (tc_count == 4 && vt_mode == true) { + /* + * Receive Queues stats setting + * 32 RQSMR registers, each configuring 4 queues. + * + * Queue Indexing in 32 VF with DCB mode maps 4 TC's to each + * pool. Set all 32 queues of each TC across pools to the same + * stat with TC 'n' going to stat 'n'. + */ + for (i = 0; i < 32; i++) + IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), 0x03020100); + /* + * Transmit Queues stats setting + * 32 TQSM registers, each controlling 4 queues. + * + * Queue Indexing in 32 VF with DCB mode maps 4 TC's to each + * pool. Set all 32 queues of each TC across pools to the same + * stat with TC 'n' going to stat 'n'. + */ + for (i = 0; i < 32; i++) + IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), 0x03020100); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_config_82599 - Configure general DCB parameters + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure general DCB parameters. + */ +s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw, + struct ixgbe_dcb_config *dcb_config) +{ + u32 reg; + u32 q; + + /* Disable the Tx desc arbiter so that MTQC can be changed */ + reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + reg |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); + + reg = IXGBE_READ_REG(hw, IXGBE_MRQC); + if (dcb_config->num_tcs.pg_tcs == 8) { + /* Enable DCB for Rx with 8 TCs */ + switch (reg & IXGBE_MRQC_MRQE_MASK) { + case 0: + case IXGBE_MRQC_RT4TCEN: + /* RSS disabled cases */ + reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | + IXGBE_MRQC_RT8TCEN; + break; + case IXGBE_MRQC_RSSEN: + case IXGBE_MRQC_RTRSS4TCEN: + /* RSS enabled cases */ + reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | + IXGBE_MRQC_RTRSS8TCEN; + break; + default: + /* + * Unsupported value, assume stale data, + * overwrite no RSS + */ + ASSERT(0); + reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | + IXGBE_MRQC_RT8TCEN; + } + } + if (dcb_config->num_tcs.pg_tcs == 4) { + /* We support both VT-on and VT-off with 4 TCs. */ + if (dcb_config->vt_mode) + reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | + IXGBE_MRQC_VMDQRT4TCEN; + else + reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | + IXGBE_MRQC_RTRSS4TCEN; + } + IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg); + + /* Enable DCB for Tx with 8 TCs */ + if (dcb_config->num_tcs.pg_tcs == 8) + reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ; + else { + /* We support both VT-on and VT-off with 4 TCs. */ + reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ; + if (dcb_config->vt_mode) + reg |= IXGBE_MTQC_VT_ENA; + } + IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg); + + /* Disable drop for all queues */ + for (q = 0; q < 128; q++) + IXGBE_WRITE_REG(hw, IXGBE_QDE, + (IXGBE_QDE_WRITE | (q << IXGBE_QDE_IDX_SHIFT))); + + /* Enable the Tx desc arbiter */ + reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + reg &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); + + /* Enable Security TX Buffer IFG for DCB */ + reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); + reg |= IXGBE_SECTX_DCB; + IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dcb_hw_config_82599 - Configure and enable DCB + * @hw: pointer to hardware structure + * @link_speed: unused + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @tsa: transmission selection algorithm indexed by traffic class + * @map: priority to tc assignments indexed by priority + * + * Configure dcb settings and enable dcb mode. + */ +s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, int link_speed, + u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa, + u8 *map) +{ + UNREFERENCED_1PARAMETER(link_speed); + + ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, tsa, + map); + ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, + tsa); + ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, + tsa, map); + + return IXGBE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.h new file mode 100644 index 0000000000..f430a67b2d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_82599.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_DCB_82599_H_ +#define _IXGBE_DCB_82599_H_ + +/* DCB register definitions */ +#define IXGBE_RTTDCS_TDPAC 0x00000001 /* 0 Round Robin, + * 1 WSP - Weighted Strict Priority + */ +#define IXGBE_RTTDCS_VMPAC 0x00000002 /* 0 Round Robin, + * 1 WRR - Weighted Round Robin + */ +#define IXGBE_RTTDCS_TDRM 0x00000010 /* Transmit Recycle Mode */ +#define IXGBE_RTTDCS_BDPM 0x00400000 /* Bypass Data Pipe - must clear! */ +#define IXGBE_RTTDCS_BPBFSM 0x00800000 /* Bypass PB Free Space - must + * clear! + */ +#define IXGBE_RTTDCS_SPEED_CHG 0x80000000 /* Link speed change */ + +/* Receive UP2TC mapping */ +#define IXGBE_RTRUP2TC_UP_SHIFT 3 +#define IXGBE_RTRUP2TC_UP_MASK 7 +/* Transmit UP2TC mapping */ +#define IXGBE_RTTUP2TC_UP_SHIFT 3 + +#define IXGBE_RTRPT4C_MCL_SHIFT 12 /* Offset to Max Credit Limit setting */ +#define IXGBE_RTRPT4C_BWG_SHIFT 9 /* Offset to BWG index */ +#define IXGBE_RTRPT4C_GSP 0x40000000 /* GSP enable bit */ +#define IXGBE_RTRPT4C_LSP 0x80000000 /* LSP enable bit */ + +#define IXGBE_RDRXCTL_MPBEN 0x00000010 /* DMA config for multiple packet + * buffers enable + */ +#define IXGBE_RDRXCTL_MCEN 0x00000040 /* DMA config for multiple cores + * (RSS) enable + */ + +/* RTRPCS Bit Masks */ +#define IXGBE_RTRPCS_RRM 0x00000002 /* Receive Recycle Mode enable */ +/* Receive Arbitration Control: 0 Round Robin, 1 DFP */ +#define IXGBE_RTRPCS_RAC 0x00000004 +#define IXGBE_RTRPCS_ARBDIS 0x00000040 /* Arbitration disable bit */ + +/* RTTDT2C Bit Masks */ +#define IXGBE_RTTDT2C_MCL_SHIFT 12 +#define IXGBE_RTTDT2C_BWG_SHIFT 9 +#define IXGBE_RTTDT2C_GSP 0x40000000 +#define IXGBE_RTTDT2C_LSP 0x80000000 + +#define IXGBE_RTTPT2C_MCL_SHIFT 12 +#define IXGBE_RTTPT2C_BWG_SHIFT 9 +#define IXGBE_RTTPT2C_GSP 0x40000000 +#define IXGBE_RTTPT2C_LSP 0x80000000 + +/* RTTPCS Bit Masks */ +#define IXGBE_RTTPCS_TPPAC 0x00000020 /* 0 Round Robin, + * 1 SP - Strict Priority + */ +#define IXGBE_RTTPCS_ARBDIS 0x00000040 /* Arbiter disable */ +#define IXGBE_RTTPCS_TPRM 0x00000100 /* Transmit Recycle Mode enable */ +#define IXGBE_RTTPCS_ARBD_SHIFT 22 +#define IXGBE_RTTPCS_ARBD_DCB 0x4 /* Arbitration delay in DCB mode */ + +#define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ + +/* SECTXMINIFG DCB */ +#define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer SEC IFG */ + +/* DCB driver APIs */ + +/* DCB PFC */ +s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *, u8, u8 *); + +/* DCB stats */ +s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *, + struct ixgbe_dcb_config *); +s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *, + struct ixgbe_hw_stats *, u8); +s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *, + struct ixgbe_hw_stats *, u8); + +/* DCB config arbiters */ +s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *, u16 *, u16 *, + u8 *, u8 *); +s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *, u16 *, u16 *, + u8 *, u8 *, u8 *); +s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *, u16 *, u16 *, u8 *, + u8 *, u8 *); + +/* DCB initialization */ +s32 ixgbe_dcb_config_82599(struct ixgbe_hw *, + struct ixgbe_dcb_config *); + +s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *, int, u16 *, u16 *, u8 *, + u8 *, u8 *); +#endif /* _IXGBE_DCB_82959_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_nl.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_nl.c new file mode 100644 index 0000000000..3bcd3f433a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_dcb_nl.c @@ -0,0 +1,1406 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#if IS_ENABLED(CONFIG_DCB) +#include +#include "ixgbe_dcb_82598.h" +#include "ixgbe_dcb_82599.h" + +/* Callbacks for DCB netlink in the kernel */ +#define BIT_DCB_MODE 0x01 +#define BIT_PFC 0x02 +#define BIT_PG_RX 0x04 +#define BIT_PG_TX 0x08 +#define BIT_APP_UPCHG 0x10 +#define BIT_RESETLINK 0x40 +#define BIT_LINKSPEED 0x80 + +/* Responses for the DCB_C_SET_ALL command */ +#define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */ +#define DCB_NO_HW_CHG 1 /* DCB configuration did not change */ +#define DCB_HW_CHG 2 /* DCB configuration changed, no reset */ + +int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max) +{ + struct ixgbe_dcb_config *scfg = &adapter->temp_dcb_cfg; + struct ixgbe_dcb_config *dcfg = &adapter->dcb_cfg; + struct ixgbe_dcb_tc_config *src = NULL; + struct ixgbe_dcb_tc_config *dst = NULL; + int i, j; + int tx = IXGBE_DCB_TX_CONFIG; + int rx = IXGBE_DCB_RX_CONFIG; + int changes = 0; + +#if IS_ENABLED(CONFIG_FCOE) + if (adapter->fcoe.up_set != adapter->fcoe.up) + changes |= BIT_APP_UPCHG; +#endif /* CONFIG_FCOE */ + + for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) { + src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0]; + dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0]; + + if (dst->path[tx].tsa != src->path[tx].tsa) { + dst->path[tx].tsa = src->path[tx].tsa; + changes |= BIT_PG_TX; + } + + if (dst->path[tx].bwg_id != src->path[tx].bwg_id) { + dst->path[tx].bwg_id = src->path[tx].bwg_id; + changes |= BIT_PG_TX; + } + + if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) { + dst->path[tx].bwg_percent = src->path[tx].bwg_percent; + changes |= BIT_PG_TX; + } + + if (dst->path[tx].up_to_tc_bitmap != + src->path[tx].up_to_tc_bitmap) { + dst->path[tx].up_to_tc_bitmap = + src->path[tx].up_to_tc_bitmap; + changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG); + } + + if (dst->path[rx].tsa != src->path[rx].tsa) { + dst->path[rx].tsa = src->path[rx].tsa; + changes |= BIT_PG_RX; + } + + if (dst->path[rx].bwg_id != src->path[rx].bwg_id) { + dst->path[rx].bwg_id = src->path[rx].bwg_id; + changes |= BIT_PG_RX; + } + + if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) { + dst->path[rx].bwg_percent = src->path[rx].bwg_percent; + changes |= BIT_PG_RX; + } + + if (dst->path[rx].up_to_tc_bitmap != + src->path[rx].up_to_tc_bitmap) { + dst->path[rx].up_to_tc_bitmap = + src->path[rx].up_to_tc_bitmap; + changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG); + } + } + + for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) { + j = i - DCB_PG_ATTR_BW_ID_0; + + if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) { + dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j]; + changes |= BIT_PG_TX; + } + if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) { + dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j]; + changes |= BIT_PG_RX; + } + } + + for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) { + j = i - DCB_PFC_UP_ATTR_0; + if (dcfg->tc_config[j].pfc != scfg->tc_config[j].pfc) { + dcfg->tc_config[j].pfc = scfg->tc_config[j].pfc; + changes |= BIT_PFC; + } + } + + if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) { + dcfg->pfc_mode_enable = scfg->pfc_mode_enable; + changes |= BIT_PFC; + } + + return changes; +} + +/** + * ixgbe_dcbnl_get_state - Retrieve the DCB state of the network device + * @netdev: Network device structure + * + * This function checks whether Data Center Bridging (DCB) is enabled on the + * specified network device. It accesses the adapter's flags to determine the + * DCB state and returns a boolean value indicating the result. The function + * returns `1` if DCB is enabled and `0` otherwise. + * + * Return: A boolean value (`1` or `0`) indicating whether DCB is enabled. + */ +static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); +} + +/** + * ixgbe_dcbnl_set_state - Set the DCB state of the network device + * @netdev: Network device structure + * @state: Desired state for DCB (0 to disable, non-zero to enable) + * + * This function sets the Data Center Bridging (DCB) state of the specified + * network device. It checks if the device is in CEE (Converged Enhanced Ethernet) + * mode and proceeds to update the DCB state if applicable. + * + * The function verifies if there is a change in the DCB state. If the desired + * state matches the current state, the function exits without making changes. + * Otherwise, it calls `ixgbe_setup_tc` to configure the traffic classes based + * on the desired state. If enabling DCB, it uses the number of priority groups + * configured in the device; if disabling, it sets the number of traffic classes + * to zero. + * + * Return: 0 on success, or 1 if the device is not in CEE mode or if an error + * occurs during the process. + */ +static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int err = 0; + + /* Fail command if not in CEE mode */ + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) + return 1; + + /* verify there is something to do, if not then exit */ + if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + goto out; + + err = ixgbe_setup_tc(netdev, + state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0); +out: + return !!err; +} + +/** + * ixgbe_dcbnl_get_perm_hw_addr - Retrieve the permanent hardware address + * @netdev: Network device structure + * @perm_addr: Buffer to store the permanent hardware address + * + * This function retrieves the permanent hardware address (MAC address) of the + * specified network device and stores it in the provided buffer `perm_addr`. + * The function first initializes the buffer with a default value of 0xff for + * each byte, then copies the permanent MAC address from the adapter's hardware + * structure. + * + * For certain MAC types, such as ixgbe_mac_82599EB and ixgbe_mac_X540, the + * function also appends the SAN (Storage Area Network) address to the buffer. + * This is conditional based on the hardware type and specific compile-time + * flags (e.g. MAGNOLIA_PARK_HW). + * + * This function is useful for obtaining the original hardware address of the + * device, which may be needed for various network configuration and management + * tasks. + */ +static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, + u8 *perm_addr) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i, j; + + memset(perm_addr, 0xff, MAX_ADDR_LEN); + + for (i = 0; i < netdev->addr_len; i++) + perm_addr[i] = adapter->hw.mac.perm_addr[i]; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_E610: + for (j = 0; j < netdev->addr_len; j++, i++) + perm_addr[i] = adapter->hw.mac.san_addr[j]; + break; + default: + break; + } +} + +/** + * ixgbe_dcbnl_set_pg_tc_cfg_tx - Set TX traffic class configuration + * @netdev: Network device structure + * @tc: Traffic class identifier for which to set the configuration + * @prio: Priority assignment for the traffic class + * @bwg_id: Bandwidth group identifier for the traffic class + * @bw_pct: Bandwidth percentage for the traffic class + * @up_map: User priority to traffic class mapping + * + * This function sets the transmit (TX) configuration for a specified traffic + * class (TC) on the given network device. It updates the temporary DCB + * configuration with the provided parameters, including the priority assignment + * (`tsa`), bandwidth group identifier (`bwg_id`), bandwidth percentage + * (`bwg_percent`), and user priority to traffic class mapping (`up_to_tc_bitmap`). + * + * The function first checks if the provided traffic class identifier is within + * the valid range. If the identifier is out of range, it logs an error message + * and returns without making any changes. + * + * Each parameter is only updated if it is not equal to `DCB_ATTR_VALUE_UNDEFINED`, + * allowing for selective updates of the traffic class configuration. + */ +static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, + u8 prio, u8 bwg_id, u8 bw_pct, + u8 up_map) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (tc < 0 || tc >= IXGBE_DCB_MAX_TRAFFIC_CLASS) { + netdev_err(netdev, "Traffic class out of range.\n"); + return; + } + + if (prio != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[0].tsa = prio; + if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id; + if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent = + bw_pct; + if (up_map != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap = + up_map; +} + +/** + * ixgbe_dcbnl_set_pg_bwg_cfg_tx - Set TX bandwidth percentage for a BWG + * @netdev: Network device structure + * @bwg_id: Bandwidth group identifier for which to set the configuration + * @bw_pct: Bandwidth percentage to be set for the specified bandwidth group + * + * This function sets the transmit (TX) bandwidth percentage for a specified + * bandwidth group (BWG) on the given network device. It updates the temporary + * DCB configuration with the provided bandwidth percentage for the specified + * BWG identifier. + * + * The function first checks if the provided BWG identifier is within the valid + * range. If the identifier is out of range, it logs an error message and + * returns without making any changes. + */ +static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, + u8 bw_pct) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (bwg_id < 0 || bwg_id >= IXGBE_DCB_MAX_BW_GROUP) { + netdev_err(netdev, + "BWG index out of range.\n"); + return; + } + + adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; +} + +/** + * ixgbe_dcbnl_set_pg_tc_cfg_rx - Set RX traffic class configuration + * @netdev: Network device structure + * @tc: Traffic class identifier for which to set the configuration + * @prio: Priority assignment for the traffic class + * @bwg_id: Bandwidth group identifier for the traffic class + * @bw_pct: Bandwidth percentage for the traffic class + * @up_map: User priority to traffic class mapping + * + * This function sets the receive (RX) configuration for a specified traffic + * class (TC) on the given network device. It updates the temporary DCB + * configuration with the provided parameters, including the priority assignment + * (`tsa`), bandwidth group identifier (`bwg_id`), bandwidth percentage + * (`bwg_percent`), and user priority to traffic class mapping (`up_to_tc_bitmap`). + * + * The function first checks if the provided traffic class identifier is within + * the valid range. If the identifier is out of range, it logs an error message + * and returns without making any changes. + * + * Each parameter is only updated if it is not equal to `DCB_ATTR_VALUE_UNDEFINED`, + * allowing for selective updates of the traffic class configuration. + */ +static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, + u8 prio, u8 bwg_id, u8 bw_pct, + u8 up_map) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (tc < 0 || tc >= IXGBE_DCB_MAX_TRAFFIC_CLASS) { + netdev_err(netdev, "Traffic class out of range.\n"); + return; + } + + if (prio != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[1].tsa = prio; + if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id; + if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent = + bw_pct; + if (up_map != DCB_ATTR_VALUE_UNDEFINED) + adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap = + up_map; +} + +/** + * ixgbe_dcbnl_set_pg_bwg_cfg_rx - Set RX bandwidth percentage for a BWG + * @netdev: Network device structure + * @bwg_id: Bandwidth group identifier for which to set the configuration + * @bw_pct: Bandwidth percentage to be set for the specified bandwidth group + * + * This function sets the receive (RX) bandwidth percentage for a specified + * bandwidth group (BWG) on the given network device. It updates the temporary + * DCB configuration with the provided bandwidth percentage for the specified + * BWG identifier. + * + * The function first checks if the provided BWG identifier is within the valid + * range. If the identifier is out of range, it logs an error message and + * returns without making any changes. + */ +static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, + u8 bw_pct) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (bwg_id < 0 || bwg_id >= IXGBE_DCB_MAX_BW_GROUP) { + netdev_err(netdev, + "BWG index out of range.\n"); + return; + } + + adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; +} + +/** + * ixgbe_dcbnl_get_pg_tc_cfg_tx - Retrieve TX traffic class configuration + * @netdev: Network device structure + * @tc: Traffic class identifier for which to retrieve the configuration + * @prio: Pointer to store the priority assignment for the traffic class + * @bwg_id: Pointer to store the bandwidth group identifier for the traffic class + * @bw_pct: Pointer to store the bandwidth percentage for the traffic class + * @up_map: Pointer to store the user priority to traffic class mapping + * + * This function retrieves the transmit (TX) configuration for a specified traffic + * class (TC) on the given network device. It accesses the adapter's DCB + * configuration to obtain various parameters for the specified traffic class, + * including the priority assignment (`tsa`), bandwidth group identifier (`bwg_id`), + * bandwidth percentage (`bwg_percent`), and user priority to traffic class mapping + * (`up_to_tc_bitmap`). These values are stored in the provided pointers. + */ +static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, + u8 *prio, u8 *bwg_id, u8 *bw_pct, + u8 *up_map) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + *prio = adapter->dcb_cfg.tc_config[tc].path[0].tsa; + *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id; + *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent; + *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap; +} + +/** + * ixgbe_dcbnl_get_pg_bwg_cfg_tx - Retrieve TX bandwidth percentage for a BWG + * @netdev: Network device structure + * @bwg_id: Bandwidth group identifier for which to retrieve the configuration + * @bw_pct: Pointer to a buffer where the bandwidth percentage will be stored + * + * This function retrieves the bandwidth percentage configuration for a specified + * bandwidth group (BWG) on the transmit (TX) side of the given network device. + * The function accesses the adapter's DCB configuration to obtain the bandwidth + * percentage for the specified BWG identifier and stores it in the provided + * buffer `bw_pct`. The TX side configuration is indexed by `0` in the + * `bw_percentage` array. + */ +static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, + u8 *bw_pct) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id]; +} + +/** + * ixgbe_dcbnl_get_pg_tc_cfg_rx - Retrieve RX traffic class configuration + * @netdev: Network device structure + * @tc: Traffic class identifier for which to retrieve the configuration + * @prio: Pointer to store the priority assignment for the traffic class + * @bwg_id: Pointer to store the bandwidth group identifier for the traffic class + * @bw_pct: Pointer to store the bandwidth percentage for the traffic class + * @up_map: Pointer to store the user priority to traffic class mapping + * + * This function retrieves the receive (RX) configuration for a specified traffic + * class (TC) on the given network device. It accesses the adapter's DCB + * configuration to obtain various parameters for the specified traffic class, + * including the priority assignment (`tsa`), bandwidth group identifier (`bwg_id`), + * bandwidth percentage (`bwg_percent`), and user priority to traffic class mapping + * (`up_to_tc_bitmap`). These values are stored in the provided pointers. + */ +static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc, + u8 *prio, u8 *bwg_id, u8 *bw_pct, + u8 *up_map) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + *prio = adapter->dcb_cfg.tc_config[tc].path[1].tsa; + *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id; + *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent; + *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap; +} + +/** + * ixgbe_dcbnl_get_pg_bwg_cfg_rx - Retrieve RX bandwidth percentage for a BWG + * @netdev: Network device structure + * @bwg_id: Bandwidth group identifier for which to retrieve the configuration + * @bw_pct: Pointer to a buffer where the bandwidth percentage will be stored + * + * This function retrieves the bandwidth percentage configuration for a specified + * bandwidth group (BWG) on the receive (RX) side of the given network device. + * The function accesses the adapter's DCB configuration to obtain the bandwidth + * percentage for the specified BWG identifier and stores it in the provided + * buffer `bw_pct`. The RX side configuration is indexed by `1` in the + * `bw_percentage` array. + */ +static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, + u8 *bw_pct) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id]; +} + +/** + * ixgbe_dcbnl_set_pfc_cfg - Set the PFC configuration for a specific user priority + * @netdev: Network device structure + * @up: User priority for which to set the PFC configuration + * @pfc: PFC configuration value to be set + * + * This function sets the Priority Flow Control (PFC) configuration for a + * specified user priority (UP) on the given network device. It determines the + * traffic class (TC) associated with the specified user priority and updates + * the temporary DCB configuration with the provided PFC value. + * + * If the new PFC configuration differs from the current configuration, the + * function enables the PFC mode in the temporary DCB configuration, indicating + * that a change has been made and may need to be applied to the hardware. + */ +static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int up, u8 pfc) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u8 tc = ixgbe_dcb_get_tc_from_up(&adapter->temp_dcb_cfg, 0, up); + + adapter->temp_dcb_cfg.tc_config[tc].pfc = pfc; + if (adapter->temp_dcb_cfg.tc_config[tc].pfc != + adapter->dcb_cfg.tc_config[tc].pfc) + adapter->temp_dcb_cfg.pfc_mode_enable = true; +} + +/** + * ixgbe_dcbnl_get_pfc_cfg - Retrieve the PFC configuration for a given user priority + * @netdev: Network device structure + * @up: User priority for which to retrieve the PFC configuration + * @pfc: Pointer to a buffer where the PFC configuration will be stored + * + * This function retrieves the Priority Flow Control (PFC) configuration for a + * specified user priority (UP) on the given network device. The PFC configuration + * is part of the Data Center Bridging (DCB) feature, which provides enhanced + * Ethernet capabilities for data center environments. + * + * The function first determines the traffic class (TC) associated with the + * specified user priority by calling `ixgbe_dcb_get_tc_from_up`. It then + * retrieves the PFC configuration for that traffic class from the adapter's + * DCB configuration and stores it in the provided buffer `pfc`. + * + * This function is useful for network management tools and applications that + * need to query the PFC settings of a network device to ensure proper traffic + * prioritization and flow control in a data center network. + */ +static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int up, u8 *pfc) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u8 tc = ixgbe_dcb_get_tc_from_up(&adapter->dcb_cfg, 0, up); + *pfc = adapter->dcb_cfg.tc_config[tc].pfc; +} + +/** + * ixgbe_dcbnl_devreset - Reset the network device for DCB changes + * @dev: Network device to reset + * + * This function resets the ixgbe network adapter to apply changes related + * to Data Center Bridging (DCB) configurations. It ensures that the device + * is not already in the process of resetting and stops the network + * interface if it is running. The function clears and reinitializes the + * interrupt scheme, then restarts the network interface if it was + * previously running. It manages the resetting state to prevent concurrent + * resets. + */ +static void ixgbe_dcbnl_devreset(struct net_device *dev) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + while (test_and_set_bit(__IXGBE_RESETTING, adapter->state)) + usleep_range(1000, 2000); + + if (netif_running(dev)) +#ifdef HAVE_NET_DEVICE_OPS + dev->netdev_ops->ndo_stop(dev); +#else + dev->stop(dev); +#endif + + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_init_interrupt_scheme(adapter); + + if (netif_running(dev)) +#ifdef HAVE_NET_DEVICE_OPS + dev->netdev_ops->ndo_open(dev); +#else + dev->open(dev); +#endif + + clear_bit(__IXGBE_RESETTING, adapter->state); +} + +/** + * ixgbe_dcbnl_set_all - Apply all DCB configurations to the hardware + * @netdev: Network device structure + * + * This function applies all Data Center Bridging (DCB) configurations to the + * hardware for the specified network device. It checks if the device is in CEE + * (Converged Enhanced Ethernet) mode and proceeds to update the DCB settings + * if applicable. The function handles Priority Group (PG) and Priority Flow + * Control (PFC) configurations, as well as application priority mappings. + * + * The function calculates traffic class credits and configures the hardware + * accordingly. It also manages the enabling and disabling of Malicious Driver + * Detection (MDD) around updates to ensure proper operation. + * + * If Fibre Channel over Ethernet (FCoE) is enabled, the function reprograms + * FCoE hardware offloads when necessary. + * + * Return: A status code indicating whether a hardware change was made and + * whether a reset is required. Possible return values are: + * - DCB_NO_HW_CHG: No hardware change was made. + * - DCB_HW_CHG: A hardware change was made. + * - DCB_HW_CHG_RST: A hardware change was made and a reset is required. + */ +static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; + struct ixgbe_hw *hw = &adapter->hw; + int ret = DCB_NO_HW_CHG; + u8 prio_tc[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; + + /* Fail command if not in CEE mode */ + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) + return ret; + + adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter, + IXGBE_DCB_MAX_TRAFFIC_CLASS); + if (!adapter->dcb_set_bitmap) + return ret; + + ixgbe_dcb_unpack_map_cee(dcb_cfg, IXGBE_DCB_TX_CONFIG, prio_tc); + + if (adapter->dcb_set_bitmap & (BIT_PG_TX | BIT_PG_RX)) { + /* Priority to TC mapping in CEE case default to 1:1 */ + int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; +#ifdef HAVE_MQPRIO + int i; +#endif + +#if IS_ENABLED(CONFIG_FCOE) +#ifdef HAVE_NETDEV_FCOE_MTU + if (adapter->netdev->fcoe_mtu) +#else + if (adapter->netdev->features & NETIF_F_FCOE_MTU) +#endif + max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif + + ixgbe_dcb_calculate_tc_credits_cee(hw, dcb_cfg, max_frame, + IXGBE_DCB_TX_CONFIG); + + ixgbe_dcb_calculate_tc_credits_cee(hw, dcb_cfg, max_frame, + IXGBE_DCB_RX_CONFIG); + + ixgbe_dcb_hw_config_cee(hw, dcb_cfg); + +#ifdef HAVE_MQPRIO + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) + netdev_set_prio_tc_map(netdev, i, prio_tc[i]); +#endif /* HAVE_MQPRIO */ + ret = DCB_HW_CHG_RST; + } + + if (adapter->dcb_set_bitmap & BIT_PFC) { + if (dcb_cfg->pfc_mode_enable) { + u8 pfc_en; + ixgbe_dcb_unpack_pfc_cee(dcb_cfg, prio_tc, &pfc_en); + ixgbe_dcb_config_pfc(hw, pfc_en, prio_tc); + } else { + hw->mac.ops.fc_enable(hw); + } + /* This is known driver so disable MDD before updating SRRCTL */ + if (hw->mac.ops.disable_mdd && + (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.disable_mdd(hw); + + ixgbe_set_rx_drop_en(adapter); + + if (hw->mac.ops.enable_mdd && + (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.enable_mdd(hw); + + if (ret != DCB_HW_CHG_RST) + ret = DCB_HW_CHG; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* Reprogam FCoE hardware offloads when the traffic class + * FCoE is using changes. This happens if the APP info + * changes or the up2tc mapping is updated. + */ + if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { + adapter->fcoe.up_set = adapter->fcoe.up; + ixgbe_dcbnl_devreset(netdev); + ret = DCB_HW_CHG_RST; + } +#endif /* CONFIG_FCOE */ + + adapter->dcb_set_bitmap = 0x00; + return ret; +} + +/** + * ixgbe_dcbnl_getcap - Retrieve DCB capability for a given attribute + * @netdev: Network device structure + * @capid: Capability identifier for which to retrieve the configuration + * @cap: Pointer to a buffer where the capability value will be stored + * + * This function retrieves the Data Center Bridging (DCB) capability for a + * specified attribute identified by `capid` on the given network device. The + * function sets the capability value in the provided buffer `cap` based on the + * attribute requested. It supports various DCB capabilities, such as Priority + * Groups (PG), Priority Flow Control (PFC), User Priority to Traffic Class + * mapping (UP2TC), and others. + * + * The function uses a switch statement to determine the capability value for + * each supported attribute. If the attribute is not recognized, the capability + * is set to `false`. + * + * Return: Always returns 0. + */ +static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) +{ +#ifdef HAVE_DCBNL_IEEE + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#endif + + switch (capid) { + case DCB_CAP_ATTR_PG: + *cap = true; + break; + case DCB_CAP_ATTR_PFC: + *cap = true; + break; + case DCB_CAP_ATTR_UP2TC: + *cap = false; + break; + case DCB_CAP_ATTR_PG_TCS: + *cap = 0x80; + break; + case DCB_CAP_ATTR_PFC_TCS: + *cap = 0x80; + break; + case DCB_CAP_ATTR_GSP: + *cap = true; + break; + case DCB_CAP_ATTR_BCN: + *cap = false; + break; +#ifdef HAVE_DCBNL_IEEE + case DCB_CAP_ATTR_DCBX: + *cap = adapter->dcbx_cap; + break; +#endif + default: + *cap = false; + break; + } + + return 0; +} + +/** + * ixgbe_dcbnl_getnumtcs - Retrieve the number of traffic classes for a given attribute + * @netdev: Network device structure + * @tcid: Traffic class identifier attribute for which to retrieve the number of TCs + * @num: Pointer to a buffer where the number of traffic classes will be stored + * + * This function retrieves the number of traffic classes (TCs) for a specified + * attribute identified by `tcid` on the given network device. It checks if Data + * Center Bridging (DCB) is enabled and then accesses the adapter's DCB + * configuration to obtain the number of TCs for the specified attribute. The + * result is stored in the provided buffer `num`. + * + * The function supports attributes such as Priority Groups (PG) and Priority + * Flow Control (PFC). If DCB is not enabled or the attribute is not recognized, + * the function returns an error value. + * + * Return: 0 on success, or a negative error code (-EINVAL) if DCB is not enabled + * or the attribute is invalid. The return type is `u8` or `int` based on + * the `NUMTCS_RETURNS_U8` preprocessor directive. + */ +#ifdef NUMTCS_RETURNS_U8 +static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) +#else +static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u8 rval = 0; + + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + switch (tcid) { + case DCB_NUMTCS_ATTR_PG: + *num = adapter->dcb_cfg.num_tcs.pg_tcs; + break; + case DCB_NUMTCS_ATTR_PFC: + *num = adapter->dcb_cfg.num_tcs.pfc_tcs; + break; + default: + rval = -EINVAL; + break; + } + } else { + rval = -EINVAL; + } + + return rval; +} + +/** + * ixgbe_dcbnl_setnumtcs - Set the number of traffic classes for a given attribute + * @netdev: Network device structure + * @tcid: Traffic class identifier attribute for which to set the number of TCs + * @num: Number of traffic classes to be set for the specified attribute + * + * This function sets the number of traffic classes (TCs) for a specified + * attribute identified by `tcid` on the given network device. It updates the + * adapter's DCB configuration with the provided number of TCs for the specified + * attribute, such as Priority Groups (PG) or Priority Flow Control (PFC). + * + * The function first checks if DCB is enabled on the device. If not, or if the + * attribute is not recognized, it returns an error value. + * + * Return: 0 on success, or a negative error code (-EINVAL) if DCB is not enabled + * or the attribute is invalid. The return type is `u8` or `int` based on + * the `NUMTCS_RETURNS_U8` preprocessor directive. + */ +#ifdef NUMTCS_RETURNS_U8 +static u8 ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) +#else +static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u8 rval = 0; + + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + switch (tcid) { + case DCB_NUMTCS_ATTR_PG: + adapter->dcb_cfg.num_tcs.pg_tcs = num; + break; + case DCB_NUMTCS_ATTR_PFC: + adapter->dcb_cfg.num_tcs.pfc_tcs = num; + break; + default: + rval = -EINVAL; + break; + } + } else { + rval = -EINVAL; + } + + return rval; +} + +/** + * ixgbe_dcbnl_getpfcstate - Retrieve the PFC state of the network device + * @netdev: Network device structure + * + * This function retrieves the Priority Flow Control (PFC) state of the specified + * network device. It accesses the adapter's DCB configuration to obtain the PFC + * mode enable status and returns it. The PFC state indicates whether PFC is + * enabled or disabled on the device. + * + * Return: The PFC mode enable status of the network device. + */ +static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + return adapter->dcb_cfg.pfc_mode_enable; +} + +/** + * ixgbe_dcbnl_setpfcstate - Set the PFC state of the network device + * @netdev: Network device structure + * @state: Desired state for PFC (0 to disable, non-zero to enable) + * + * This function sets the Priority Flow Control (PFC) state for the specified + * network device. It updates the temporary DCB configuration to reflect the + * desired PFC state, enabling or disabling PFC as specified by the `state` + * parameter. + * + * The function directly modifies the `pfc_mode_enable` field in the temporary + * DCB configuration, which may later be applied to the hardware. + */ +static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + adapter->temp_dcb_cfg.pfc_mode_enable = state; + return; +} + +#ifdef HAVE_DCBNL_OPS_GETAPP +/** + * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority + * @netdev : the corresponding netdev + * @idtype : identifies the id as ether type or TCP/UDP port number + * @id: id is either ether type or TCP/UDP port number + * + * Returns : on success, returns a non-zero 802.1p user priority bitmap + * otherwise returns 0 as the invalid user priority bitmap to indicate an + * error. + */ +#ifdef HAVE_DCBNL_OPS_SETAPP_RETURN_INT +static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) +#else +static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) +#endif +{ + u8 rval = 0; +#ifdef HAVE_DCBNL_IEEE + struct dcb_app app = { + .selector = idtype, + .protocol = id, + }; + + rval = dcb_getapp(netdev, &app); +#endif + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: +#if IS_ENABLED(CONFIG_FCOE) + if (id == ETH_P_FCOE) + rval = ixgbe_fcoe_getapp(netdev); +#endif + break; + case DCB_APP_IDTYPE_PORTNUM: + break; + default: + break; + } + + return rval; +} + +/** + * ixgbe_dcbnl_setapp - set the DCBX application user priority + * @netdev: the corresponding netdev + * @idtype: identifies the id as ether type or TCP/UDP port number + * @id: id is either ether type or TCP/UDP port number + * @up: the 802.1p user priority bitmap + * + * Returns : 0 on success or 1 on error + */ +#ifdef HAVE_DCBNL_OPS_SETAPP_RETURN_INT +static int ixgbe_dcbnl_setapp(struct net_device *netdev, + u8 idtype, u16 id, u8 up) +#else +static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, + u8 idtype, u16 id, u8 up) +#endif +{ + int err = 0; +#ifdef HAVE_DCBNL_IEEE + struct dcb_app app; + + app.selector = idtype; + app.protocol = id; + app.priority = up; + err = dcb_setapp(netdev, &app); +#endif + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: +#if IS_ENABLED(CONFIG_FCOE) + if (id == ETH_P_FCOE) { + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + adapter->fcoe.up = up ? ffs(up) - 1 : IXGBE_FCOE_DEFUP; + } +#endif + break; + case DCB_APP_IDTYPE_PORTNUM: + break; + default: + break; + } + + return err; +} +#endif /* HAVE_DCBNL_OPS_GETAPP */ + +#ifdef HAVE_DCBNL_IEEE +/** + * ixgbe_dcbnl_ieee_getets - Retrieve IEEE ETS configuration + * @dev: Network device structure + * @ets: Pointer to the IEEE ETS structure where the configuration will be stored + * + * This function retrieves the Enhanced Transmission Selection (ETS) configuration + * for the specified network device according to the IEEE 802.1Qaz standard. It + * accesses the adapter's stored ETS configuration and copies it into the provided + * `ets` structure. + * + * The function sets the ETS capability (`ets_cap`) based on the number of priority + * groups configured in the device. It also copies the Class-Based Shaping (CBS) + * settings, transmit and receive bandwidth allocations (`tc_tx_bw` and `tc_rx_bw`), + * traffic selection algorithms (`tc_tsa`), and priority to traffic class mappings + * (`prio_tc`) from the adapter's ETS configuration. + * + * If no IEEE ETS settings are available, the function returns an error. + * + * Return: 0 on success, or a negative error code (-EINVAL) if no ETS settings are + * available. + */ +static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, + struct ieee_ets *ets) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; + + /* No IEEE PFC settings available */ + if (!my_ets) + return -EINVAL; + + ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs; + ets->cbs = my_ets->cbs; + memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); + memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); + memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); + memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); + return 0; +} + +/** + * ixgbe_dcbnl_ieee_setets - Set IEEE ETS configuration + * @dev: Network device structure + * @ets: Pointer to the IEEE ETS structure containing the configuration to be set + * + * This function sets the Enhanced Transmission Selection (ETS) configuration + * for the specified network device according to the IEEE 802.1Qaz standard. It + * first checks if the device supports IEEE DCBX (Data Center Bridging Exchange) + * version. If not, it returns an error. + * + * The function allocates memory for the ETS configuration if it hasn't been + * initialized yet and attempts to update the User Priority to Traffic Class + * (UP2TC) mappings from hardware if possible. It then updates the ETS + * configuration with the provided settings and checks for changes in the + * traffic class mappings. + * + * If the number of traffic classes (`max_tc`) changes, the function calls + * `ixgbe_setup_tc` to reconfigure the traffic classes. If only the mappings + * change, it resets the device's DCB configuration. + * + * Finally, the function updates the hardware ETS settings using + * `ixgbe_dcb_hw_ets`. + * + * Return: 0 on success, or a negative error code (-EINVAL, -ENOMEM) if an error + * occurs during the process. + */ +static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, + struct ieee_ets *ets) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; + int i, err = 0; + __u8 max_tc = 0; + __u8 map_chg = 0; + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; + + if (!adapter->ixgbe_ieee_ets) { + adapter->ixgbe_ieee_ets = kzalloc(sizeof(struct ieee_ets), + GFP_KERNEL); + if (!adapter->ixgbe_ieee_ets) + return -ENOMEM; + /* initialize UP2TC mappings to invalid value */ + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) + adapter->ixgbe_ieee_ets->prio_tc[i] = + IEEE_8021QAZ_MAX_TCS; + /* if possible update UP2TC mappings from HW */ + if (adapter->hw.mac.ops.get_rtrup2tc) + adapter->hw.mac.ops.get_rtrup2tc(&adapter->hw, + adapter->ixgbe_ieee_ets->prio_tc); + } + + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + if (ets->prio_tc[i] > max_tc) + max_tc = ets->prio_tc[i]; + if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i]) + map_chg = 1; + } + + memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); + + if (max_tc) + max_tc++; + + if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs) + return -EINVAL; + + if (max_tc != netdev_get_num_tc(dev)) + err = ixgbe_setup_tc(dev, max_tc); + else if (map_chg) + ixgbe_dcbnl_devreset(dev); + + if (err) + goto err_out; + + err = ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame); +err_out: + return err; +} + +/** + * ixgbe_dcbnl_ieee_getpfc - Retrieve IEEE PFC configuration + * @dev: Network device structure + * @pfc: Pointer to the IEEE PFC structure where the configuration will be stored + * + * This function retrieves the Priority Flow Control (PFC) configuration for the + * specified network device according to the IEEE 802.1Qaz standard. It accesses + * the adapter's stored PFC configuration and copies it into the provided `pfc` + * structure. + * + * The function sets the PFC capability (`pfc_cap`) based on the number of traffic + * classes configured for PFC in the device. It also copies the PFC enable mask + * (`pfc_en`), the MAC control frame support (`mbc`), and the delay time for PFC + * frames (`delay`) from the adapter's PFC configuration. + * + * Additionally, the function populates the `requests` and `indications` arrays + * with the number of PFC requests and indications for each traffic class, using + * statistics from the adapter. + * + * If no IEEE PFC settings are available, the function returns an error. + * + * Return: 0 on success, or a negative error code (-EINVAL) if no PFC settings are + * available. + */ +static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, + struct ieee_pfc *pfc) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; + int i; + + /* No IEEE PFC settings available */ + if (!my_pfc) + return -EINVAL; + + pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs; + pfc->pfc_en = my_pfc->pfc_en; + pfc->mbc = my_pfc->mbc; + pfc->delay = my_pfc->delay; + + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + pfc->requests[i] = adapter->stats.pxoffrxc[i]; + pfc->indications[i] = adapter->stats.pxofftxc[i]; + } + + return 0; +} + +/** + * ixgbe_dcbnl_ieee_setpfc - Set IEEE PFC configuration + * @dev: Network device structure + * @pfc: Pointer to the IEEE PFC structure containing the configuration to be set + * + * This function sets the Priority Flow Control (PFC) configuration for the + * specified network device according to the IEEE 802.1Qaz standard. It first + * checks if the device supports IEEE DCBX (Data Center Bridging Exchange) + * version. If not, it returns an error. + * + * The function allocates memory for the PFC configuration if it hasn't been + * initialized yet. It then updates the adapter's PFC configuration with the + * provided settings. + * + * If PFC is enabled, the function configures the PFC settings using + * `ixgbe_dcb_config_pfc`, passing the PFC enable mask and the priority to + * traffic class mapping. If PFC is disabled, it enables standard link flow + * control using the hardware's `fc_enable` operation. + * + * The function also handles the disabling and enabling of Malicious Driver + * Detection (MDD) around the update of the SRRCTL register to ensure proper + * operation. + * + * Return: 0 on success, or a negative error code (-EINVAL, -ENOMEM) if an error + * occurs during the process. + */ +static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, + struct ieee_pfc *pfc) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + u8 *prio_tc; + int err; + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; + + if (!adapter->ixgbe_ieee_pfc) { + adapter->ixgbe_ieee_pfc = kzalloc(sizeof(struct ieee_pfc), + GFP_KERNEL); + if (!adapter->ixgbe_ieee_pfc) + return -ENOMEM; + } + + prio_tc = adapter->ixgbe_ieee_ets->prio_tc; + memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); + + + /* Enable link flow control parameters if PFC is disabled */ + if (pfc->pfc_en) + err = ixgbe_dcb_config_pfc(hw, pfc->pfc_en, prio_tc); + else + err = hw->mac.ops.fc_enable(hw); + + /* This is known driver so disable MDD before updating SRRCTL */ + if (hw->mac.ops.disable_mdd && + (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.disable_mdd(hw); + + ixgbe_set_rx_drop_en(adapter); + + if (hw->mac.ops.enable_mdd && + (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.enable_mdd(hw); + + return err; +} + +/** + * ixgbe_dcbnl_ieee_setapp - Set an IEEE DCB application priority mapping + * @dev: Network device structure + * @app: Pointer to the DCB application structure to be set + * + * This function sets an IEEE Data Center Bridging (DCB) application priority + * mapping for the specified network device. It first checks if the device + * supports IEEE DCBX (Data Center Bridging Exchange) version. If not, it returns + * an error. The function then calls `dcb_ieee_setapp` to apply the application + * mapping. + * + * If Fibre Channel over Ethernet (FCoE) is enabled in the kernel configuration + * and the application being set is related to FCoE, the function updates the + * FCoE user priority (UP) and resets the device's DCB configuration if necessary. + * + * Return: 0 on success, or a negative error code (-EINVAL) if IEEE DCBX is not + * supported or if the setting fails. + */ +static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, + struct dcb_app *app) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int err = -EINVAL; + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return err; + + err = dcb_ieee_setapp(dev, app); + +#if IS_ENABLED(CONFIG_FCOE) + if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && + app->protocol == ETH_P_FCOE) { + u8 app_mask = dcb_ieee_getapp_mask(dev, app); + + if (app_mask & (1 << adapter->fcoe.up)) + return err; + + adapter->fcoe.up = app->priority; + adapter->fcoe.up_set = adapter->fcoe.up; + ixgbe_dcbnl_devreset(dev); + } +#endif + return 0; +} + +#ifdef HAVE_DCBNL_IEEE_DELAPP +/** + * ixgbe_dcbnl_ieee_delapp - Delete an IEEE DCB application priority mapping + * @dev: Network device structure + * @app: Pointer to the DCB application structure to be deleted + * + * This function deletes an IEEE Data Center Bridging (DCB) application priority + * mapping from the specified network device. It first checks if the device + * supports IEEE DCBX (Data Center Bridging Exchange) version. If not, it returns + * an error. The function then calls `dcb_ieee_delapp` to remove the application + * mapping. + * + * If Fibre Channel over Ethernet (FCoE) is enabled in the kernel configuration + * and the application being deleted is related to FCoE, the function updates the + * FCoE user priority (UP) if necessary and resets the device's DCB configuration. + * + * Return: 0 on success, or a negative error code (-EINVAL) if IEEE DCBX is not + * supported or if the deletion fails. + */ +static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev, + struct dcb_app *app) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int err; + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; + + err = dcb_ieee_delapp(dev, app); + +#if IS_ENABLED(CONFIG_FCOE) + if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && + app->protocol == ETH_P_FCOE) { + u8 app_mask = dcb_ieee_getapp_mask(dev, app); + + if (app_mask & (1 << adapter->fcoe.up)) + return err; + + adapter->fcoe.up = app_mask ? + ffs(app_mask) - 1 : IXGBE_FCOE_DEFUP; + ixgbe_dcbnl_devreset(dev); + } +#endif + return err; +} +#endif /* HAVE_DCBNL_IEEE_DELAPP */ + +/** + * ixgbe_dcbnl_getdcbx - Retrieve the DCBX capability of the network device + * @dev: Network device structure + * + * This function retrieves the Data Center Bridging Exchange (DCBX) capability + * of the specified network device. It accesses the adapter's configuration to + * obtain the DCBX capability value and returns it. The DCBX capability + * indicates the level of DCBX support provided by the device. + * + * Return: The DCBX capability value of the network device. + */ +static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + return adapter->dcbx_cap; +} + +/** + * ixgbe_dcbnl_setdcbx - Set the DCBX mode of the network device + * @dev: Network device structure + * @mode: Desired DCBX mode to be set + * + * This function sets the Data Center Bridging Exchange (DCBX) mode for the + * specified network device. It checks for unsupported configurations, such as + * LLD_MANAGED modes or simultaneous CEE and IEEE modes, and returns an error + * if any are detected. The function also ensures that the mode includes + * DCB_CAP_DCBX_HOST. + * + * If the desired mode is already set, the function exits without making changes. + * Otherwise, it updates the adapter's DCBX capability and applies default + * Enhanced Transmission Selection (ETS) and Priority Flow Control (PFC) + * configurations. + * + * Depending on the mode, the function configures the device for IEEE or CEE + * DCBX. For IEEE, it sets ETS and PFC using the respective functions. For CEE, + * it sets a bitmap for DCB configuration and applies all settings. If both CEE + * and IEEE are disabled, the function configures the device for single traffic + * class mode with strict priority. + * + * Return: 0 on success, or 1 if an unsupported configuration is detected. + */ +static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ieee_ets ets = { .ets_cap = 0 }; + struct ieee_pfc pfc = { .pfc_en = 0 }; + + /* no support for LLD_MANAGED modes or CEE+IEEE */ + if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || + ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || + !(mode & DCB_CAP_DCBX_HOST)) + return 1; + + if (mode == adapter->dcbx_cap) + return 0; + + adapter->dcbx_cap = mode; + + /* ETS and PFC defaults */ + ets.ets_cap = 8; + pfc.pfc_cap = 8; + + if (mode & DCB_CAP_DCBX_VER_IEEE) { + ixgbe_dcbnl_ieee_setets(dev, &ets); + ixgbe_dcbnl_ieee_setpfc(dev, &pfc); + } else if (mode & DCB_CAP_DCBX_VER_CEE) { + u8 mask = (BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG); + + adapter->dcb_set_bitmap |= mask; + ixgbe_dcbnl_set_all(dev); + } else { + /* Drop into single TC mode strict priority as this + * indicates CEE and IEEE versions are disabled + */ + ixgbe_dcbnl_ieee_setets(dev, &ets); + ixgbe_dcbnl_ieee_setpfc(dev, &pfc); + ixgbe_setup_tc(dev, 0); + } + + return 0; +} + +#endif + +struct dcbnl_rtnl_ops ixgbe_dcbnl_ops = { +#ifdef HAVE_DCBNL_IEEE + .ieee_getets = ixgbe_dcbnl_ieee_getets, + .ieee_setets = ixgbe_dcbnl_ieee_setets, + .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, + .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, + .ieee_setapp = ixgbe_dcbnl_ieee_setapp, +#ifdef HAVE_DCBNL_IEEE_DELAPP + .ieee_delapp = ixgbe_dcbnl_ieee_delapp, +#endif +#endif + .getstate = ixgbe_dcbnl_get_state, + .setstate = ixgbe_dcbnl_set_state, + .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, + .setpgtccfgtx = ixgbe_dcbnl_set_pg_tc_cfg_tx, + .setpgbwgcfgtx = ixgbe_dcbnl_set_pg_bwg_cfg_tx, + .setpgtccfgrx = ixgbe_dcbnl_set_pg_tc_cfg_rx, + .setpgbwgcfgrx = ixgbe_dcbnl_set_pg_bwg_cfg_rx, + .getpgtccfgtx = ixgbe_dcbnl_get_pg_tc_cfg_tx, + .getpgbwgcfgtx = ixgbe_dcbnl_get_pg_bwg_cfg_tx, + .getpgtccfgrx = ixgbe_dcbnl_get_pg_tc_cfg_rx, + .getpgbwgcfgrx = ixgbe_dcbnl_get_pg_bwg_cfg_rx, + .setpfccfg = ixgbe_dcbnl_set_pfc_cfg, + .getpfccfg = ixgbe_dcbnl_get_pfc_cfg, + .setall = ixgbe_dcbnl_set_all, + .getcap = ixgbe_dcbnl_getcap, + .getnumtcs = ixgbe_dcbnl_getnumtcs, + .setnumtcs = ixgbe_dcbnl_setnumtcs, + .getpfcstate = ixgbe_dcbnl_getpfcstate, + .setpfcstate = ixgbe_dcbnl_setpfcstate, +#ifdef HAVE_DCBNL_OPS_GETAPP + .getapp = ixgbe_dcbnl_getapp, + .setapp = ixgbe_dcbnl_setapp, +#endif +#ifdef HAVE_DCBNL_IEEE + .getdcbx = ixgbe_dcbnl_getdcbx, + .setdcbx = ixgbe_dcbnl_setdcbx, +#endif +}; + +#endif /* CONFIG_DCB */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_debugfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_debugfs.c new file mode 100644 index 0000000000..a2923f6b12 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_debugfs.c @@ -0,0 +1,1447 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#ifdef HAVE_IXGBE_DEBUG_FS +#include +#include + +static struct dentry *ixgbe_dbg_root; + +#define IXGBE_FW_DUMP_BLK_MAX 0xFFFF +#define IXGBE_FW_DUMP_DATA_SIZE 4096 +#define IXGBE_FW_DUMP_HDR_SIZE 24 +/* dump blk = Cluster header + dump data */ +#define IXGBE_FW_DUMP_BLK_SIZE (IXGBE_FW_DUMP_DATA_SIZE + IXGBE_FW_DUMP_HDR_SIZE) +#define IXGBE_FW_DUMP_FILENAME "debug_dump" +#define IXGBE_FW_DUMP_LAST_IDX 0xFFFFFFFF +#define IXGBE_FW_DUMP_LAST_ID 0xFF +#define IXGBE_FW_DUMP_LAST_ID2 0xFFFF + +static char ixgbe_dbg_reg_ops_buf[256] = ""; + +/* the ordering in this array is important. it matches the ordering of the + * values in the FW so the index is the same value as in ice_aqc_fw_logging_mod + */ +static const char * const ixgbe_fwlog_module_string[] = { + "GENERAL", + "CTRL", + "LINK", + "LINK_TOPO", + "DNL", + "I2C", + "SDP", + "MDIO", + "ADMINQ", + "HDMA", + "LLDP", + "DCBX", + "DCB", + "XLR", + "NVM", + "AUTH", + "VPD", + "IOSF", + "PARSER", + "SW", + "SCHEDULER", + "TXQ", + "RSVD", + "POST", + "WATCHDOG", + "TASK_DISPATCH", + "MNG", + "SYNCE", + "HEALTH", + "TSDRV", + "PFREG", + "MDLVER", + "ALL", +}; + +/* the ordering in this array is important. it matches the ordering of the + * values in the FW so the index is the same value as in ice_fwlog_level + */ +static const char * const ixgbe_fwlog_level_string[] = { + "NONE", + "ERROR", + "WARNING", + "NORMAL", + "VERBOSE", +}; + +static void ixgbe_print_fwlog_config(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg, + char **buff, int *size) +{ + char *tmp = *buff; + int used = *size; + u16 i, len; + + len = snprintf(tmp, used, "Log_resolution: %d\n", cfg->log_resolution); + tmp = tmp + len; + used -= len; + len = snprintf(tmp, used, "Options: 0x%04x\n", cfg->options); + tmp = tmp + len; + used -= len; + len = snprintf(tmp, used, "\tarq_ena: %s\n", + (cfg->options & + IXGBE_FWLOG_OPTION_ARQ_ENA) ? "true" : "false"); + tmp = tmp + len; + used -= len; + len = snprintf(tmp, used, "\tuart_ena: %s\n", + (cfg->options & + IXGBE_FWLOG_OPTION_UART_ENA) ? "true" : "false"); + tmp = tmp + len; + used -= len; + len = snprintf(tmp, used, "\trunning: %s\n", + (cfg->options & + IXGBE_FWLOG_OPTION_IS_REGISTERED) ? "true" : "false"); + tmp = tmp + len; + used -= len; + len = snprintf(tmp, used, "Module Entries:\n"); + tmp = tmp + len; + used -= len; + + for (i = 0; i < IXGBE_ACI_FW_LOG_ID_MAX; i++) { + struct ixgbe_fwlog_module_entry *entry = + &cfg->module_entries[i]; + + /* TODO: Remove this hack when SyncE gets turned on always */ + if (i == IXGBE_ACI_FW_LOG_ID_SYNCE) + continue; + + len = snprintf(tmp, used, "\tModule: %s, Log Level: %s\n", + ixgbe_fwlog_module_string[entry->module_id], + ixgbe_fwlog_level_string[entry->log_level]); + tmp = tmp + len; + used -= len; + } + + len = snprintf(tmp, used, "Valid log levels:\n"); + tmp = tmp + len; + used -= len; + + for (i = 0; i < IXGBE_FWLOG_LEVEL_INVALID; i++) { + len = snprintf(tmp, used, "\t%s\n", ixgbe_fwlog_level_string[i]); + tmp = tmp + len; + used -= len; + } + + *buff = tmp; + *size = used; +} + +/** + * ixgbe_fwlog_dump_cfg - Dump current FW logging configuration + * @hw: pointer to the HW structure + * @buff: pointer to a buffer to hold the config strings + * @buff_size: size of the buffer in bytes + */ +static void ixgbe_fwlog_dump_cfg(struct ixgbe_hw *hw, char *buff, int buff_size) +{ + int len; + + len = snprintf(buff, buff_size, "FWLOG Configuration:\n"); + buff = buff + len; + buff_size -= len; + + ixgbe_print_fwlog_config(hw, &hw->fwlog_cfg, &buff, &buff_size); +} + +/** + * ixgbe_debugfs_parse_cmd_line - Parse the command line that was passed in + * @src: pointer to a buffer holding the command line + * @len: size of the buffer in bytes + * @argv: pointer to store the command line items + * @argc: pointer to store the number of command line items + */ +static ssize_t ixgbe_debugfs_parse_cmd_line(const char __user *src, size_t len, + char ***argv, int *argc) +{ + char *cmd_buf, *cmd_buf_tmp; + + cmd_buf = memdup_user(src, len + 1); + if (IS_ERR(cmd_buf)) + return PTR_ERR(cmd_buf); + cmd_buf[len] = '\0'; + + /** the cmd_buf has a newline at the end of the command so + * remove it + */ + cmd_buf_tmp = strchr(cmd_buf, '\n'); + if (cmd_buf_tmp) { + *cmd_buf_tmp = '\0'; + len = (size_t)cmd_buf_tmp - (size_t)cmd_buf + 1; + } + + *argv = argv_split(GFP_KERNEL, cmd_buf, argc); + if (!*argv) + return -ENOMEM; + + kfree(cmd_buf); + return 0; +} + +/** + * ixgbe_dbg_reg_ops_read - Read reg_ops data for debugging + * @filp: The opened file + * @buffer: Buffer where the data is written for the user to read + * @count: Size of the user's buffer + * @ppos: File position offset + * + * This function reads the reg_ops data for debugging purposes from the + * ixgbe network adapter. It formats the data into a string and writes it to + * the user's buffer. The function does not allow partial reads and returns + * an error if the user's buffer is too small to hold the data. + * + * Return: Number of bytes read on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_dbg_reg_ops_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = filp->private_data; + char *buf; + int len; + + /* don't allow partial reads */ + if (*ppos != 0) + return 0; + + buf = kasprintf(GFP_KERNEL, "%s: %s\n", + adapter->netdev->name, + ixgbe_dbg_reg_ops_buf); + if (!buf) + return -ENOMEM; + + if (count < strlen(buf)) { + kfree(buf); + return -ENOSPC; + } + + len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); + + kfree(buf); + return len; +} + +/** + * ixgbe_dbg_reg_ops_write - Write data to reg_ops for debugging + * @filp: The opened file + * @buffer: Buffer containing the user's data + * @count: Length of the user's data + * @ppos: File position offset + * + * This function writes user-provided data to the reg_ops buffer for + * debugging purposes. It processes specific commands, such as "read" and + * "write", to perform register operations on the ixgbe network adapter. The + * function does not allow partial writes and returns an error if the data + * exceeds the buffer size. If an unknown command is received, it logs + * available commands. + * + * Return: Number of bytes written on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = filp->private_data; + int len; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + if (count >= sizeof(ixgbe_dbg_reg_ops_buf)) + return -ENOSPC; + + len = simple_write_to_buffer(ixgbe_dbg_reg_ops_buf, + sizeof(ixgbe_dbg_reg_ops_buf)-1, + ppos, + buffer, + count); + if (len < 0) + return len; + + ixgbe_dbg_reg_ops_buf[len] = '\0'; + + if (strncmp(ixgbe_dbg_reg_ops_buf, "write", 5) == 0) { + u32 reg, value; + int cnt; + cnt = sscanf(&ixgbe_dbg_reg_ops_buf[5], "%x %x", ®, &value); + /* check format and bounds check register access */ + if (cnt == 2 && reg <= IXGBE_HFDR) { + IXGBE_WRITE_REG(&adapter->hw, reg, value); + value = IXGBE_READ_REG(&adapter->hw, reg); + e_dev_info("write: 0x%08x = 0x%08x\n", reg, value); + } else { + e_dev_info("write \n"); + } + } else if (strncmp(ixgbe_dbg_reg_ops_buf, "read", 4) == 0) { + u32 reg, value; + int cnt; + cnt = sscanf(&ixgbe_dbg_reg_ops_buf[4], "%x", ®); + /* check format and bounds check register access */ + if (cnt == 1 && reg <= IXGBE_HFDR) { + value = IXGBE_READ_REG(&adapter->hw, reg); + e_dev_info("read 0x%08x = 0x%08x\n", reg, value); + } else { + e_dev_info("read \n"); + } + } else { + e_dev_info("Unknown command %s\n", ixgbe_dbg_reg_ops_buf); + e_dev_info("Available commands:\n"); + e_dev_info(" read \n"); + e_dev_info(" write \n"); + } + return count; +} + +static const struct file_operations ixgbe_dbg_reg_ops_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_dbg_reg_ops_read, + .write = ixgbe_dbg_reg_ops_write, +}; + +static char ixgbe_dbg_netdev_ops_buf[256] = ""; + +/** + * ixgbe_dbg_netdev_ops_read - Read netdev_ops data for debugging + * @filp: The opened file + * @buffer: Buffer where the data is written for the user to read + * @count: Size of the user's buffer + * @ppos: File position offset + * + * This function reads the netdev_ops data for debugging purposes from the + * ixgbe network adapter. It formats the data into a string and writes it to + * the user's buffer. The function does not allow partial reads and returns + * an error if the user's buffer is too small to hold the data. + * + * Return: Number of bytes read on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_dbg_netdev_ops_read(struct file *filp, + char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = filp->private_data; + char *buf; + int len; + + /* don't allow partial reads */ + if (*ppos != 0) + return 0; + + buf = kasprintf(GFP_KERNEL, "%s: %s\n", + adapter->netdev->name, + ixgbe_dbg_netdev_ops_buf); + if (!buf) + return -ENOMEM; + + if (count < strlen(buf)) { + kfree(buf); + return -ENOSPC; + } + + len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); + + kfree(buf); + return len; +} + +/** + * ixgbe_dbg_netdev_ops_write - Write data to netdev_ops for debugging + * @filp: The opened file + * @buffer: Buffer containing the user's data + * @count: Length of the user's data + * @ppos: File position offset + * + * This function writes user-provided data to the netdev_ops buffer for + * debugging purposes. It processes specific commands, such as "tx_timeout", + * to trigger corresponding network device operations. The function does not + * allow partial writes and returns an error if the data exceeds the buffer + * size. If an unknown command is received, it logs available commands. + * + * Return: Number of bytes written on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_dbg_netdev_ops_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = filp->private_data; + int len; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + if (count >= sizeof(ixgbe_dbg_netdev_ops_buf)) + return -ENOSPC; + + len = simple_write_to_buffer(ixgbe_dbg_netdev_ops_buf, + sizeof(ixgbe_dbg_netdev_ops_buf)-1, + ppos, + buffer, + count); + if (len < 0) + return len; + + ixgbe_dbg_netdev_ops_buf[len] = '\0'; + + if (strncmp(ixgbe_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) { +#ifdef HAVE_NET_DEVICE_OPS +#ifdef HAVE_TX_TIMEOUT_TXQUEUE + adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev, + UINT_MAX); +#else + adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev); +#endif +#else + adapter->netdev->tx_timeout(adapter->netdev); +#endif /* HAVE_NET_DEVICE_OPS */ + e_dev_info("tx_timeout called\n"); + } else { + e_dev_info("Unknown command: %s\n", ixgbe_dbg_netdev_ops_buf); + e_dev_info("Available commands:\n"); + e_dev_info(" tx_timeout\n"); + } + return count; +} + +static struct file_operations ixgbe_dbg_netdev_ops_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_dbg_netdev_ops_read, + .write = ixgbe_dbg_netdev_ops_write, +}; + +struct ixgbe_cluster_header { + u32 cluster_id; + u32 table_id; + u32 table_len; + u32 table_offset; + u32 reserved[2]; +}; + +/** + * ixgbe_get_last_table_id - get a value that should be used as End of Table + * @adapter: pointer to adapter struct + * + * Different versions of FW may indicate End Of Table by different value. Read + * FW capabilities and decide what value to use as End of Table. + * + * Return: end of table identifier. + */ +static u16 ixgbe_get_last_table_id(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.func_caps.common_cap.next_cluster_id_support || + adapter->hw.dev_caps.common_cap.next_cluster_id_support) + return IXGBE_FW_DUMP_LAST_ID2; + else + return IXGBE_FW_DUMP_LAST_ID; +} + +/** + * ixgbe_debugfs_fw_dump - send request to FW to dump cluster and save to file + * @adapter: pointer to adapter struct + * @cluster_id: number or FW cluster to be dumped + * @read_all_clusters: ignore cluster_id and dump all clusters + * + * Create FW configuration binary snapshot. Repeatedly send ACI requests to dump + * FW cluster, FW responds in 4KB blocks and sets new values for table_id + * and table_idx. Repeat until all tables in given cluster were read. + * + * Return: 0 on success or error code on failure. + */ +static int ixgbe_debugfs_fw_dump(struct ixgbe_adapter *adapter, + u16 cluster_id, bool read_all_clusters) +{ + u16 buf_len, next_tbl_id, next_cluster_id, last_tbl_id, tbl_id = 0; + u32 next_blk_idx, blk_idx = 0, ntw = 0, ctw = 0, offset = 0; + struct debugfs_blob_wrapper *desc_blob; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_cluster_header header = {}; + struct dentry *pfile; + u8 *vblk; + int i; + + desc_blob = devm_kzalloc(dev, sizeof(*desc_blob), GFP_KERNEL); + if (!desc_blob) + return -ENOMEM; + + vfree(adapter->ixgbe_cluster_blk); + adapter->ixgbe_cluster_blk = NULL; + + vblk = vmalloc(IXGBE_FW_DUMP_BLK_MAX * IXGBE_FW_DUMP_BLK_SIZE); + if (!vblk) + return -ENOMEM; + + last_tbl_id = ixgbe_get_last_table_id(adapter); + + for (i = 0; i < IXGBE_FW_DUMP_BLK_MAX; i++) { + int res; + + /* Skip the header bytes */ + ntw += sizeof(struct ixgbe_cluster_header); + + res = ixgbe_aci_get_internal_data(&adapter->hw, cluster_id, + tbl_id, blk_idx, vblk + ntw, + IXGBE_FW_DUMP_DATA_SIZE, + &buf_len, &next_cluster_id, + &next_tbl_id, &next_blk_idx); + + if (res) { + dev_err(dev, "Internal FW error %d while dumping cluster %d\n", + res, cluster_id); + devm_kfree(dev, desc_blob); + vfree(vblk); + return -EINVAL; + } + ntw += buf_len; + + header.cluster_id = cluster_id; + header.table_id = tbl_id; + header.table_len = buf_len; + header.table_offset = offset; + + memcpy(vblk + ctw, &header, sizeof(header)); + ctw = ntw; + memset(&header, 0, sizeof(header)); + + offset += buf_len; + + if (blk_idx == next_blk_idx) + blk_idx = IXGBE_FW_DUMP_LAST_IDX; + else + blk_idx = next_blk_idx; + + if (blk_idx != IXGBE_FW_DUMP_LAST_IDX) + continue; + + blk_idx = 0; + offset = 0; + + if (next_cluster_id == IXGBE_FW_DUMP_LAST_ID2) + break; + + if (next_tbl_id != last_tbl_id) + tbl_id = next_tbl_id; + + /* End of cluster */ + if (cluster_id != next_cluster_id) { + if (read_all_clusters) { + dev_info(dev, "All FW clusters dump - cluster %d appended", + cluster_id); + cluster_id = next_cluster_id; + tbl_id = 0; + } else { + break; + } + } + } + + desc_blob->size = (unsigned long)ntw; + desc_blob->data = vblk; + + pfile = debugfs_create_blob(IXGBE_FW_DUMP_FILENAME, 0400, + adapter->ixgbe_dbg_adapter_fw_cluster, desc_blob); + if (!pfile) + return -ENODEV; + + adapter->ixgbe_cluster_blk = vblk; + + if (read_all_clusters) + dev_info(dev, "Created FW dump of all available clusters in file %s\n", + IXGBE_FW_DUMP_FILENAME); + else + dev_info(dev, "Created FW dump of cluster %d in file %s\n", + cluster_id, IXGBE_FW_DUMP_FILENAME); + + return 0; +} + +/** + * dump_cluster_id_read - show currently set FW cluster id to dump + * @file: kernel file struct + * @buf: user space buffer to fill with correct data + * @len: buf's length + * @offset: current position in buf + */ +static ssize_t dump_cluster_id_read(struct file *file, char __user *buf, + size_t len, loff_t *offset) +{ + struct ixgbe_adapter *adapter = file->private_data; + char tmp_buf[11]; + int ret; + + ret = snprintf(tmp_buf, sizeof(tmp_buf), "%u\n", + adapter->fw_dump_cluster_id); + + return simple_read_from_buffer(buf, len, offset, tmp_buf, ret); +} + +/** + * dump_cluster_id_write - set FW cluster id to dump + * @file: kernel file struct + * @buf: user space buffer containing data to read + * @len: buf's length + * @offset: current position in buf + */ +static ssize_t dump_cluster_id_write(struct file *file, const char __user *buf, + size_t len, loff_t *offset) +{ + struct ixgbe_adapter *adapter = file->private_data; + bool read_all_clusters = false; + char kbuf[11] = { 0 }; + int bytes_read, err; + u16 cluster_id; + + bytes_read = simple_write_to_buffer(kbuf, sizeof(kbuf), offset, buf, + len); + + if (bytes_read < 0) + return -EINVAL; + + if (bytes_read == 1 && kbuf[0] == '\n') { + cluster_id = 0; + read_all_clusters = true; + } else { + err = kstrtou16(kbuf, 10, &cluster_id); + if (err) + return err; + } + + debugfs_lookup_and_remove(IXGBE_FW_DUMP_FILENAME, adapter->ixgbe_dbg_adapter_fw_cluster); + err = ixgbe_debugfs_fw_dump(adapter, cluster_id, read_all_clusters); + if (err) + return err; + + /* Not all cluster IDs are supported in every FW version, save + * the value only when FW returned success + */ + adapter->fw_dump_cluster_id = cluster_id; + + return bytes_read; +} + +static const struct file_operations dump_cluster_id_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = dump_cluster_id_read, + .write = dump_cluster_id_write, +}; + +/** + * ixgbe_debugfs_enable_read - read from 'enable' file + * @file: the opened file + * @buffer: where to write the data for the user to read + * @count: the size of the user's buffer + * @ppos: file position offset + */ +static ssize_t ixgbe_debugfs_enable_read(struct file *file, + char __user *buffer, size_t count, + loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct ixgbe_hw *hw = &adapter->hw; + char buff[32] = {}; + int status; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + snprintf(buff, sizeof(buff), "%u\n", + (u16)(hw->fwlog_cfg.options & + IXGBE_FWLOG_OPTION_IS_REGISTERED) >> 3); + + status = simple_read_from_buffer(buffer, count, ppos, buff, + strlen(buff)); + + return status; +} + +/** + * ixgbe_debugfs_enable_write - write into 'enable' file + * @file: the opened file + * @buf: where to find the user's data + * @count: the length of the user's data + * @ppos: file position offset + */ +static ssize_t ixgbe_debugfs_enable_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + ssize_t ret; + char **argv; + int argc; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + + ret = ixgbe_debugfs_parse_cmd_line(buf, count, &argv, &argc); + if (ret) + goto err_copy_from_user; + + if (argc == 1) { + bool enable; + + ret = kstrtobool(argv[0], &enable); + if (ret) + goto enable_write_error; + + if (enable) + hw->fwlog_cfg.options |= IXGBE_FWLOG_OPTION_ARQ_ENA; + else + hw->fwlog_cfg.options &= ~IXGBE_FWLOG_OPTION_ARQ_ENA; + + ret = ixgbe_fwlog_set(hw, &hw->fwlog_cfg); + if (ret) + goto enable_write_error; + + if (enable) + ret = ixgbe_fwlog_register(hw); + else + ret = ixgbe_fwlog_unregister(hw); + + if (ret) + goto enable_write_error; + } else { + dev_info(dev, "unknown or invalid command '%s'\n", argv[0]); + ret = -EINVAL; + goto enable_write_error; + } + + /* if we get here, nothing went wrong; return bytes copied */ + ret = (ssize_t)count; + +enable_write_error: + argv_free(argv); +err_copy_from_user: + /* This function always consumes all of the written input, or produces + * an error. Check and enforce this. Otherwise, the write operation + * won't complete properly. + */ + if (WARN_ON(ret != (ssize_t)count && ret >= 0)) + ret = -EIO; + + return ret; +} + +static const struct file_operations ixgbe_debugfs_enable_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_debugfs_enable_read, + .write = ixgbe_debugfs_enable_write, +}; + +/** + * ixgbe_debugfs_data_read - Read data from the 'data' debugfs file + * @file: The opened file + * @buffer: Buffer where the data is written for the user to read + * @count: Size of the user's buffer + * @ppos: File position offset + * + * This function reads firmware log data from the 'data' debugfs file for + * the ixgbe network adapter. It checks if the firmware supports logging and + * if there is data available in the log ring. The function copies available + * log data to the user's buffer, handling partial reads and errors + * gracefully. It updates the file position and returns the number of bytes + * copied. + * + * Return: Number of bytes read on success, or a negative error code if + * unsupported. + */ +static ssize_t ixgbe_debugfs_data_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct ixgbe_hw *hw = &adapter->hw; + int data_copied = 0; + bool done = false; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + if (ixgbe_fwlog_ring_empty(&hw->fwlog_ring)) + return 0; + + while (!ixgbe_fwlog_ring_empty(&hw->fwlog_ring) && !done) { + struct ixgbe_fwlog_data *log; + u16 cur_buf_len; + + log = &hw->fwlog_ring.rings[hw->fwlog_ring.head]; + cur_buf_len = log->data_size; + + if (cur_buf_len >= count) { + done = true; + continue; + } + + if (copy_to_user(buffer, log->data, cur_buf_len)) { + /* if there is an error then bail and return whatever + * the driver has copied so far + */ + done = true; + continue; + } + + data_copied += cur_buf_len; + buffer += cur_buf_len; + count -= cur_buf_len; + *ppos += cur_buf_len; + ixgbe_fwlog_ring_increment(&hw->fwlog_ring.head, + hw->fwlog_ring.size); + } + + return data_copied; +} + +/** + * ixgbe_debugfs_data_write - Write data to the 'data' debugfs file + * @file: The opened file + * @buf: Buffer containing the user's data + * @count: Length of the user's data + * @ppos: File position offset + * + * This function writes user-provided data to the 'data' debugfs file for + * the ixgbe network adapter. It processes commands related to firmware log + * management, such as clearing the log if the firmware log is not running. + * The function does not allow partial writes and returns an error if the + * command is invalid or unsupported. It ensures that all input is consumed + * or an error is returned. + * + * Return: Number of bytes written on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_debugfs_data_write(struct file *file, const char __user *buf, size_t count, + loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + ssize_t ret; + char **argv; + int argc; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + + ret = ixgbe_debugfs_parse_cmd_line(buf, count, &argv, &argc); + if (ret) + goto err_copy_from_user; + + if (argc == 1) { + if (!(hw->fwlog_cfg.options & IXGBE_FWLOG_OPTION_IS_REGISTERED)) { + hw->fwlog_ring.head = 0; + hw->fwlog_ring.tail = 0; + } else { + dev_info(dev, "Can't clear FW log data while FW log running\n"); + ret = -EINVAL; + goto nr_buffs_write_error; + } + } else { + dev_info(dev, "unknown or invalid command '%s'\n", argv[0]); + ret = -EINVAL; + goto nr_buffs_write_error; + } + + /* if we get here, nothing went wrong; return bytes copied */ + ret = (ssize_t)count; + +nr_buffs_write_error: + argv_free(argv); +err_copy_from_user: + /* This function always consumes all of the written input, or produces + * an error. Check and enforce this. Otherwise, the write operation + * won't complete properly. + */ + if (WARN_ON(ret != (ssize_t)count && ret >= 0)) + ret = -EIO; + + return ret; +} + +static const struct file_operations ixgbe_debugfs_data_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_debugfs_data_read, + .write = ixgbe_debugfs_data_write, +}; + +/** + * ixgbe_debugfs_nr_buffs_read - Read from the 'nr_buffs' debugfs file + * @file: The opened file + * @buffer: Buffer where the data is written for the user to read + * @count: Size of the user's buffer + * @ppos: File position offset + * + * This function reads the number of buffers from the 'nr_buffs' debugfs + * file for the ixgbe network adapter. It checks if the firmware supports + * logging and formats the buffer size into a string for the user to read. + * The function returns an error if the firmware does not support logging. + * + * Return: Number of bytes read on success, or a negative error code if + * unsupported. + */ +static ssize_t ixgbe_debugfs_nr_buffs_read(struct file *file, + char __user *buffer, size_t count, + loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct ixgbe_hw *hw = &adapter->hw; + char buff[32] = {}; + int status; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + snprintf(buff, sizeof(buff), "%d\n", hw->fwlog_ring.size); + + status = simple_read_from_buffer(buffer, count, ppos, buff, + strlen(buff)); + + return status; +} + +/** + * ixgbe_debugfs_nr_buffs_write - Write data to the 'nr_buffs' debugfs file + * @file: The opened file + * @buf: Buffer containing the user's data + * @count: Length of the user's data + * @ppos: File position offset + * + * This function writes user-provided data to the 'nr_buffs' debugfs file for + * the ixgbe network adapter. It processes commands to set the number of + * buffers for firmware logging, ensuring the value is within bounds and a + * power of two. The function does not allow partial writes and returns an + * error if the command is invalid or if firmware logging is active. It + * ensures that all input is consumed or an error is returned. + * + * Return: Number of bytes written on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_debugfs_nr_buffs_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + ssize_t ret; + char **argv; + int argc; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + + ret = ixgbe_debugfs_parse_cmd_line(buf, count, &argv, &argc); + if (ret) + goto err_copy_from_user; + + if (argc == 1) { + s16 nr_buffs; + + ret = kstrtos16(argv[0], 0, &nr_buffs); + if (ret) + goto nr_buffs_write_error; + + if (nr_buffs <= 0 || nr_buffs > IXGBE_FWLOG_RING_SIZE_MAX) { + dev_info(dev, "nr_buffs '%d' is not within bounds. Please use a value between 1 and %d\n", + nr_buffs, IXGBE_FWLOG_RING_SIZE_MAX); + ret = -EINVAL; + goto nr_buffs_write_error; + } else if (hweight16(nr_buffs) > 1) { + dev_info(dev, "nr_buffs '%d' is not a power of 2. Please use a value that is a power of 2.\n", + nr_buffs); + ret = -EINVAL; + goto nr_buffs_write_error; + } else if (hw->fwlog_cfg.options & + IXGBE_FWLOG_OPTION_IS_REGISTERED) { + dev_info(dev, "FW logging is currently running. Please disable FW logging to change nr_buffs\n"); + ret = -EINVAL; + goto nr_buffs_write_error; + } + + /* free all the buffers and the tracking info and resize */ + ixgbe_fwlog_realloc_rings(hw, nr_buffs); + } else { + dev_info(dev, "unknown or invalid command '%s'\n", argv[0]); + ret = -EINVAL; + goto nr_buffs_write_error; + } + + /* if we get here, nothing went wrong; return bytes copied */ + ret = (ssize_t)count; + +nr_buffs_write_error: + argv_free(argv); +err_copy_from_user: + /* This function always consumes all of the written input, or produces + * an error. Check and enforce this. Otherwise, the write operation + * won't complete properly. + */ + if (WARN_ON(ret != (ssize_t)count && ret >= 0)) + ret = -EIO; + + return ret; +} + +static const struct file_operations ixgbe_debugfs_nr_buffs_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_debugfs_nr_buffs_read, + .write = ixgbe_debugfs_nr_buffs_write, +}; + +/** + * ixgbe_debugfs_module_read - Read from the 'module' debugfs file + * @file: The opened file + * @buffer: Buffer where the data is written for the user to read + * @count: Size of the user's buffer + * @ppos: File position offset + * + * This function reads firmware module configuration data from the 'module' + * debugfs file for the ixgbe network adapter. It checks if the firmware + * supports logging and allocates memory to store the configuration data. + * The function writes the data to the user's buffer and returns an error if + * the buffer is too small or if memory allocation fails. + * + * Return: Number of bytes read on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_debugfs_module_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + char *data = NULL; + int status; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + data = vzalloc(PAGE_SIZE); + if (!data) { + dev_warn(dev, "Unable to allocate memory for FW configuration!\n"); + return -ENOMEM; + } + + ixgbe_fwlog_dump_cfg(hw, data, PAGE_SIZE); + + if (count < strlen(data)) + return -ENOSPC; + + status = simple_read_from_buffer(buffer, count, ppos, data, + strlen(data)); + vfree(data); + + return status; +} + +/** + * ixgbe_debugfs_module_write - Write data to the 'module' debugfs file + * @file: The opened file + * @buf: Buffer containing the user's data + * @count: Length of the user's data + * @ppos: File position offset + * + * This function writes user-provided data to the 'module' debugfs file for + * the ixgbe network adapter. It processes commands to set the log level for + * specific firmware modules, ensuring the module and log level are valid. + * The function does not allow partial writes and returns an error if the + * command is invalid or unsupported. It ensures that all input is consumed + * or an error is returned. + * + * Return: Number of bytes written on success, or a negative error code on + * failure. + */ +static ssize_t ixgbe_debugfs_module_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + ssize_t ret; + char **argv; + int argc; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + + ret = ixgbe_debugfs_parse_cmd_line(buf, count, &argv, &argc); + if (ret) + goto err_copy_from_user; + + if (argc == 2) { + int module, log_level; + + module = sysfs_match_string(ixgbe_fwlog_module_string, argv[0]); + if (module < 0) { + dev_info(dev, "unknown module '%s'\n", argv[0]); + ret = -EINVAL; + goto module_write_error; + } + + /* TODO: remove this hack when SyncE gets turned on always */ + if (module == IXGBE_ACI_FW_LOG_ID_SYNCE) { + ret = -EINVAL; + goto module_write_error; + } + + log_level = sysfs_match_string(ixgbe_fwlog_level_string, argv[1]); + if (log_level < 0) { + dev_info(dev, "unknown log level '%s'\n", argv[1]); + ret = -EINVAL; + goto module_write_error; + } + + /* module is valid because it was range checked using + * sysfs_match_string() + */ + if (module != IXGBE_ACI_FW_LOG_ID_MAX) { + ixgbe_pf_fwlog_update_modules(adapter, log_level, 1 << module); + } else { + /* the module 'ALL' is a shortcut so that we can set + * all of the modules to the same level quickly + */ + int i; + + for (i = 0; i < IXGBE_ACI_FW_LOG_ID_MAX; i++) + ixgbe_pf_fwlog_update_modules(adapter, log_level, 1 << i); + } + } else { + dev_info(dev, "unknown or invalid command '%s'\n", argv[0]); + ret = -EINVAL; + goto module_write_error; + } + + /* if we get here, nothing went wrong; return bytes copied */ + ret = (ssize_t)count; + +module_write_error: + argv_free(argv); +err_copy_from_user: + /* This function always consumes all of the written input, or produces + * an error. Check and enforce this. Otherwise, the write operation + * won't complete properly. + */ + if (WARN_ON(ret != (ssize_t)count && ret >= 0)) + ret = -EIO; + + return ret; +} + +static const struct file_operations ixgbe_dbg_module_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_debugfs_module_read, + .write = ixgbe_debugfs_module_write, +}; + +/** + * ixgbe_debugfs_resolution_read - Read from the 'resolution' debugfs file + * @file: The opened file + * @buffer: Buffer where the data is written for the user to read + * @count: Size of the user's buffer + * @ppos: File position offset + * + * This function reads the log resolution from the 'resolution' debugfs file + * for the ixgbe network adapter. It checks if the firmware supports logging + * and formats the log resolution into a string for the user to read. The + * function returns an error if the firmware does not support logging. + * + * Return: Number of bytes read on success, or a negative error code if + * unsupported. + */ +static ssize_t ixgbe_debugfs_resolution_read(struct file *file, + char __user *buffer, size_t count, + loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct ixgbe_hw *hw = &adapter->hw; + char buff[32] = {}; + int status; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + snprintf(buff, sizeof(buff), "%d\n", + hw->fwlog_cfg.log_resolution); + + status = simple_read_from_buffer(buffer, count, ppos, buff, + strlen(buff)); + + return status; +} + +/** + * ixgbe_debugfs_resolution_write - Write data to the 'resolution' debugfs file + * @file: The opened file + * @buf: Buffer containing the user's data + * @count: Length of the user's data + * @ppos: File position offset + * + * This function writes user-provided data to the 'resolution' debugfs file + * for the ixgbe network adapter. It processes commands to set the firmware + * log resolution, ensuring the value is within valid bounds. The function + * does not allow partial writes and returns an error if the command is + * invalid or unsupported. It ensures that all input is consumed or an error + * is returned. + * + * Return: Number of bytes written on success, or a negative error code on + * failure. + */ +static ssize_t +ixgbe_debugfs_resolution_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct ixgbe_adapter *adapter = file->private_data; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + ssize_t ret; + char **argv; + int argc; + + /* don't allow commands if the FW doesn't support it */ + if (!ixgbe_fwlog_supported(hw)) + return -EOPNOTSUPP; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + + ret = ixgbe_debugfs_parse_cmd_line(buf, count, &argv, &argc); + if (ret) + goto err_copy_from_user; + + if (argc == 1) { + s16 resolution; + + ret = kstrtos16(argv[0], 0, &resolution); + if (ret) + goto resolution_write_error; + + if (resolution < IXGBE_ACI_FW_LOG_MIN_RESOLUTION || + resolution > IXGBE_ACI_FW_LOG_MAX_RESOLUTION) { + dev_err(dev, "Invalid FW log resolution %d, value must be between %d - %d\n", + resolution, IXGBE_ACI_FW_LOG_MIN_RESOLUTION, + IXGBE_ACI_FW_LOG_MAX_RESOLUTION); + ret = -EINVAL; + goto resolution_write_error; + } + + hw->fwlog_cfg.log_resolution = resolution; + } else { + dev_info(dev, "unknown or invalid command '%s'\n", argv[0]); + ret = -EINVAL; + goto resolution_write_error; + } + + /* if we get here, nothing went wrong; return bytes copied */ + ret = (ssize_t)count; + +resolution_write_error: + argv_free(argv); +err_copy_from_user: + /* This function always consumes all of the written input, or produces + * an error. Check and enforce this. Otherwise, the write operation + * won't complete properly. + */ + if (WARN_ON(ret != (ssize_t)count && ret >= 0)) + ret = -EIO; + + return ret; +} + +static const struct file_operations ixgbe_dbg_resolution_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = ixgbe_debugfs_resolution_read, + .write = ixgbe_debugfs_resolution_write, +}; + +/** + * ixgbe_dbg_adapter_init - Set up the debugfs directory for the adapter + * @adapter: The adapter that is starting up + * + * This function initializes the debugfs directory structure for the given + * ixgbe network adapter. It creates various debugfs entries for monitoring + * and controlling the adapter, including firmware logs, module settings, + * and register operations. The function handles errors in creating these + * entries and cleans up if any creation fails. + */ +void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter) +{ + const char *name = pci_name(adapter->pdev); + + adapter->ixgbe_dbg_adapter_pf = debugfs_create_dir(name, ixgbe_dbg_root); + if (!adapter->ixgbe_dbg_adapter_pf) { + e_dev_err("debugfs pf entry for %s failed\n", name); + return; + } + + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + adapter->ixgbe_dbg_adapter_fw = + debugfs_create_dir("fwlog", adapter->ixgbe_dbg_adapter_pf); + if (!adapter->ixgbe_dbg_adapter_fw) { + e_dev_err("debugfs fwlog entry for %s failed\n", name); + return; + } + + adapter->ixgbe_dbg_adapter_fw_cluster = + debugfs_create_dir("fw", adapter->ixgbe_dbg_adapter_pf); + if (!adapter->ixgbe_dbg_adapter_fw_cluster) { + e_dev_err("debugfs fw entry for %s failed\n", name); + return; + } + + if (!debugfs_create_file("dump_cluster_id", 0600, + adapter->ixgbe_dbg_adapter_fw_cluster, + adapter, + &dump_cluster_id_fops)) { + e_dev_err("debugfs dump_cluster_id for %s failed\n", name); + goto create_failed; + } + + if (!debugfs_create_file("enable", 0600, + adapter->ixgbe_dbg_adapter_fw, + adapter, + &ixgbe_debugfs_enable_fops)) { + e_dev_err("debugfs enable for %s failed\n", name); + goto create_failed; + } + + if (!debugfs_create_file("data", 0600, + adapter->ixgbe_dbg_adapter_fw, + adapter, + &ixgbe_debugfs_data_fops)) { + e_dev_err("debugfs data for %s failed\n", name); + goto create_failed; + } + + if (!debugfs_create_file("modules", 0600, + adapter->ixgbe_dbg_adapter_fw, + adapter, + &ixgbe_dbg_module_fops)) { + e_dev_err("debugfs modules for %s failed\n", name); + goto create_failed; + } + + if (!debugfs_create_file("resolution", 0600, + adapter->ixgbe_dbg_adapter_fw, + adapter, + &ixgbe_dbg_resolution_fops)) { + e_dev_err("debugfs resolution for %s failed\n", name); + goto create_failed; + } + + if (!debugfs_create_file("nr_buffs", 0600, + adapter->ixgbe_dbg_adapter_fw, + adapter, + &ixgbe_debugfs_nr_buffs_fops)) { + e_dev_err("debugfs nr_buffs for %s failed\n", name); + goto create_failed; + } + } + + if (!debugfs_create_file("reg", 0600, + adapter->ixgbe_dbg_adapter_pf, + adapter, + &ixgbe_dbg_reg_ops_fops)) { + e_dev_err("debugfs reg for %s failed\n", name); + goto create_failed; + } + + if (!debugfs_create_file("netdev", 0600, + adapter->ixgbe_dbg_adapter_pf, + adapter, + &ixgbe_dbg_netdev_ops_fops)) { + e_dev_err("debugfs netdev for %s failed\n", name); + goto create_failed; + } + + return; + +create_failed: + debugfs_remove_recursive(adapter->ixgbe_dbg_adapter_pf); + adapter->ixgbe_dbg_adapter_pf = NULL; +} + +/** + * ixgbe_dbg_adapter_exit - Clear the adapter's debugfs entries + * @adapter: Board private structure + * + * This function removes the debugfs entries associated with the given ixgbe + * network adapter. It recursively deletes the debugfs directory and frees + * any allocated memory for cluster blocks. This ensures that all debugfs + * resources are properly cleaned up when the adapter is being shut down or + * removed. + */ +void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter) +{ + if (adapter->ixgbe_dbg_adapter_pf) + debugfs_remove_recursive(adapter->ixgbe_dbg_adapter_pf); + adapter->ixgbe_dbg_adapter_pf = NULL; + + vfree(adapter->ixgbe_cluster_blk); + adapter->ixgbe_cluster_blk = NULL; +} + +/** + * ixgbe_dbg_init - Create root directory for debugfs entries + * + * This function initializes the root directory for debugfs entries related + * to the ixgbe network driver. It creates a directory named after the + * driver, which serves as the root for all subsequent debugfs entries. If + * the directory creation fails, an error message is logged. + */ +void ixgbe_dbg_init(void) +{ + ixgbe_dbg_root = debugfs_create_dir(ixgbe_driver_name, NULL); + if (ixgbe_dbg_root == NULL) + pr_err("init of debugfs failed\n"); +} + +/** + * ixgbe_dbg_exit - Clean out the driver's debugfs entries + * + * This function removes the root directory and all associated debugfs + * entries for the ixgbe network driver. It ensures that all debugfs + * resources are properly cleaned up when the driver is being unloaded or + * shut down. + */ +void ixgbe_dbg_exit(void) +{ + debugfs_remove_recursive(ixgbe_dbg_root); +} + +#endif /* HAVE_IXGBE_DEBUG_FS */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.c new file mode 100644 index 0000000000..32ec84d44a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.c @@ -0,0 +1,1534 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" +#include "ixgbe_devlink.h" +#include "ixgbe_fw_update.h" + +#if IS_ENABLED(CONFIG_NET_DEVLINK) + +#ifdef HAVE_DEVLINK_INFO_GET + +/* context for devlink info version reporting */ +struct ixgbe_info_ctx { + char buf[128]; + struct ixgbe_orom_info pending_orom; + struct ixgbe_nvm_info pending_nvm; + struct ixgbe_netlist_info pending_netlist; + struct ixgbe_hw_dev_caps dev_caps; +}; + +/* The following functions are used to format specific strings for various + * devlink info versions. The ctx parameter is used to provide the storage + * buffer, as well as any ancillary information calculated when the info + * request was made. + * + * If a version does not exist, for example when attempting to get the + * inactive version of flash when there is no pending update, the function + * should leave the buffer in the ctx structure empty. + */ + +/** + * ixgbe_info_get_dsn - get Device-Serial-Number + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format DSN string and put it into the context buffer + * in the Big Endian format. + */ +static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + u8 dsn[8]; + + /* Copy the DSN into an array in Big Endian format */ + put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn); + + snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn); +} + +/** + * ixgbe_info_pba - get Product Board Assemby + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format PBA string and put it into the context buffer + * in the Big Endian format. + */ +static void ixgbe_info_pba(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 status; + + status = ixgbe_read_pba_string(hw, (u8 *)ctx->buf, sizeof(ctx->buf)); + if (status) + /* We failed to locate the PBA, so just skip this entry */ + dev_dbg(ixgbe_pf_to_dev(adapter), + "Failed to read Product Board Assembly string, status %d\n", + status); +} + +/** + * ixgbe_info_fw_mgmt - get Firmware version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Firmware major, minor and patch versions string + * and put it into the context buffer. + */ +static void ixgbe_info_fw_mgmt(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_hw *hw = &adapter->hw; + + snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", + hw->fw_maj_ver, hw->fw_min_ver, hw->fw_patch); +} + +/** + * ixgbe_info_fw_api - get Firmware API version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Firmware API major, minor and patch versions string + * and put it into the context buffer. + */ +static void ixgbe_info_fw_api(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_hw *hw = &adapter->hw; + + snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", + hw->api_maj_ver, hw->api_min_ver, hw->api_patch); +} + +/** + * ixgbe_info_fw_build - get Firmware build + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Firmware build string and put it into + * the context buffer. + */ +static void ixgbe_info_fw_build(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_hw *hw = &adapter->hw; + + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build); +} + +/** + * ixgbe_info_fw_srev - get Firmware Serial Revision + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Firmware serial revision string and put it + * into the context buffer. + */ +static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; + + snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev); +} + +/** + * ixgbe_info_pending_fw_srev - get pending Firmware Serial Revision + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Firmware serial revision string and + * put it into the context buffer if there is a pending update. + */ +static void ixgbe_info_pending_fw_srev(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_nvm_info *nvm = &ctx->pending_nvm; + + if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) + snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev); +} + +/** + * ixgbe_info_orom_ver - get OROM version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format OROM major version, build and patch string and + * put it into the context buffer. + */ +static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; + + snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", + orom->major, orom->build, orom->patch); +} + +/** + * ixgbe_info_pending_orom_ver - get pending OROM version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format OROM major version, build and patch string and + * put it into the context buffer if there is a pending update. + */ +static void ixgbe_info_pending_orom_ver(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_orom_info *orom = &ctx->pending_orom; + + if (ctx->dev_caps.common_cap.nvm_update_pending_orom) + snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", + orom->major, orom->build, orom->patch); +} + +/** + * ixgbe_info_orom_srev - get OROM Serial Revision + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format OROM string and put it into the context buffer. + */ +static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; + + snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev); +} + +/** + * ixgbe_info_pending_orom_srev - get pending OROM Serial Revision + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format OROM serial revision string and put + * it into the context buffer if there is a pending update. + */ +static void ixgbe_info_pending_orom_srev(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_orom_info *orom = &ctx->pending_orom; + + if (ctx->dev_caps.common_cap.nvm_update_pending_orom) + snprintf(ctx->buf, sizeof(ctx->buf), "%u", orom->srev); +} + +/** + * ixgbe_info_nvm_ver - get NVM version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format NVM major and minor versions string and put + * it into the context buffer. + */ +static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; + + snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor); +} + +/** + * ixgbe_info_pending_nvm_ver - get pending NVM version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format NVM major and minor versions string and put + * it into the context buffer if there is a pending update. + */ +static void ixgbe_info_pending_nvm_ver(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_nvm_info *nvm = &ctx->pending_nvm; + + if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) + snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", + nvm->major, nvm->minor); +} + +/** + * ixgbe_info_eetrack - get NVM EEtrack ID + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format NVM EEtrack ID string and put + * it into the context buffer. + */ +static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; + + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack); +} + +/** + * ixgbe_info_pending_eetrack - get pending NVM EEtrack ID + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format NVM EEtrack ID and put it into + * the context buffer if there is a pending update. + */ +static void ixgbe_info_pending_eetrack(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_nvm_info *nvm = &ctx->pending_nvm; + + if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack); +} + +/** + * ixgbe_info_netlist_ver - get Netlist version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Netlist major version, minor version, + * type, revision and customer version string and put it + * into the context buffer. + */ +static void ixgbe_info_netlist_ver(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; + + /* The netlist version fields are BCD formatted */ + snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", + netlist->major, netlist->minor, + netlist->type >> 16, netlist->type & 0xFFFF, + netlist->rev, netlist->cust_ver); +} + +/** + * ixgbe_info_netlist_build - get Netlist build + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Netlist hash (build) and puts it into the context buffer. + */ +static void ixgbe_info_netlist_build(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; + + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); +} + +/** + * ixgbe_info_pending_netlist_ver - get pending Netlist version + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Netlist major version, minor version, + * type, revision and customer version string and put it + * into the context buffer if there is a pending update. + */ +static void ixgbe_info_pending_netlist_ver(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_netlist_info *netlist = &adapter->hw.flash.netlist; + + /* The netlist version fields are BCD formatted */ + if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) + snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", + netlist->major, netlist->minor, + netlist->type >> 16, netlist->type & 0xFFFF, + netlist->rev, netlist->cust_ver); +} + +/** + * ixgbe_info_pending_netlist_build - get Netlist build + * @adapter: adapter instance + * @ctx: context providing buffer and additional information for the request + * + * Format Netlist hash (build) and put it into the context buffer + * if there is a pending update. + */ +static void ixgbe_info_pending_netlist_build(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx) +{ + struct ixgbe_netlist_info *netlist = &ctx->pending_netlist; + + if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) + snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash); +} + +#define fixed(key, getter) { IXGBE_VERSION_FIXED, key, getter, NULL } +#define running(key, getter) { IXGBE_VERSION_RUNNING, key, getter, NULL } +#define stored(key, getter, fallback) \ + { IXGBE_VERSION_STORED, key, getter, fallback } + +enum ixgbe_version_type { + IXGBE_VERSION_FIXED, + IXGBE_VERSION_RUNNING, + IXGBE_VERSION_STORED, +}; + +static const struct ixgbe_devlink_version { + enum ixgbe_version_type type; + const char *key; + void (*getter)(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx); + void (*fallback)(struct ixgbe_adapter *adapter, + struct ixgbe_info_ctx *ctx); +} ixgbe_devlink_versions[] = { + fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, + ixgbe_info_pba), + running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, + ixgbe_info_fw_mgmt), + running("fw.mgmt.api", + ixgbe_info_fw_api), + running("fw.mgmt.build", + ixgbe_info_fw_build), + + running("fw.mgmt.srev", ixgbe_info_fw_srev), + stored("fw.mgmt.srev", + ixgbe_info_pending_fw_srev, ixgbe_info_fw_srev), + running(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ixgbe_info_orom_ver), + stored(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, + ixgbe_info_pending_orom_ver, ixgbe_info_orom_ver), + running("fw.undi.srev", ixgbe_info_orom_srev), + stored("fw.undi.srev", + ixgbe_info_pending_orom_srev, ixgbe_info_orom_srev), + running("fw.psid.api", ixgbe_info_nvm_ver), + stored("fw.psid.api", + ixgbe_info_pending_nvm_ver, ixgbe_info_nvm_ver), + running(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ixgbe_info_eetrack), + stored(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, + ixgbe_info_pending_eetrack, ixgbe_info_eetrack), + running("fw.netlist", ixgbe_info_netlist_ver), + stored("fw.netlist", + ixgbe_info_pending_netlist_ver, ixgbe_info_netlist_ver), + running("fw.netlist.build", ixgbe_info_netlist_build), + stored("fw.netlist.build", + ixgbe_info_pending_netlist_build, ixgbe_info_netlist_build), +}; + +/** + * ixgbe_devlink_info_get - Devlink handler for retrieving device info + * @devlink: Devlink instance structure + * @req: The devlink info request + * @extack: Extended netdev ack structure + * + * This function serves as a callback for the devlink .info_get operation, + * providing detailed information about the ixgbe network adapter. It + * discovers device capabilities, retrieves version information, and reports + * it through the devlink interface. The function handles errors in + * retrieving data and sets appropriate error messages in the extack + * structure. + * + * Return: 0 on success, or an error code on failure. + */ +static int ixgbe_devlink_info_get(struct devlink *devlink, + struct devlink_info_req *req, + struct netlink_ext_ack *extack) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_info_ctx *ctx; + struct ixgbe_hw *hw; + struct device *dev; + s32 status; + size_t i; + int err; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + hw = &adapter->hw; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + /* discover capabilities first */ + status = ixgbe_discover_dev_caps(hw, &ctx->dev_caps); + if (status) { + dev_dbg(dev, + "Failed to discover device capabilities, status %d aq_err %d\n", + status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Unable to discover device capabilities"); + err = -EIO; + goto out_free_ctx; + } + if (ctx->dev_caps.common_cap.nvm_update_pending_orom) { + status = ixgbe_get_inactive_orom_ver(hw, &ctx->pending_orom); + if (status) { + dev_dbg(dev, + "Unable to read inactive Option ROM version data, status %d aq_err %d\n", + status, hw->aci.last_status); + + /* disable display of pending Option ROM */ + ctx->dev_caps.common_cap.nvm_update_pending_orom = + false; + } + } + + if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) { + status = ixgbe_get_inactive_nvm_ver(hw, &ctx->pending_nvm); + if (status) { + dev_dbg(dev, + "Unable to read inactive NVM version data, status %d aq_err %d\n", + status, hw->aci.last_status); + + /* disable display of pending Option ROM */ + ctx->dev_caps.common_cap.nvm_update_pending_nvm = false; + } + } + + if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) { + status = ixgbe_get_inactive_netlist_ver(hw, + &ctx->pending_netlist); + if (status) { + dev_dbg(dev, + "Unable to read inactive Netlist version data, status %d aq_err %d\n", + status, hw->aci.last_status); + + /* disable display of pending Option ROM */ + ctx->dev_caps.common_cap.nvm_update_pending_netlist = + false; + } + } + +#ifdef HAVE_DEVLINK_INFO_DRIVER_NAME_PUT + err = devlink_info_driver_name_put(req, KBUILD_MODNAME); + if (err) { + NL_SET_ERR_MSG_MOD(extack, "Unable to set driver name"); + goto out_free_ctx; + } +#endif /* HAVE_DEVLINK_INFO_DRIVER_NAME_PUT */ + + ixgbe_info_get_dsn(adapter, ctx); + + err = devlink_info_serial_number_put(req, ctx->buf); + if (err) { + NL_SET_ERR_MSG_MOD(extack, "Unable to set serial number"); + goto out_free_ctx; + } + + for (i = 0; i < ARRAY_SIZE(ixgbe_devlink_versions); i++) { + enum ixgbe_version_type type = ixgbe_devlink_versions[i].type; + const char *key = ixgbe_devlink_versions[i].key; + + memset(ctx->buf, 0, sizeof(ctx->buf)); + + ixgbe_devlink_versions[i].getter(adapter, ctx); + + /* If the default getter doesn't report a version, use the + * fallback function. This is primarily useful in the case of + * "stored" versions that want to report the same value as the + * running version in the normal case of no pending update. + */ + if (ctx->buf[0] == '\0' && ixgbe_devlink_versions[i].fallback) + ixgbe_devlink_versions[i].fallback(adapter, ctx); + + /* Do not report missing versions */ + if (ctx->buf[0] == '\0') + continue; + + switch (type) { + case IXGBE_VERSION_FIXED: + err = devlink_info_version_fixed_put(req, key, + ctx->buf); + if (err) { + NL_SET_ERR_MSG_MOD(extack, + "Unable to set fixed version"); + goto out_free_ctx; + } + break; + case IXGBE_VERSION_RUNNING: + err = devlink_info_version_running_put(req, key, + ctx->buf); + if (err) { + NL_SET_ERR_MSG_MOD(extack, + "Unable to set running version"); + goto out_free_ctx; + } + break; + case IXGBE_VERSION_STORED: + err = devlink_info_version_stored_put(req, key, + ctx->buf); + if (err) { + NL_SET_ERR_MSG_MOD(extack, + "Unable to set stored version"); + goto out_free_ctx; + } + break; + } + } +out_free_ctx: + kfree(ctx); + return err; +} +#endif /* HAVE_DEVLINK_INFO_GET */ + +#ifdef HAVE_DEVLINK_PARAMS +enum ixgbe_devlink_param_id { + IXGBE_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, + IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV, + IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV, +}; + +/** + * ixgbe_devlink_minsrev_get - Get the current minimum security revision + * @devlink: pointer to the devlink instance + * @id: the parameter ID to get + * @ctx: context to return the parameter value + * + * Returns: zero on success, or an error code on failure. + */ +static int ixgbe_devlink_minsrev_get(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx) +{ + struct ixgbe_minsrev_info minsrevs = {}; + struct ixgbe_adapter *adapter; + struct device *dev; + s32 status; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + + if (id != IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV && + id != IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV) + return -EINVAL; + + status = ixgbe_get_nvm_minsrevs(&adapter->hw, &minsrevs); + + if (status == IXGBE_ERR_ACI_ERROR) { + ixgbe_release_nvm(&adapter->hw); + status = ixgbe_get_nvm_minsrevs(&adapter->hw, &minsrevs); + } + + if (status) { + dev_warn(dev, + "Failed to read minimum security revision data from flash\n"); + return -EIO; + } + + /* We report zero if the device has not yet had a valid minimum + * security revision programmed for the associated module. This makes + * sense because it is not possible to have a security revision of + * less than zero. Thus, all images will be able to load if the + * minimum security revision is zero, the same as the case where the + * minimum value is indicated as invalid. + */ + + switch (id) { + case IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV: + if (minsrevs.nvm_valid) + ctx->val.vu32 = minsrevs.nvm; + else + ctx->val.vu32 = 0; + break; + case IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV: + if (minsrevs.orom_valid) + ctx->val.vu32 = minsrevs.orom; + else + ctx->val.vu32 = 0; + break; + } + + return 0; +} + +#ifdef HAVE_DEVLINK_PARAMS_SET_EXTACK +/** + * ixgbe_devlink_minsrev_set - Set the minimum security revision + * @devlink: pointer to the devlink instance + * @id: the parameter ID to set + * @ctx: context to return the parameter value + * @extack: netlink extended ACK structure + * + * Set the minimum security revision value for fw.mgmt or fw.undi. The kernel + * calls the validate handler before calling this, so we do not need to + * duplicate those checks here. + * + * Returns: zero on success, or an error code on failure. + */ +static int ixgbe_devlink_minsrev_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +#else +static int ixgbe_devlink_minsrev_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx) +#endif +{ + struct ixgbe_minsrev_info minsrevs = {}; + struct ixgbe_adapter *adapter; + struct device *dev; + s32 status; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + + switch (id) { + case IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV: + minsrevs.nvm_valid = true; + minsrevs.nvm = ctx->val.vu32; + break; + case IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV: + minsrevs.orom_valid = true; + minsrevs.orom = ctx->val.vu32; + break; + default: + return -EINVAL; + } + + status = ixgbe_update_nvm_minsrevs(&adapter->hw, &minsrevs); + if (status) { + dev_warn(dev, + "Failed to update minimum security revision data\n"); + return -EIO; + } + + return 0; +} + +/** + * ixgbe_devlink_minsrev_validate - Validate a minimum security revision update + * @devlink: unused pointer to devlink instance + * @id: the parameter ID to validate + * @val: value to validate + * @extack: netlink extended ACK structure + * + * Check that a proposed update to a minimum security revision field is valid. + * Each minimum security revision can only be increased, not decreased. + * Additionally, we verify that the value is never set higher than the + * security revision of the active flash component. + * + * Returns: zero if the value is valid, -ERANGE if it is out of range, and + * -EINVAL if this function is called with the wrong ID. + */ +static int ixgbe_devlink_minsrev_validate(struct devlink *devlink, u32 id, + union devlink_param_value val, + struct netlink_ext_ack *extack) +{ + struct ixgbe_minsrev_info minsrevs = {}; + struct ixgbe_adapter *adapter; + struct device *dev; + s32 status; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + + if (id != IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV && + id != IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV) + return -EINVAL; + + status = ixgbe_get_nvm_minsrevs(&adapter->hw, &minsrevs); + + if (status == IXGBE_ERR_ACI_ERROR) { + ixgbe_release_nvm(&adapter->hw); + status = ixgbe_get_nvm_minsrevs(&adapter->hw, &minsrevs); + } + if (status) { + NL_SET_ERR_MSG_MOD(extack, + "Failed to read minimum security revision data from flash"); + return -EIO; + } + + switch (id) { + case IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV: + if (val.vu32 > adapter->hw.flash.nvm.srev) { + NL_SET_ERR_MSG_MOD(extack, + "Cannot update fw.mgmt minimum security revision higher than the currently running firmware"); + dev_dbg(dev, + "Attempted to set fw.mgmt.minsrev to %u, but running firmware has srev %u\n", + val.vu32, adapter->hw.flash.nvm.srev); + return -EPERM; + } + + if (minsrevs.nvm_valid && val.vu32 < minsrevs.nvm) { + NL_SET_ERR_MSG_MOD(extack, + "Cannot lower the minimum security revision for fw.mgmt flash section"); + dev_dbg(dev, + "Attempted to set fw.mgmt.minsrev to %u, but current minsrev is %u\n", + val.vu32, minsrevs.nvm); + return -EPERM; + } + break; + case IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV: + if (val.vu32 > adapter->hw.flash.orom.srev) { + NL_SET_ERR_MSG_MOD(extack, + "Cannot update fw.undi minimum security revision higher than the currently running firmware"); + dev_dbg(dev, + "Attempted to set fw.undi.minsrev to %u, but running firmware has srev %u\n", + val.vu32, adapter->hw.flash.orom.srev); + return -EPERM; + } + + if (minsrevs.orom_valid && val.vu32 < minsrevs.orom) { + NL_SET_ERR_MSG_MOD(extack, + "Cannot lower the minimum security revision for fw.undi flash section"); + dev_dbg(dev, + "Attempted to set fw.undi.minsrev to %u, but current minsrev is %u\n", + val.vu32, minsrevs.orom); + return -EPERM; + } + break; + } + + return 0; +} + +/* devlink parameters for the driver */ +static const struct devlink_param ixgbe_devlink_params[] = { + DEVLINK_PARAM_DRIVER(IXGBE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV, + "fw.mgmt.minsrev", + DEVLINK_PARAM_TYPE_U32, + BIT(DEVLINK_PARAM_CMODE_PERMANENT), + ixgbe_devlink_minsrev_get, + ixgbe_devlink_minsrev_set, + ixgbe_devlink_minsrev_validate), + DEVLINK_PARAM_DRIVER(IXGBE_DEVLINK_PARAM_ID_FW_UNDI_MINSREV, + "fw.undi.minsrev", + DEVLINK_PARAM_TYPE_U32, + BIT(DEVLINK_PARAM_CMODE_PERMANENT), + ixgbe_devlink_minsrev_get, + ixgbe_devlink_minsrev_set, + ixgbe_devlink_minsrev_validate), +}; +#endif /* HAVE_DEVLINK_PARAMS */ + +#ifdef HAVE_DEVLINK_FLASH_UPDATE +#ifdef HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY +/** + * ixgbe_devlink_flash_update_notify - Compatibility for begin/end notify + * @devlink: pointer to the devlink instance for this device + * @params: flash update parameters + * @extack: netlink extended ACK message structure + * + * Compatibility wrapper which handles calling + * devlink_flash_update_begin_notify and devlink_flash_update_end_notify when + * the kernel does not do this for us. + * + * Return: 0 on success or negative error code on failure. + */ +static int ixgbe_devlink_flash_update_notify(struct devlink *devlink, + struct devlink_flash_update_params + *params, + struct netlink_ext_ack *extack) +{ + int err; + + devlink_flash_update_begin_notify(devlink); + err = ixgbe_flash_pldm_image(devlink, params, extack); + devlink_flash_update_end_notify(devlink); + + return err; +} +#endif /* HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY */ + +#ifndef HAVE_DEVLINK_FLASH_UPDATE_PARAMS +/** + * ixgbe_devlink_flash_update_params - Compatibility for params argument + * @devlink: pointer to the devlink instance for this device + * @file_name: the file name to request the firmware from + * @component: the flash component to update + * @extack: netlink extended ACK message structure + * + * Compatibility wrapper which handles creating the flash update parameters + * structure for kernels which do not have this structure defined yet. + * + * Return: 0 on success or negative error code on failure. + */ +static int ixgbe_devlink_flash_update_params(struct devlink *devlink, + const char *file_name, + const char *component, + struct netlink_ext_ack *extack) +{ + struct devlink_flash_update_params params = {}; + struct ixgbe_adapter *adapter; + struct device *dev; + int ret; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + + /* individual component update is not yet supported, and older kernels + * did not check this for us. + */ + if (component) + return -EOPNOTSUPP; + + params.file_name = file_name; + +#ifdef HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY + ret = ixgbe_devlink_flash_update_notify(devlink, ¶ms, extack); + + if (ret) + dev_dbg(dev, + "ixgbe_devlink_flash_update_notify() returned %d\n", + ret); +#else + ret = ixgbe_flash_pldm_image(devlink, ¶ms, extack); + + if (ret) + dev_dbg(dev, "ixgbe_flash_pldm_image() returned %d\n", ret); +#endif + return ret; +} +#endif /* !HAVE_DEVLINK_FLASH_UPDATE_PARAMS */ +#endif /* HAVE_DEVLINK_FLASH_UPDATE */ + +#ifdef HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT +/** + * ixgbe_devlink_reload_empr_start - Start EMP reset to activate new firmware + * @devlink: pointer to the devlink instance to reload + * @netns_change: if true, the network namespace is changing + * @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE + * @limit: limits on what reload should do, such as not resetting + * @extack: netlink extended ACK structure + * + * Allow user to activate new Embedded Management Processor firmware by + * issuing device specific EMP reset. Called in response to + * a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE. + * + * Note that teardown and rebuild of the driver state happens automatically as + * part of an interrupt and watchdog task. This is because all physical + * functions on the device must be able to reset when an EMP reset occurs from + * any source. + * + * Return: the exit code of the operation. + */ +static int ixgbe_devlink_reload_empr_start(struct devlink *devlink, + bool netns_change, + enum devlink_reload_action action, + enum devlink_reload_limit limit, + struct netlink_ext_ack *extack) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct device *dev; + s32 status; + u8 pending; + int err; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + hw = &adapter->hw; + + err = ixgbe_get_pending_updates(adapter, &pending, extack); + if (err) + return err; + + /* pending is a bitmask of which flash banks have a pending update, + * including the main NVM bank, the Option ROM bank, and the netlist + * bank. If any of these bits are set, then there is a pending update + * waiting to be activated. + */ + if (!pending) { + NL_SET_ERR_MSG_MOD(extack, "No pending firmware update"); + return -ECANCELED; + } + + if (adapter->fw_emp_reset_disabled) { + NL_SET_ERR_MSG_MOD(extack, + "EMP reset is not available. To activate firmware, a reboot or power cycle is needed\n"); + return -ECANCELED; + } + + dev_dbg(dev, "Issuing device EMP reset to activate firmware\n"); + + status = ixgbe_aci_nvm_update_empr(hw); + if (status) { + dev_err(dev, + "Failed to trigger EMP device reset to reload firmware, err %d\n", + status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to trigger EMP device reset to reload firmware"); + return -EIO; + } + + return 0; +} + +/* Wait for 10 sec with 0.5 sec tic. EMPR takes no less than half of a sec */ +#define IXGBE_DEVLINK_RELOAD_TICK_L 400000 +#define IXGBE_DEVLINK_RELOAD_TICK_H 500000 +#define IXGBE_DEVLINK_RELOAD_TIMEOUT 20 + +/** + * ixgbe_devlink_reload_empr_finish - Complete EMP reset process + * @devlink: Pointer to the devlink instance + * @action: The action to perform + * @limit: Limits on what reload should do + * @actions_performed: Actions performed + * @extack: Netlink extended ACK structure + * + * This function completes the EMP reset process for the ixgbe network + * adapter. It updates the actions performed to indicate firmware activation + * and waits for the device and driver to finish the reset and rebuild + * process. The function currently includes a temporary 10-second wait to + * ensure completion. + * + * Return: Always returns 0, what means success. + */ +static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink, + enum devlink_reload_action action, + enum devlink_reload_limit limit, + u32 *actions_performed, + struct netlink_ext_ack *extack) +{ + struct ixgbe_adapter *adapter = + *(struct ixgbe_adapter **)devlink_priv(devlink); + struct ixgbe_hw *hw = &adapter->hw; + int i = 0; + u32 fwsm; + + do { + if (i++ >= IXGBE_DEVLINK_RELOAD_TIMEOUT) + return -ETIME; + + /* Just right away after triggering EMP reset the FWSM register + * may be not cleared yet, so begin the loop with the delay + * in order to not check the not updated register. + */ + usleep_range(IXGBE_DEVLINK_RELOAD_TICK_L, + IXGBE_DEVLINK_RELOAD_TICK_H); + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); + + } while (!(fwsm & IXGBE_FWSM_FW_VAL_BIT)); + + *actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE); + + return ixgbe_refresh_fw_version(adapter); +} +#endif /* HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT */ + + +static const struct devlink_ops ixgbe_devlink_ops = { +#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS + .supported_flash_update_params = + DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, +#endif /* HAVE_DEVLINK_FLASH_UPDATE_PARAMS */ +#ifdef HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT + .reload_actions = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), + /* The ixgbe driver currently does not support driver reinit */ + .reload_down = ixgbe_devlink_reload_empr_start, + .reload_up = ixgbe_devlink_reload_empr_finish, +#endif +#ifdef HAVE_DEVLINK_INFO_GET + .info_get = ixgbe_devlink_info_get, +#endif /* HAVE_DEVLINK_INFO_GET */ + +#ifdef HAVE_DEVLINK_FLASH_UPDATE +#if !defined(HAVE_DEVLINK_FLASH_UPDATE_PARAMS) + .flash_update = ixgbe_devlink_flash_update_params, +#elif defined(HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY) + .flash_update = ixgbe_devlink_flash_update_notify, +#else + .flash_update = ixgbe_flash_pldm_image, +#endif +#endif /* HAVE_DEVLINK_FLASH_UPDATE */ +}; + +/** + * ixgbe_allocate_devlink - Allocate devlink and return adapter pointer + * @adapter: pointer to the device adapter structure + * + * Allocate a devlink instance for this device and return the private area as + * the pointer to the adapter structure. + * + * Return: the pointer to adapter structure is returned + */ +struct ixgbe_adapter **ixgbe_allocate_devlink(struct ixgbe_adapter *adapter) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_adapter **padapter; + struct devlink *devlink; + + devlink = devlink_alloc(&ixgbe_devlink_ops, + sizeof(struct ixgbe_adapter *), dev); + if (!devlink) + return NULL; +#ifdef HAVE_DEVLINK_REGISTER_SETS_DEV + /* On older kernels, eg. 4.12, + * devlink->dev is not set during devlink_alloc. + * Assign it here just to be sure. + */ + devlink->dev = dev; +#endif /* HAVE_DEVLINK_REGISTER_SETS_DEV */ + + padapter = (struct ixgbe_adapter **)devlink_priv(devlink); + /* The adapter pointer is assigned to the indicated place in devlink */ + *padapter = adapter; + /* Add pointer to devlink to the adapter structure */ + adapter->devlink = devlink; + + return padapter; +} + +/** + * ixgbe_devlink_register - Register devlink interface for this adapter + * @adapter: pointer to the device adapter structure + * + * Register the devlink instance associated with this physical function. + */ +void ixgbe_devlink_register(struct ixgbe_adapter *adapter) +{ + struct devlink *devlink = adapter->devlink; + +#ifdef HAVE_DEVLINK_SET_FEATURES + devlink_set_features(devlink, DEVLINK_F_RELOAD); +#endif /* HAVE_DEVLINK_SET_FEATURES */ +#ifdef HAVE_DEVLINK_REGISTER_SETS_DEV + devlink_register(devlink, ixgbe_pf_to_dev(adapter)); +#else + devlink_register(devlink); +#endif + +#ifdef HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT +#ifndef HAVE_DEVLINK_SET_FEATURES +#ifdef HAVE_DEVLINK_RELOAD_ENABLE_DISABLE + devlink_reload_enable(devlink); +#endif /* HAVE_DEVLINK_RELOAD_ENABLE_DISABLE */ +#endif /* !HAVE_DEVLINK_SET_FEATURES */ +#endif /* HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT */ +} + +/** + * ixgbe_devlink_unregister - Unregister devlink resources for this adapter. + * @adapter: pointer to the device adapter structure + * + * Releases resources used by devlink and cleans up associated memory. + */ +void ixgbe_devlink_unregister(struct ixgbe_adapter *adapter) +{ + struct devlink *devlink = adapter->devlink; + +#ifdef HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT +#ifndef HAVE_DEVLINK_SET_FEATURES +#ifdef HAVE_DEVLINK_RELOAD_ENABLE_DISABLE + devlink_reload_disable(devlink); +#endif /* HAVE_DEVLINK_RELOAD_ENABLE_DISABLE */ +#endif /* !HAVE_DEVLINK_SET_FEATURES */ +#endif /* HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT */ + + devlink_unregister(devlink); +} + +/** + * ixgbe_devlink_register_params - Register devlink parameters + * @adapter: pointer to the device adapter structure + * + * Registers the parameters associated with this adapter. + * + * Return: the exit code of the operation. + */ +int ixgbe_devlink_register_params(struct ixgbe_adapter *adapter) +{ +#ifdef HAVE_DEVLINK_PARAMS + struct device *dev = ixgbe_pf_to_dev(adapter); + struct devlink *devlink = adapter->devlink; + int err; + + err = devlink_params_register(devlink, ixgbe_devlink_params, + ARRAY_SIZE(ixgbe_devlink_params)); + if (err) { + dev_err(dev, + "devlink params registration failed, err %d\n", + err); + return err; + } + +#ifdef HAVE_DEVLINK_PARAMS_PUBLISH + devlink_params_publish(devlink); +#endif /* HAVE_DEVLINK_PARAMS_PUBLISH */ + +#endif /* HAVE_DEVLINK_PARAMS */ + return 0; +} + +/** + * ixgbe_devlink_unregister_params - Unregister devlink parameters + * @adapter: pointer to the device adapter structure + * + * Removes the main devlink parameters associated with this adapter. + */ +void ixgbe_devlink_unregister_params(struct ixgbe_adapter *adapter) +{ +#ifdef HAVE_DEVLINK_PARAMS + struct devlink *devlink = adapter->devlink; + +#ifdef HAVE_DEVLINK_PARAMS_PUBLISH + devlink_params_unpublish(devlink); +#endif /* HAVE_DEVLINK_PARAMS_PUBLISH */ + + devlink_params_unregister(devlink, ixgbe_devlink_params, + ARRAY_SIZE(ixgbe_devlink_params)); +#endif /* HAVE_DEVLINK_PARAMS */ +} + +/** + * ixgbe_devlink_register_port - Register a devlink port for the adapter + * @adapter: pointer to the device adapter structure + * + * Create and register a devlink_port for this adapter. + * + * Return: zero on success or an error code on failure. + */ +int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter) +{ + struct devlink_port *devlink_port = &adapter->devlink_port; + struct device *dev = ixgbe_pf_to_dev(adapter); + struct devlink *devlink = adapter->devlink; + struct devlink_port_attrs attrs = {}; + int err; + + attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; + attrs.phys.port_number = adapter->hw.bus.func; + + devlink_port_attrs_set(devlink_port, &attrs); + + err = devlink_port_register(devlink, devlink_port, 0); + if (err) { + dev_err(dev, + "devlink port registration failed, err %d\n", + err); + } + + return err; +} + +/** + * ixgbe_devlink_unregister_port - Unregister the devlink port + * @adapter: pointer to the device adapter structure + * + * Unregisters the devlink_port structure associated with this adapter. + */ +void ixgbe_devlink_unregister_port(struct ixgbe_adapter *adapter) +{ + struct devlink_port *devlink_port = &adapter->devlink_port; + + devlink_port_unregister(devlink_port); +} + +#ifdef HAVE_DEVLINK_REGIONS +#define IXGBE_ACI_MAX_BUF_LEN 4096 + +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT +#define IXGBE_DEVLINK_READ_BLK_SIZE (1024 * 1024) + +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS + +/** + * ixgbe_devlink_nvm_snapshot - Capture a snapshot of the NVM flash contents + * @devlink: the devlink instance + * @ops: the devlink region being snapshotted + * @extack: extended ACK response structure + * @data: on exit points to snapshot data buffer + * + * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for + * the nvm-flash devlink region. It captures a snapshot of the full NVM flash + * contents, including both banks of flash. This snapshot can later be viewed + * via the devlink-region interface. + * + * It captures the flash using the FLASH_ONLY bit set when reading via + * firmware, so it does not read the current Shadow RAM contents. For that, + * use the shadow-ram region. + * + * @returns zero on success, and updates the data pointer. Returns a non-zero + * error code on failure. + */ +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS */ +static int ixgbe_devlink_nvm_snapshot(struct devlink *devlink, +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS + const struct devlink_region_ops + __always_unused *ops, +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS */ + struct netlink_ext_ack *extack, u8 **data) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct device *dev; + u8 *nvm_data, *tmp; + u32 nvm_size, left; + s8 num_blks, i; + s32 status; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + hw = &adapter->hw; + + nvm_size = hw->flash.flash_size; + nvm_data = vzalloc(nvm_size); + if (!nvm_data) + return -ENOMEM; + + num_blks = DIV_ROUND_UP(nvm_size, IXGBE_DEVLINK_READ_BLK_SIZE); + tmp = nvm_data; + left = nvm_size; + + /* some systems take longer to read the nvm than others which causes the + * fw to reclaim the nvm lock before the entire nvm has been read. fix + * this by breaking the reads of the nvm into smaller chunks that will + * probably not take as long. this has some overhead since we are + * increasing the number of AQ commands, but it should always work + */ + for (i = 0; i < num_blks; i++) { + u32 read_sz = min_t(u32, IXGBE_DEVLINK_READ_BLK_SIZE, left); + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) { + dev_dbg(dev, + "ixgbe_acquire_nvm failed, err %d aq_err %d\n", + status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to acquire NVM semaphore"); + vfree(nvm_data); + return -EIO; + } + + status = ixgbe_read_flat_nvm(hw, + i * IXGBE_DEVLINK_READ_BLK_SIZE, + &read_sz, tmp, false); + if (status) { + dev_dbg(dev, + "ixgbe_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n", + read_sz, status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to read RAM contents"); + ixgbe_release_nvm(hw); + vfree(nvm_data); + return -EIO; + } + + ixgbe_release_nvm(hw); + + tmp += read_sz; + left -= read_sz; + } + + *data = nvm_data; + + return 0; +} + +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS +/** + * ixgbe_devlink_sram_snapshot - Capture a snapshot of the Shadow RAM contents + * @devlink: the devlink instance + * @ops: the devlink region being snapshotted + * @extack: extended ACK response structure + * @data: on exit points to snapshot data buffer + * + * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for + * the shadow-ram devlink region. It captures a snapshot of the shadow ram + * contents. This snapshot can later be viewed via the devlink-region + * interface. + * + * @returns zero on success, and updates the data pointer. Returns a non-zero + * error code on failure. + */ +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS */ +static int ixgbe_devlink_sram_snapshot(struct devlink *devlink, +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS + const struct devlink_region_ops + __always_unused *ops, +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS */ + struct netlink_ext_ack *extack, + u8 **data) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct device *dev; + u32 sram_size; + u8 *sram_data; + int status; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + hw = &adapter->hw; + + sram_size = hw->flash.sr_words * 2u; + sram_data = vzalloc(sram_size); + if (!sram_data) + return -ENOMEM; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) { + dev_dbg(dev, + "ixgbe_acquire_nvm failed, err %d aq_err %d\n", + status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore"); + vfree(sram_data); + return (int)status; + } + + /* Read from the Shadow RAM, rather than directly from NVM */ + status = ixgbe_read_flat_nvm(hw, 0, &sram_size, sram_data, true); + if (status) { + dev_dbg(dev, + "ixgbe_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n", + sram_size, status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to read Shadow RAM contents"); + ixgbe_release_nvm(hw); + vfree(sram_data); + return (int)status; + } + + ixgbe_release_nvm(hw); + + *data = sram_data; + + return 0; +} + +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS +/** + * ixgbe_devlink_devcaps_snapshot - Capture snapshot of device capabilities + * @devlink: the devlink instance + * @ops: the devlink region being snapshotted + * @extack: extended ACK response structure + * @data: on exit points to snapshot data buffer + * + * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for + * the device-caps devlink region. It captures a snapshot of the device + * capabilities reported by firmware. + * + * @returns zero on success, and updates the data pointer. Returns a non-zero + * error code on failure. + */ +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS */ +static int ixgbe_devlink_devcaps_snapshot(struct devlink *devlink, +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS + const struct devlink_region_ops + __always_unused *ops, +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS */ + struct netlink_ext_ack *extack, + u8 **data) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct device *dev; + void *devcaps; + s32 status; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + hw = &adapter->hw; + + devcaps = vzalloc(IXGBE_ACI_MAX_BUF_LEN); + if (!devcaps) + return -ENOMEM; + + status = ixgbe_aci_list_caps(hw, devcaps, IXGBE_ACI_MAX_BUF_LEN, NULL, + ixgbe_aci_opc_list_dev_caps); + if (status) { + dev_dbg(dev, + "ixgbe_aci_list_caps: failed to read device capabilities, err %d aci_err %d\n", + status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to read device capabilities"); + vfree(devcaps); + return status; + } + + *data = (u8 *)devcaps; + + return 0; +} +#endif /* HAVE_DEVLINK_REGION_OPS_SNAPSHOT */ + +static const struct devlink_region_ops ixgbe_nvm_region_ops = { + .name = "nvm-flash", + .destructor = vfree, +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT + .snapshot = ixgbe_devlink_nvm_snapshot, +#endif +}; + +static const struct devlink_region_ops ixgbe_sram_region_ops = { + .name = "shadow-ram", + .destructor = vfree, +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT + .snapshot = ixgbe_devlink_sram_snapshot, +#endif +}; + +static const struct devlink_region_ops ixgbe_devcaps_region_ops = { + .name = "device-caps", + .destructor = vfree, +#ifdef HAVE_DEVLINK_REGION_OPS_SNAPSHOT + .snapshot = ixgbe_devlink_devcaps_snapshot, +#endif +}; + +/** + * ixgbe_devlink_init_regions - Initialize devlink regions + * @adapter: adapter instance + * + * Create devlink regions used to enable access to dump the contents of the + * flash memory on the device. + */ +void ixgbe_devlink_init_regions(struct ixgbe_adapter *adapter) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct devlink *devlink = adapter->devlink; + u64 nvm_size, sram_size; + + nvm_size = adapter->hw.flash.flash_size; + adapter->nvm_region = + devlink_region_create(devlink, + &ixgbe_nvm_region_ops, + 1, nvm_size); + if (IS_ERR(adapter->nvm_region)) { + dev_err(dev, + "Failed to create NVM devlink region, err %ld\n", + PTR_ERR(adapter->nvm_region)); + adapter->nvm_region = NULL; + } + + sram_size = adapter->hw.flash.sr_words * 2u; + adapter->sram_region = + devlink_region_create(devlink, + &ixgbe_sram_region_ops, + 1, sram_size); + if (IS_ERR(adapter->sram_region)) { + dev_err(dev, + "Failed to create shadow-ram devlink region, err %ld\n", + PTR_ERR(adapter->sram_region)); + adapter->sram_region = NULL; + } + + adapter->devcaps_region = + devlink_region_create(devlink, + &ixgbe_devcaps_region_ops, + 10, IXGBE_ACI_MAX_BUF_LEN); + if (IS_ERR(adapter->devcaps_region)) { + dev_err(dev, + "Failed to create device-caps devlink region, err %ld\n", + PTR_ERR(adapter->devcaps_region)); + adapter->devcaps_region = NULL; + } +} + +/** + * ixgbe_devlink_destroy_regions - Destroy devlink regions + * @adapter: adapter instance + * + * Remove previously created regions for this PF. + */ +void ixgbe_devlink_destroy_regions(struct ixgbe_adapter *adapter) +{ + if (adapter->nvm_region) + devlink_region_destroy(adapter->nvm_region); + + if (adapter->sram_region) + devlink_region_destroy(adapter->sram_region); + + if (adapter->devcaps_region) + devlink_region_destroy(adapter->devcaps_region); +} +#endif /* HAVE_DEVLINK_REGIONS */ + +#endif /* CONFIG_NET_DEVLINK */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.h new file mode 100644 index 0000000000..5bfa522694 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_devlink.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_DEVLINK_H_ +#define _IXGBE_DEVLINK_H_ + +#if IS_ENABLED(CONFIG_NET_DEVLINK) + +struct ixgbe_adapter **ixgbe_allocate_devlink(struct ixgbe_adapter *adapter); + +void ixgbe_devlink_register(struct ixgbe_adapter *adapter); +void ixgbe_devlink_unregister(struct ixgbe_adapter *adapter); + +int ixgbe_devlink_register_params(struct ixgbe_adapter *adapter); +void ixgbe_devlink_unregister_params(struct ixgbe_adapter *adapter); + +int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter); +void ixgbe_devlink_unregister_port(struct ixgbe_adapter *adapter); + +#else /* CONFIG_NET_DEVLINK */ + +struct ixgbe_adapter **ixgbe_allocate_devlink(struct ixgbe_adapter *adapter) +{ + return NULL +} + +static inline void ixgbe_devlink_register(struct ixgbe_adapter *adapter) { } +static inline void ixgbe_devlink_unregister(struct ixgbe_adapter *adapter) { } + +static inline int ixgbe_devlink_register_params(struct ixgbe_adapter *adapter) { return 0; } +static inline void ixgbe_devlink_unregister_params(struct ixgbe_adapter *adapter) { } + +static inline int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter) { return 0; } +static inline void ixgbe_devlink_unregister_port(struct ixgbe_adapter *adapter) { } + +#endif /* !CONFIG_NET_DEVLINK */ + +#if IS_ENABLED(CONFIG_NET_DEVLINK) && defined(HAVE_DEVLINK_REGIONS) + +void ixgbe_devlink_init_regions(struct ixgbe_adapter *adapter); +void ixgbe_devlink_destroy_regions(struct ixgbe_adapter *adapter); + +#else + +static inline void ixgbe_devlink_init_regions(struct ixgbe_adapter *adapter) { } +static inline void ixgbe_devlink_destroy_regions(struct ixgbe_adapter *adapter) { } + +#endif + +#endif /* _IXGBE_DEVLINK_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.c new file mode 100644 index 0000000000..4fa600f60f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.c @@ -0,0 +1,6282 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_e610.h" +#include "ixgbe_x550.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" +#include "ixgbe_api.h" + +/** + * ixgbe_init_aci - initialization routine for Admin Command Interface + * @hw: pointer to the hardware structure + * + * Initialize the ACI lock. + */ +void ixgbe_init_aci(struct ixgbe_hw *hw) +{ + ixgbe_init_lock(&hw->aci.lock); +} + +/** + * ixgbe_shutdown_aci - shutdown routine for Admin Command Interface + * @hw: pointer to the hardware structure + * + * Destroy the ACI lock. + */ +void ixgbe_shutdown_aci(struct ixgbe_hw *hw) +{ + ixgbe_destroy_lock(&hw->aci.lock); +} + +#define IXGBE_ACI_DEBUG_PREFIX "ixgbe " +#define ixgbe_aci_debug_array(hw, rowsize, buf, len) \ + print_hex_dump_debug(IXGBE_ACI_DEBUG_PREFIX, DUMP_PREFIX_OFFSET, \ + rowsize, 1, buf, len, false) + +/** + * ixgbe_aci_debug - dump the ACI data with the descriptor contents. + * @hw: pointer to the hardware structure + * @desc: pointer to control queue descriptor + * @buf: pointer to command buffer + * @buf_len: max length of buf + * + * Debug function for dumping logs about ACI command with descriptor contents. + */ +void ixgbe_aci_debug(struct ixgbe_hw *hw, void *desc, void *buf, u16 buf_len) +{ + struct ixgbe_aci_desc *aci_desc = (struct ixgbe_aci_desc *)desc; + u16 datalen, flags; + + if (!hw || !desc) + return; + + datalen = IXGBE_LE16_TO_CPU(aci_desc->datalen); + flags = IXGBE_LE16_TO_CPU(aci_desc->flags); + + hw_dbg(hw, "CQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n", + IXGBE_LE16_TO_CPU(aci_desc->opcode), flags, datalen, + IXGBE_LE16_TO_CPU(aci_desc->retval)); + hw_dbg(hw, "\tcookie (h,l) 0x%08X 0x%08X\n", + IXGBE_LE32_TO_CPU(aci_desc->cookie_high), + IXGBE_LE32_TO_CPU(aci_desc->cookie_low)); + hw_dbg(hw, "\tparam (0,1) 0x%08X 0x%08X\n", + IXGBE_LE32_TO_CPU(aci_desc->params.generic.param0), + IXGBE_LE32_TO_CPU(aci_desc->params.generic.param1)); + hw_dbg(hw, "\taddr (h,l) 0x%08X 0x%08X\n", + IXGBE_LE32_TO_CPU(aci_desc->params.generic.addr_high), + IXGBE_LE32_TO_CPU(aci_desc->params.generic.addr_low)); + + /* Dump buffer if 1) one exists and 2) is either a response indicated + * by the DD and/or CMP flag set or a command with the RD flag set. + */ + if (buf && aci_desc->datalen != 0 && + (flags & (IXGBE_ACI_FLAG_DD | IXGBE_ACI_FLAG_CMP) || + flags & IXGBE_ACI_FLAG_RD)) { + hw_dbg(hw, "Buffer:\n"); + ixgbe_aci_debug_array(hw, 16, (u8 *)buf, min(buf_len, datalen)); + } +} + +/** + * ixgbe_should_retry_aci_send_cmd_execute - decide if ACI command should + * be resent + * @opcode: ACI opcode + * + * Check if ACI command should be sent again depending on the provided opcode. + * + * Return: true if the sending command routine should be repeated, + * otherwise false. + */ +STATIC bool ixgbe_should_retry_aci_send_cmd_execute(u16 opcode) +{ + + switch (opcode) { + case ixgbe_aci_opc_disable_rxen: + case ixgbe_aci_opc_get_phy_caps: + case ixgbe_aci_opc_get_link_status: + case ixgbe_aci_opc_get_link_topo: + return true; + } + + return false; +} + +/** + * ixgbe_aci_send_cmd_execute - execute sending FW Admin Command to FW Admin + * Command Interface + * @hw: pointer to the HW struct + * @desc: descriptor describing the command + * @buf: buffer to use for indirect commands (NULL for direct commands) + * @buf_size: size of buffer for indirect commands (0 for direct commands) + * + * Admin Command is sent using CSR by setting descriptor and buffer in specific + * registers. + * + * Return: the exit code of the operation. + * * - IXGBE_SUCCESS - success. + * * - IXGBE_ERR_ACI_DISABLED - CSR mechanism is not enabled. + * * - IXGBE_ERR_ACI_BUSY - CSR mechanism is busy. + * * - IXGBE_ERR_PARAM - buf_size is too big or + * invalid argument buf or buf_size. + * * - IXGBE_ERR_ACI_TIMEOUT - Admin Command X command timeout. + * * - IXGBE_ERR_ACI_ERROR - Admin Command X invalid state of HICR register or + * Admin Command failed because of bad opcode was returned or + * Admin Command failed with error Y. + */ +STATIC s32 +ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc, + void *buf, u16 buf_size) +{ + u32 hicr = 0, tmp_buf_size = 0, i = 0; + u32 *raw_desc = (u32 *)desc; + s32 status = IXGBE_SUCCESS; + bool valid_buf = false; + u32 *tmp_buf = NULL; + u16 opcode = 0; + + do { + hw->aci.last_status = IXGBE_ACI_RC_OK; + + /* It's necessary to check if mechanism is enabled */ + hicr = IXGBE_READ_REG(hw, PF_HICR); + if (!(hicr & PF_HICR_EN)) { + hw_dbg(hw, "CSR mechanism is not enabled\n"); + status = IXGBE_ERR_ACI_DISABLED; + break; + } + if (hicr & PF_HICR_C) { + hw_dbg(hw, "CSR mechanism is busy\n"); + hw->aci.last_status = IXGBE_ACI_RC_EBUSY; + status = IXGBE_ERR_ACI_BUSY; + break; + } + opcode = desc->opcode; + + if (buf_size > IXGBE_ACI_MAX_BUFFER_SIZE) { + hw_dbg(hw, "buf_size is too big\n"); + status = IXGBE_ERR_PARAM; + break; + } + + if (buf) + desc->flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF); + + /* Check if buf and buf_size are proper params */ + if (desc->flags & IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF)) { + if ((buf && buf_size == 0) || + (buf == NULL && buf_size)) { + status = IXGBE_ERR_PARAM; + hw_dbg(hw, "Error: Invalid argument buf or buf_size\n"); + break; + } + if (buf && buf_size) + valid_buf = true; + } + + if (valid_buf == true) { + if (buf_size % 4 == 0) + tmp_buf_size = buf_size; + else + tmp_buf_size = (buf_size & (u16)(~0x03)) + 4; + + tmp_buf = (u32*)ixgbe_malloc(hw, tmp_buf_size); + if (!tmp_buf) + return IXGBE_ERR_OUT_OF_MEM; + + /* tmp_buf will be firstly filled with 0xFF and after + * that the content of buf will be written into it. + * This approach lets us use valid buf_size and + * prevents us from reading past buf area + * when buf_size mod 4 not equal to 0. + */ + memset(tmp_buf, 0xFF, tmp_buf_size); + memcpy(tmp_buf, buf, buf_size); + + if (tmp_buf_size > IXGBE_ACI_LG_BUF) + desc->flags |= + IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_LB); + + desc->datalen = IXGBE_CPU_TO_LE16(buf_size); + + if (desc->flags & IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD)) { + for (i = 0; i < tmp_buf_size / 4; i++) { + IXGBE_WRITE_REG(hw, PF_HIBA(i), + IXGBE_LE32_TO_CPU(tmp_buf[i])); + } + } + } + + ixgbe_aci_debug(hw, (void *)desc, tmp_buf, (u16)tmp_buf_size); + + /* Descriptor is written to specific registers */ + for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) + IXGBE_WRITE_REG(hw, PF_HIDA(i), + IXGBE_LE32_TO_CPU(raw_desc[i])); + + /* SW has to set PF_HICR.C bit and clear PF_HICR.SV and + * PF_HICR_EV + */ + hicr = IXGBE_READ_REG(hw, PF_HICR); + hicr = (hicr | PF_HICR_C) & ~(PF_HICR_SV | PF_HICR_EV); + IXGBE_WRITE_REG(hw, PF_HICR, hicr); + + /* Wait for sync Admin Command response */ + for (i = 0; i < IXGBE_ACI_SYNC_RESPONSE_TIMEOUT; i += 1) { + hicr = IXGBE_READ_REG(hw, PF_HICR); + if ((hicr & PF_HICR_SV) || !(hicr & PF_HICR_C)) + break; + + msec_delay(1); + } + + /* Wait for async Admin Command response */ + if ((hicr & PF_HICR_SV) && (hicr & PF_HICR_C)) { + for (i = 0; i < IXGBE_ACI_ASYNC_RESPONSE_TIMEOUT; + i += 1) { + hicr = IXGBE_READ_REG(hw, PF_HICR); + if ((hicr & PF_HICR_EV) || !(hicr & PF_HICR_C)) + break; + + msec_delay(1); + } + } + + /* Read sync Admin Command response */ + if ((hicr & PF_HICR_SV)) { + for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) { + raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA(i)); + raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]); + } + ixgbe_aci_debug(hw, (void *)raw_desc, NULL, 0); + } + + /* Read async Admin Command response */ + if ((hicr & PF_HICR_EV) && !(hicr & PF_HICR_C)) { + for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) { + raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA_2(i)); + raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]); + } + ixgbe_aci_debug(hw, (void *)raw_desc, NULL, 0); + } + + /* Handle timeout and invalid state of HICR register */ + if (hicr & PF_HICR_C) { + hw_dbg(hw, "Error: Admin Command 0x%X command timeout\n", + desc->opcode); + status = IXGBE_ERR_ACI_TIMEOUT; + break; + } else if (!(hicr & PF_HICR_SV) && !(hicr & PF_HICR_EV)) { + hw_dbg(hw, "Error: Admin Command 0x%X invalid state of HICR register\n", + desc->opcode); + status = IXGBE_ERR_ACI_ERROR; + break; + } + + /* For every command other than 0x0014 treat opcode mismatch + * as an error. Response to 0x0014 command read from HIDA_2 + * is a descriptor of an event which is expected to contain + * different opcode than the command. + */ + if (desc->opcode != opcode && + opcode != IXGBE_CPU_TO_LE16(ixgbe_aci_opc_get_fw_event)) { + hw_dbg(hw, "Error: Admin Command failed because of bad opcode was returned\n"); + status = IXGBE_ERR_ACI_ERROR; + break; + } + + if (desc->retval != IXGBE_ACI_RC_OK) { + hw_dbg(hw, "Error: Admin Command failed with error %x\n", + desc->retval); + hw->aci.last_status = (enum ixgbe_aci_err)desc->retval; + status = IXGBE_ERR_ACI_ERROR; + break; + } + + /* Write a response values to a buf */ + if (valid_buf && (desc->flags & + IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF))) { + for (i = 0; i < tmp_buf_size / 4; i++) { + tmp_buf[i] = IXGBE_R32_Q(hw, PF_HIBA(i)); + tmp_buf[i] = IXGBE_CPU_TO_LE32(tmp_buf[i]); + } + memcpy(buf, tmp_buf, buf_size); + ixgbe_aci_debug(hw, (void *)raw_desc, tmp_buf, + (u16)tmp_buf_size); + } + } while (0); + + if (tmp_buf) + ixgbe_free(hw, tmp_buf); + + return status; +} + +/** + * ixgbe_aci_send_cmd - send FW Admin Command to FW Admin Command Interface + * @hw: pointer to the HW struct + * @desc: descriptor describing the command + * @buf: buffer to use for indirect commands (NULL for direct commands) + * @buf_size: size of buffer for indirect commands (0 for direct commands) + * + * Helper function to send FW Admin Commands to the FW Admin Command Interface. + * + * Retry sending the FW Admin Command multiple times to the FW ACI + * if the EBUSY Admin Command error is returned. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_send_cmd(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc, + void *buf, u16 buf_size) +{ + struct ixgbe_aci_desc desc_cpy; + enum ixgbe_aci_err last_status; + bool is_cmd_for_retry; + u8 *buf_cpy = NULL; + s32 status; + u16 opcode; + u8 idx = 0; + + opcode = IXGBE_LE16_TO_CPU(desc->opcode); + is_cmd_for_retry = ixgbe_should_retry_aci_send_cmd_execute(opcode); + memset(&desc_cpy, 0, sizeof(desc_cpy)); + + if (is_cmd_for_retry) { + if (buf) { + buf_cpy = (u8 *)ixgbe_malloc(hw, buf_size); + if (!buf_cpy) + return IXGBE_ERR_OUT_OF_MEM; + memcpy(buf_cpy, buf, buf_size); + } + memcpy(&desc_cpy, desc, sizeof(desc_cpy)); + } + + do { + ixgbe_acquire_lock(&hw->aci.lock); + status = ixgbe_aci_send_cmd_execute(hw, desc, buf, buf_size); + last_status = hw->aci.last_status; + ixgbe_release_lock(&hw->aci.lock); + + if (!is_cmd_for_retry || status == IXGBE_SUCCESS || + (last_status != IXGBE_ACI_RC_EBUSY && status != IXGBE_ERR_ACI_ERROR)) + break; + + if (buf) + memcpy(buf, buf_cpy, buf_size); + memcpy(desc, &desc_cpy, sizeof(desc_cpy)); + + msec_delay(IXGBE_ACI_SEND_DELAY_TIME_MS); + } while (++idx < IXGBE_ACI_SEND_MAX_EXECUTE); + + if (buf_cpy) + ixgbe_free(hw, buf_cpy); + + return status; +} + +/** + * ixgbe_aci_check_event_pending - check if there are any pending events + * @hw: pointer to the HW struct + * + * Determine if there are any pending events. + * + * Return: true if there are any currently pending events + * otherwise false. + */ +bool ixgbe_aci_check_event_pending(struct ixgbe_hw *hw) +{ + u32 ep_bit_mask; + u32 fwsts; + + ep_bit_mask = hw->bus.func ? GL_FWSTS_EP_PF1 : GL_FWSTS_EP_PF0; + + /* Check state of Event Pending (EP) bit */ + fwsts = IXGBE_READ_REG(hw, GL_FWSTS); + return (fwsts & ep_bit_mask) ? true : false; +} + +/** + * ixgbe_aci_get_event - get an event from ACI + * @hw: pointer to the HW struct + * @e: event information structure + * @pending: optional flag signaling that there are more pending events + * + * Obtain an event from ACI and return its content + * through 'e' using ACI command (0x0014). + * Provide information if there are more events + * to retrieve through 'pending'. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_event(struct ixgbe_hw *hw, struct ixgbe_aci_event *e, + bool *pending) +{ + struct ixgbe_aci_desc desc; + s32 status; + + if (!e || (!e->msg_buf && e->buf_len) || (e->msg_buf && !e->buf_len)) + return IXGBE_ERR_PARAM; + + ixgbe_acquire_lock(&hw->aci.lock); + + /* Check if there are any events pending */ + if (!ixgbe_aci_check_event_pending(hw)) { + status = IXGBE_ERR_ACI_NO_EVENTS; + goto aci_get_event_exit; + } + + /* Obtain pending event */ + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_fw_event); + status = ixgbe_aci_send_cmd_execute(hw, &desc, e->msg_buf, e->buf_len); + if (status) + goto aci_get_event_exit; + + /* Returned 0x0014 opcode indicates that no event was obtained */ + if (desc.opcode == IXGBE_CPU_TO_LE16(ixgbe_aci_opc_get_fw_event)) { + status = IXGBE_ERR_ACI_NO_EVENTS; + goto aci_get_event_exit; + } + + /* Determine size of event data */ + e->msg_len = MIN_T(u16, IXGBE_LE16_TO_CPU(desc.datalen), e->buf_len); + /* Write event descriptor to event info structure */ + memcpy(&e->desc, &desc, sizeof(e->desc)); + + /* Check if there are any further events pending */ + if (pending) { + *pending = ixgbe_aci_check_event_pending(hw); + } + +aci_get_event_exit: + ixgbe_release_lock(&hw->aci.lock); + + return status; +} + +/** + * ixgbe_fill_dflt_direct_cmd_desc - fill ACI descriptor with default values. + * @desc: pointer to the temp descriptor (non DMA mem) + * @opcode: the opcode can be used to decide which flags to turn off or on + * + * Helper function to fill the descriptor desc with default values + * and the provided opcode. + */ +void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc *desc, u16 opcode) +{ + /* zero out the desc */ + memset(desc, 0, sizeof(*desc)); + desc->opcode = IXGBE_CPU_TO_LE16(opcode); + desc->flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_SI); +} + +/** + * ixgbe_aci_get_fw_ver - get the firmware version + * @hw: pointer to the HW struct + * + * Get the firmware version using ACI command (0x0001). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_fw_ver(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_ver *resp; + struct ixgbe_aci_desc desc; + s32 status; + + resp = &desc.params.get_ver; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_ver); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + if (!status) { + hw->fw_branch = resp->fw_branch; + hw->fw_maj_ver = resp->fw_major; + hw->fw_min_ver = resp->fw_minor; + hw->fw_patch = resp->fw_patch; + hw->fw_build = IXGBE_LE32_TO_CPU(resp->fw_build); + hw->api_branch = resp->api_branch; + hw->api_maj_ver = resp->api_major; + hw->api_min_ver = resp->api_minor; + hw->api_patch = resp->api_patch; + } + + return status; +} + +/** + * ixgbe_aci_send_driver_ver - send the driver version to firmware + * @hw: pointer to the HW struct + * @dv: driver's major, minor version + * + * Send the driver version to the firmware + * using the ACI command (0x0002). + * + * Return: the exit code of the operation. + * Returns IXGBE_ERR_PARAM, if dv is NULL. + */ +s32 ixgbe_aci_send_driver_ver(struct ixgbe_hw *hw, struct ixgbe_driver_ver *dv) +{ + struct ixgbe_aci_cmd_driver_ver *cmd; + struct ixgbe_aci_desc desc; + u16 len; + + cmd = &desc.params.driver_ver; + + if (!dv) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_driver_ver); + + desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + cmd->major_ver = dv->major_ver; + cmd->minor_ver = dv->minor_ver; + cmd->build_ver = dv->build_ver; + cmd->subbuild_ver = dv->subbuild_ver; + + len = 0; + while (len < sizeof(dv->driver_string) && + IS_ASCII(dv->driver_string[len]) && dv->driver_string[len]) + len++; + + return ixgbe_aci_send_cmd(hw, &desc, dv->driver_string, len); +} + +/** + * ixgbe_aci_req_res - request a common resource + * @hw: pointer to the HW struct + * @res: resource ID + * @access: access type + * @sdp_number: resource number + * @timeout: the maximum time in ms that the driver may hold the resource + * + * Requests a common resource using the ACI command (0x0008). + * Specifies the maximum time the driver may hold the resource. + * If the requested resource is currently occupied by some other driver, + * a busy return value is returned and the timeout field value indicates the + * maximum time the current owner has to free it. + * + * Return: the exit code of the operation. + */ +static s32 +ixgbe_aci_req_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res, + enum ixgbe_aci_res_access_type access, u8 sdp_number, + u32 *timeout) +{ + struct ixgbe_aci_cmd_req_res *cmd_resp; + struct ixgbe_aci_desc desc; + s32 status; + + cmd_resp = &desc.params.res_owner; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_req_res); + + cmd_resp->res_id = IXGBE_CPU_TO_LE16(res); + cmd_resp->access_type = IXGBE_CPU_TO_LE16(access); + cmd_resp->res_number = IXGBE_CPU_TO_LE32(sdp_number); + cmd_resp->timeout = IXGBE_CPU_TO_LE32(*timeout); + *timeout = 0; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + /* The completion specifies the maximum time in ms that the driver + * may hold the resource in the Timeout field. + */ + + /* If the resource is held by some other driver, the command completes + * with a busy return value and the timeout field indicates the maximum + * time the current owner of the resource has to free it. + */ + if (!status || hw->aci.last_status == IXGBE_ACI_RC_EBUSY) + *timeout = IXGBE_LE32_TO_CPU(cmd_resp->timeout); + + return status; +} + +/** + * ixgbe_aci_release_res - release a common resource using ACI + * @hw: pointer to the HW struct + * @res: resource ID + * @sdp_number: resource number + * + * Release a common resource using ACI command (0x0009). + * + * Return: the exit code of the operation. + */ +static s32 +ixgbe_aci_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res, + u8 sdp_number) +{ + struct ixgbe_aci_cmd_req_res *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.res_owner; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_release_res); + + cmd->res_id = IXGBE_CPU_TO_LE16(res); + cmd->res_number = IXGBE_CPU_TO_LE32(sdp_number); + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_acquire_res - acquire the ownership of a resource + * @hw: pointer to the HW structure + * @res: resource ID + * @access: access type (read or write) + * @timeout: timeout in milliseconds + * + * Make an attempt to acquire the ownership of a resource using + * the ixgbe_aci_req_res to utilize ACI. + * In case if some other driver has previously acquired the resource and + * performed any necessary updates, the IXGBE_ERR_ACI_NO_WORK is returned, + * and the caller does not obtain the resource and has no further work to do. + * If needed, the function will poll until the current lock owner timeouts. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_acquire_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res, + enum ixgbe_aci_res_access_type access, u32 timeout) +{ +#define IXGBE_RES_POLLING_DELAY_MS 10 + u32 delay = IXGBE_RES_POLLING_DELAY_MS; + u32 res_timeout = timeout; + u32 retry_timeout = 0; + s32 status; + + status = ixgbe_aci_req_res(hw, res, access, 0, &res_timeout); + + /* A return code of IXGBE_ERR_ACI_NO_WORK means that another driver has + * previously acquired the resource and performed any necessary updates; + * in this case the caller does not obtain the resource and has no + * further work to do. + */ + if (status == IXGBE_ERR_ACI_NO_WORK) + goto ixgbe_acquire_res_exit; + + /* If necessary, poll until the current lock owner timeouts. + * Set retry_timeout to the timeout value reported by the FW in the + * response to the "Request Resource Ownership" (0x0008) Admin Command + * as it indicates the maximum time the current owner of the resource + * is allowed to hold it. + */ + retry_timeout = res_timeout; + while (status && retry_timeout && res_timeout) { + msec_delay(delay); + retry_timeout = (retry_timeout > delay) ? + retry_timeout - delay : 0; + status = ixgbe_aci_req_res(hw, res, access, 0, &res_timeout); + + if (status == IXGBE_ERR_ACI_NO_WORK) + /* lock free, but no work to do */ + break; + + if (!status) + /* lock acquired */ + break; + } + +ixgbe_acquire_res_exit: + return status; +} + +/** + * ixgbe_release_res - release a common resource + * @hw: pointer to the HW structure + * @res: resource ID + * + * Release a common resource using ixgbe_aci_release_res. + */ +void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res) +{ + u32 total_delay = 0; + s32 status; + + status = ixgbe_aci_release_res(hw, res, 0); + + /* There are some rare cases when trying to release the resource + * results in an admin command timeout, so handle them correctly. + */ + while ((status == IXGBE_ERR_ACI_TIMEOUT) && + (total_delay < IXGBE_ACI_RELEASE_RES_TIMEOUT)) { + msec_delay(1); + status = ixgbe_aci_release_res(hw, res, 0); + total_delay++; + } +} + +/** + * ixgbe_parse_common_caps - Parse common device/function capabilities + * @hw: pointer to the HW struct + * @caps: pointer to common capabilities structure + * @elem: the capability element to parse + * @prefix: message prefix for tracing capabilities + * + * Given a capability element, extract relevant details into the common + * capability structure. + * + * Return: true if the capability matches one of the common capability ids, + * false otherwise. + */ +static bool +ixgbe_parse_common_caps(struct ixgbe_hw *hw, struct ixgbe_hw_common_caps *caps, + struct ixgbe_aci_cmd_list_caps_elem *elem, + const char *prefix) +{ + u32 logical_id = IXGBE_LE32_TO_CPU(elem->logical_id); + u32 phys_id = IXGBE_LE32_TO_CPU(elem->phys_id); + u32 number = IXGBE_LE32_TO_CPU(elem->number); + u16 cap = IXGBE_LE16_TO_CPU(elem->cap); + bool found = true; + + UNREFERENCED_1PARAMETER(hw); + + switch (cap) { + case IXGBE_ACI_CAPS_VALID_FUNCTIONS: + caps->valid_functions = number; + break; + case IXGBE_ACI_CAPS_VMDQ: + caps->vmdq = (number == 1); + break; + case IXGBE_ACI_CAPS_DCB: + caps->dcb = (number == 1); + caps->active_tc_bitmap = logical_id; + caps->maxtc = phys_id; + break; + case IXGBE_ACI_CAPS_RSS: + caps->rss_table_size = number; + caps->rss_table_entry_width = logical_id; + break; + case IXGBE_ACI_CAPS_RXQS: + caps->num_rxq = number; + caps->rxq_first_id = phys_id; + break; + case IXGBE_ACI_CAPS_TXQS: + caps->num_txq = number; + caps->txq_first_id = phys_id; + break; + case IXGBE_ACI_CAPS_MSIX: + caps->num_msix_vectors = number; + caps->msix_vector_first_id = phys_id; + break; + case IXGBE_ACI_CAPS_NVM_VER: + break; + case IXGBE_ACI_CAPS_PENDING_NVM_VER: + caps->nvm_update_pending_nvm = true; + break; + case IXGBE_ACI_CAPS_PENDING_OROM_VER: + caps->nvm_update_pending_orom = true; + break; + case IXGBE_ACI_CAPS_PENDING_NET_VER: + caps->nvm_update_pending_netlist = true; + break; + case IXGBE_ACI_CAPS_NVM_MGMT: + caps->sec_rev_disabled = + (number & IXGBE_NVM_MGMT_SEC_REV_DISABLED) ? + true : false; + caps->update_disabled = + (number & IXGBE_NVM_MGMT_UPDATE_DISABLED) ? + true : false; + caps->nvm_unified_update = + (number & IXGBE_NVM_MGMT_UNIFIED_UPD_SUPPORT) ? + true : false; + caps->netlist_auth = + (number & IXGBE_NVM_MGMT_NETLIST_AUTH_SUPPORT) ? + true : false; + break; + case IXGBE_ACI_CAPS_MAX_MTU: + caps->max_mtu = number; + break; + case IXGBE_ACI_CAPS_PCIE_RESET_AVOIDANCE: + caps->pcie_reset_avoidance = (number > 0); + break; + case IXGBE_ACI_CAPS_POST_UPDATE_RESET_RESTRICT: + caps->reset_restrict_support = (number == 1); + break; + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0: + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG1: + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG2: + case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG3: + { + u8 index = cap - IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0; + + caps->ext_topo_dev_img_ver_high[index] = number; + caps->ext_topo_dev_img_ver_low[index] = logical_id; + caps->ext_topo_dev_img_part_num[index] = + (phys_id & IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_M) >> + IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_S; + caps->ext_topo_dev_img_load_en[index] = + (phys_id & IXGBE_EXT_TOPO_DEV_IMG_LOAD_EN) != 0; + caps->ext_topo_dev_img_prog_en[index] = + (phys_id & IXGBE_EXT_TOPO_DEV_IMG_PROG_EN) != 0; + break; + } + case IXGBE_ACI_CAPS_OROM_RECOVERY_UPDATE: + caps->orom_recovery_update = (number == 1); + break; + + case IXGBE_ACI_CAPS_NEXT_CLUSTER_ID: + caps->next_cluster_id_support = (number == 1); + hw_dbg(hw, "%s: next_cluster_id_support = %d\n", + prefix, caps->next_cluster_id_support); + break; +#ifndef NO_PTP_SUPPORT + case IXGBE_ACI_CAPS_PTP_BY_PHY: + caps->ptp_by_phy_support = + (number & IXGBE_ACI_CAPS_PTP_BY_PHY_SUPP) ? true : + false; + caps->ptp_by_phy_ll = + (number & IXGBE_ACI_CAPS_PTP_BY_PHY_LL) ? true : false; + hw_dbg(hw, "%s: ptp_by_phy_support = %d, low_latency = %d\n", + prefix, caps->ptp_by_phy_support, + caps->ptp_by_phy_ll); + break; +#endif /* !NO_PTP_SUPPORT */ + case IXGBE_ACI_CAPS_EEE: + caps->eee_support = (u8)number; + hw_dbg(hw, "%s: eee_support = %x\n", prefix, caps->eee_support); + break; + default: + /* Not one of the recognized common capabilities */ + found = false; + } + + return found; +} + +/** + * ixgbe_hweight8 - count set bits among the 8 lowest bits + * @w: variable storing set bits to count + * + * Return: the number of set bits among the 8 lowest bits in the provided value. + */ +static u8 ixgbe_hweight8(u32 w) +{ + u8 hweight = 0, i; + + for (i = 0; i < 8; i++) + if (w & (1 << i)) + hweight++; + + return hweight; +} + +/** + * ixgbe_hweight32 - count set bits among the 32 lowest bits + * @w: variable storing set bits to count + * + * Return: the number of set bits among the 32 lowest bits in the + * provided value. + */ +static u8 ixgbe_hweight32(u32 w) +{ + return (u8)hweight32(w); /* narrow at the leaf if needed */ +} + +/** + * ixgbe_parse_valid_functions_cap - Parse IXGBE_ACI_CAPS_VALID_FUNCTIONS caps + * @hw: pointer to the HW struct + * @dev_p: pointer to device capabilities structure + * @cap: capability element to parse + * + * Parse IXGBE_ACI_CAPS_VALID_FUNCTIONS for device capabilities. + */ +static void +ixgbe_parse_valid_functions_cap(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_p, + struct ixgbe_aci_cmd_list_caps_elem *cap) +{ + u32 number = IXGBE_LE32_TO_CPU(cap->number); + + UNREFERENCED_1PARAMETER(hw); + + dev_p->num_funcs = ixgbe_hweight32(number); + +} + +/** + * ixgbe_parse_vsi_dev_caps - Parse IXGBE_ACI_CAPS_VSI device caps + * @hw: pointer to the HW struct + * @dev_p: pointer to device capabilities structure + * @cap: capability element to parse + * + * Parse IXGBE_ACI_CAPS_VSI for device capabilities. + */ +static void ixgbe_parse_vsi_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_p, + struct ixgbe_aci_cmd_list_caps_elem *cap) +{ + u32 number = IXGBE_LE32_TO_CPU(cap->number); + + UNREFERENCED_1PARAMETER(hw); + + dev_p->num_vsi_allocd_to_host = number; +} + +#ifndef NO_PTP_SUPPORT +/** + * ixgbe_parse_1588_dev_caps - Parse IXGBE_ACI_CAPS_1588 device caps + * @hw: pointer to the HW struct + * @dev_p: pointer to device capabilities structure + * @cap: capability element to parse + * + * Parse IXGBE_ACI_CAPS_1588 for device capabilities. + */ +static void ixgbe_parse_1588_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_p, + struct ixgbe_aci_cmd_list_caps_elem *cap) +{ + struct ixgbe_ts_dev_info *info = &dev_p->ts_dev_info; + u32 logical_id = IXGBE_LE32_TO_CPU(cap->logical_id); + u32 phys_id = IXGBE_LE32_TO_CPU(cap->phys_id); + u32 number = IXGBE_LE32_TO_CPU(cap->number); + + UNREFERENCED_1PARAMETER(hw); + + info->ena = ((number & IXGBE_TS_DEV_ENA_M) != 0); + dev_p->common_cap.ieee_1588 = info->ena; + + info->tmr0_owner = number & IXGBE_TS_TMR0_OWNR_M; + info->tmr0_owned = ((number & IXGBE_TS_TMR0_OWND_M) != 0); + info->tmr0_ena = ((number & IXGBE_TS_TMR0_ENA_M) != 0); + + info->tmr1_owner = (number & IXGBE_TS_TMR1_OWNR_M) >> + IXGBE_TS_TMR1_OWNR_S; + info->tmr1_owned = ((number & IXGBE_TS_TMR1_OWND_M) != 0); + info->tmr1_ena = ((number & IXGBE_TS_TMR1_ENA_M) != 0); + + info->ena_ports = logical_id; + info->tmr_own_map = phys_id; + +} +#endif /* NO_PTP_SUPPORT */ + +/** + * ixgbe_parse_fdir_dev_caps - Parse IXGBE_ACI_CAPS_FD device caps + * @hw: pointer to the HW struct + * @dev_p: pointer to device capabilities structure + * @cap: capability element to parse + * + * Parse IXGBE_ACI_CAPS_FD for device capabilities. + */ +static void ixgbe_parse_fdir_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_p, + struct ixgbe_aci_cmd_list_caps_elem *cap) +{ + u32 number = IXGBE_LE32_TO_CPU(cap->number); + + UNREFERENCED_1PARAMETER(hw); + + dev_p->num_flow_director_fltr = number; +} + +/** + * ixgbe_parse_dev_caps - Parse device capabilities + * @hw: pointer to the HW struct + * @dev_p: pointer to device capabilities structure + * @buf: buffer containing the device capability records + * @cap_count: the number of capabilities + * + * Helper device to parse device (0x000B) capabilities list. For + * capabilities shared between device and function, this relies on + * ixgbe_parse_common_caps. + * + * Loop through the list of provided capabilities and extract the relevant + * data into the device capabilities structured. + */ +static void ixgbe_parse_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_p, + void *buf, u32 cap_count) +{ + struct ixgbe_aci_cmd_list_caps_elem *cap_resp; + u32 i; + + cap_resp = (struct ixgbe_aci_cmd_list_caps_elem *)buf; + + memset(dev_p, 0, sizeof(*dev_p)); + + for (i = 0; i < cap_count; i++) { + u16 cap = IXGBE_LE16_TO_CPU(cap_resp[i].cap); + bool found; + + found = ixgbe_parse_common_caps(hw, &dev_p->common_cap, + &cap_resp[i], "dev caps"); + + switch (cap) { + case IXGBE_ACI_CAPS_VALID_FUNCTIONS: + ixgbe_parse_valid_functions_cap(hw, dev_p, + &cap_resp[i]); + break; + case IXGBE_ACI_CAPS_VSI: + ixgbe_parse_vsi_dev_caps(hw, dev_p, &cap_resp[i]); + break; +#ifndef NO_PTP_SUPPORT + case IXGBE_ACI_CAPS_1588: + ixgbe_parse_1588_dev_caps(hw, dev_p, &cap_resp[i]); + break; +#endif /* !NO_PTP_SUPPORT */ + case IXGBE_ACI_CAPS_FD: + ixgbe_parse_fdir_dev_caps(hw, dev_p, &cap_resp[i]); + break; + default: + /* Don't list common capabilities as unknown */ + if (!found) + break; + } + } + +} + +/** + * ixgbe_get_num_per_func - determine number of resources per PF + * @hw: pointer to the HW structure + * @max: value to be evenly split between each PF + * + * Determine the number of valid functions by going through the bitmap returned + * from parsing capabilities and use this to calculate the number of resources + * per PF based on the max value passed in. + * + * Return: the number of resources per PF or 0, if no PH are available. + */ +static u32 ixgbe_get_num_per_func(struct ixgbe_hw *hw, u32 max) +{ + u8 funcs; + +#define IXGBE_CAPS_VALID_FUNCS_M 0xFF + funcs = ixgbe_hweight8(hw->dev_caps.common_cap.valid_functions & + IXGBE_CAPS_VALID_FUNCS_M); + + if (!funcs) + return 0; + + return max / funcs; +} + +/** + * ixgbe_parse_vsi_func_caps - Parse IXGBE_ACI_CAPS_VSI function caps + * @hw: pointer to the HW struct + * @func_p: pointer to function capabilities structure + * @cap: pointer to the capability element to parse + * + * Extract function capabilities for IXGBE_ACI_CAPS_VSI. + */ +static void ixgbe_parse_vsi_func_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_func_caps *func_p, + struct ixgbe_aci_cmd_list_caps_elem *cap) +{ + func_p->guar_num_vsi = ixgbe_get_num_per_func(hw, IXGBE_MAX_VSI); +} + +#ifndef NO_PTP_SUPPORT +/** + * ixgbe_parse_1588_func_caps - Parse IXGBE_ACI_CAPS_1588 function caps + * @hw: pointer to the HW struct + * @func_p: pointer to function capabilities structure + * @cap: pointer to the capability element to parse + * + * Extract function capabilities for IXGBE_ACI_CAPS_1588. + */ +static void ixgbe_parse_1588_func_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_func_caps *func_p, + struct ixgbe_aci_cmd_list_caps_elem *cap) +{ + struct ixgbe_ts_func_info *info = &func_p->ts_func_info; + u32 number = IXGBE_LE32_TO_CPU(cap->number); + + UNREFERENCED_1PARAMETER(hw); + + info->ena = ((number & IXGBE_TS_FUNC_ENA_M) != 0); + func_p->common_cap.ieee_1588 = info->ena; + + info->src_tmr_owned = ((number & IXGBE_TS_SRC_TMR_OWND_M) != 0); + info->tmr_ena = ((number & IXGBE_TS_TMR_ENA_M) != 0); + info->tmr_index_owned = ((number & IXGBE_TS_TMR_IDX_OWND_M) != 0); + info->tmr_index_assoc = ((number & IXGBE_TS_TMR_IDX_ASSOC_M) != 0); + + info->clk_freq = (number & IXGBE_TS_CLK_FREQ_M) >> IXGBE_TS_CLK_FREQ_S; + info->clk_src = ((number & IXGBE_TS_CLK_SRC_M) != 0); + + if (info->clk_freq < NUM_IXGBE_TIME_REF_FREQ) { + info->time_ref = (enum ixgbe_time_ref_freq)info->clk_freq; + } else { + /* Unknown clock frequency, so assume a (probably incorrect) + * default to avoid out-of-bounds look ups of frequency + * related information. + */ + info->time_ref = IXGBE_TIME_REF_FREQ_25_000; + } + +} +#endif /* NO_PTP_SUPPORT */ +/** + * ixgbe_parse_func_caps - Parse function capabilities + * @hw: pointer to the HW struct + * @func_p: pointer to function capabilities structure + * @buf: buffer containing the function capability records + * @cap_count: the number of capabilities + * + * Helper function to parse function (0x000A) capabilities list. For + * capabilities shared between device and function, this relies on + * ixgbe_parse_common_caps. + * + * Loop through the list of provided capabilities and extract the relevant + * data into the function capabilities structured. + */ +static void ixgbe_parse_func_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_func_caps *func_p, + void *buf, u32 cap_count) +{ + struct ixgbe_aci_cmd_list_caps_elem *cap_resp; + u32 i; + + cap_resp = (struct ixgbe_aci_cmd_list_caps_elem *)buf; + + memset(func_p, 0, sizeof(*func_p)); + + for (i = 0; i < cap_count; i++) { + u16 cap = IXGBE_LE16_TO_CPU(cap_resp[i].cap); + + ixgbe_parse_common_caps(hw, &func_p->common_cap, + &cap_resp[i], "func caps"); + + switch (cap) { + case IXGBE_ACI_CAPS_VSI: + ixgbe_parse_vsi_func_caps(hw, func_p, &cap_resp[i]); + break; +#ifndef NO_PTP_SUPPORT + case IXGBE_ACI_CAPS_1588: + ixgbe_parse_1588_func_caps(hw, func_p, &cap_resp[i]); + break; +#endif /* NO_PTP_SUPPORT */ + default: + /* Don't list common capabilities as unknown */ + break; + } + } + +} + +/** + * ixgbe_aci_list_caps - query function/device capabilities + * @hw: pointer to the HW struct + * @buf: a buffer to hold the capabilities + * @buf_size: size of the buffer + * @cap_count: if not NULL, set to the number of capabilities reported + * @opc: capabilities type to discover, device or function + * + * Get the function (0x000A) or device (0x000B) capabilities description from + * firmware and store it in the buffer. + * + * If the cap_count pointer is not NULL, then it is set to the number of + * capabilities firmware will report. Note that if the buffer size is too + * small, it is possible the command will return IXGBE_ERR_OUT_OF_MEM. The + * cap_count will still be updated in this case. It is recommended that the + * buffer size be set to IXGBE_ACI_MAX_BUFFER_SIZE (the largest possible + * buffer that firmware could return) to avoid this. + * + * Return: the exit code of the operation. + * Exit code of IXGBE_ERR_OUT_OF_MEM means the buffer size is too small. + */ +s32 ixgbe_aci_list_caps(struct ixgbe_hw *hw, void *buf, u16 buf_size, + u32 *cap_count, enum ixgbe_aci_opc opc) +{ + struct ixgbe_aci_cmd_list_caps *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.get_cap; + + if (opc != ixgbe_aci_opc_list_func_caps && + opc != ixgbe_aci_opc_list_dev_caps) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, opc); + status = ixgbe_aci_send_cmd(hw, &desc, buf, buf_size); + + if (cap_count) + *cap_count = IXGBE_LE32_TO_CPU(cmd->count); + + return status; +} + +/** + * ixgbe_discover_dev_caps - Read and extract device capabilities + * @hw: pointer to the hardware structure + * @dev_caps: pointer to device capabilities structure + * + * Read the device capabilities and extract them into the dev_caps structure + * for later use. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_discover_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_caps) +{ + u32 cap_count = 0; + u8 *cbuf = NULL; + s32 status; + + cbuf = (u8*)ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE); + if (!cbuf) + return IXGBE_ERR_OUT_OF_MEM; + /* Although the driver doesn't know the number of capabilities the + * device will return, we can simply send a 4KB buffer, the maximum + * possible size that firmware can return. + */ + cap_count = IXGBE_ACI_MAX_BUFFER_SIZE / + sizeof(struct ixgbe_aci_cmd_list_caps_elem); + + status = ixgbe_aci_list_caps(hw, cbuf, IXGBE_ACI_MAX_BUFFER_SIZE, + &cap_count, + ixgbe_aci_opc_list_dev_caps); + if (!status) + ixgbe_parse_dev_caps(hw, dev_caps, cbuf, cap_count); + + if (cbuf) + ixgbe_free(hw, cbuf); + + return status; +} + +/** + * ixgbe_discover_func_caps - Read and extract function capabilities + * @hw: pointer to the hardware structure + * @func_caps: pointer to function capabilities structure + * + * Read the function capabilities and extract them into the func_caps structure + * for later use. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_discover_func_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_func_caps *func_caps) +{ + u32 cap_count = 0; + u8 *cbuf = NULL; + s32 status; + + cbuf = (u8*)ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE); + if(!cbuf) + return IXGBE_ERR_OUT_OF_MEM; + /* Although the driver doesn't know the number of capabilities the + * device will return, we can simply send a 4KB buffer, the maximum + * possible size that firmware can return. + */ + cap_count = IXGBE_ACI_MAX_BUFFER_SIZE / + sizeof(struct ixgbe_aci_cmd_list_caps_elem); + + status = ixgbe_aci_list_caps(hw, cbuf, IXGBE_ACI_MAX_BUFFER_SIZE, + &cap_count, + ixgbe_aci_opc_list_func_caps); + if (!status) + ixgbe_parse_func_caps(hw, func_caps, cbuf, cap_count); + + if (cbuf) + ixgbe_free(hw, cbuf); + + return status; +} + +/** + * ixgbe_get_caps - get info about the HW + * @hw: pointer to the hardware structure + * + * Retrieve both device and function capabilities. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_caps(struct ixgbe_hw *hw) +{ + s32 status; + + status = ixgbe_discover_dev_caps(hw, &hw->dev_caps); + if (status) + return status; + + return ixgbe_discover_func_caps(hw, &hw->func_caps); +} + +/** + * ixgbe_aci_disable_rxen - disable RX + * @hw: pointer to the HW struct + * + * Request a safe disable of Receive Enable using ACI command (0x000C). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_disable_rxen(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_disable_rxen *cmd; + struct ixgbe_aci_desc desc; + + UNREFERENCED_1PARAMETER(hw); + + cmd = &desc.params.disable_rxen; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_disable_rxen); + + cmd->lport_num = (u8)hw->bus.func; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_get_phy_caps - returns PHY capabilities + * @hw: pointer to the HW struct + * @qual_mods: report qualified modules + * @report_mode: report mode capabilities + * @pcaps: structure for PHY capabilities to be filled + * + * Returns the various PHY capabilities supported on the Port + * using ACI command (0x0600). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_phy_caps(struct ixgbe_hw *hw, bool qual_mods, u8 report_mode, + struct ixgbe_aci_cmd_get_phy_caps_data *pcaps) +{ + struct ixgbe_aci_cmd_get_phy_caps *cmd; + u16 pcaps_size = sizeof(*pcaps); + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.get_phy; + + if (!pcaps || (report_mode & ~IXGBE_ACI_REPORT_MODE_M)) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_phy_caps); + + if (qual_mods) + cmd->param0 |= IXGBE_CPU_TO_LE16(IXGBE_ACI_GET_PHY_RQM); + + cmd->param0 |= IXGBE_CPU_TO_LE16(report_mode); + status = ixgbe_aci_send_cmd(hw, &desc, pcaps, pcaps_size); + + if (status == IXGBE_SUCCESS && + report_mode == IXGBE_ACI_REPORT_TOPO_CAP_MEDIA) { + hw->phy.phy_type_low = IXGBE_LE64_TO_CPU(pcaps->phy_type_low); + hw->phy.phy_type_high = IXGBE_LE64_TO_CPU(pcaps->phy_type_high); + memcpy(hw->link.link_info.module_type, &pcaps->module_type, + sizeof(hw->link.link_info.module_type)); + } + + return status; +} + +/** + * ixgbe_phy_caps_equals_cfg - check if capabilities match the PHY config + * @phy_caps: PHY capabilities + * @phy_cfg: PHY configuration + * + * Helper function to determine if PHY capabilities match PHY + * configuration + * + * Return: true if PHY capabilities match PHY configuration. + */ +bool +ixgbe_phy_caps_equals_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *phy_caps, + struct ixgbe_aci_cmd_set_phy_cfg_data *phy_cfg) +{ + u8 caps_mask, cfg_mask; + + if (!phy_caps || !phy_cfg) + return false; + + /* These bits are not common between capabilities and configuration. + * Do not use them to determine equality. + */ + caps_mask = IXGBE_ACI_PHY_CAPS_MASK & ~(IXGBE_ACI_PHY_AN_MODE | + IXGBE_ACI_PHY_EN_MOD_QUAL); + cfg_mask = IXGBE_ACI_PHY_ENA_VALID_MASK & + ~IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT; + + if (phy_caps->phy_type_low != phy_cfg->phy_type_low || + phy_caps->phy_type_high != phy_cfg->phy_type_high || + ((phy_caps->caps & caps_mask) != (phy_cfg->caps & cfg_mask)) || + phy_caps->low_power_ctrl_an != phy_cfg->low_power_ctrl_an || + phy_caps->eee_cap != phy_cfg->eee_cap || + phy_caps->eeer_value != phy_cfg->eeer_value || + phy_caps->link_fec_options != phy_cfg->link_fec_opt) + return false; + + return true; +} + +/** + * ixgbe_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data + * @caps: PHY ability structure to copy data from + * @cfg: PHY configuration structure to copy data to + * + * Helper function to copy data from PHY capabilities data structure + * to PHY configuration data structure + */ +void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg) +{ + if (!caps || !cfg) + return; + + memset(cfg, 0, sizeof(*cfg)); + cfg->phy_type_low = caps->phy_type_low; + cfg->phy_type_high = caps->phy_type_high; + cfg->caps = caps->caps; + cfg->low_power_ctrl_an = caps->low_power_ctrl_an; + cfg->eee_cap = caps->eee_cap; + cfg->eeer_value = caps->eeer_value; + cfg->link_fec_opt = caps->link_fec_options; + cfg->module_compliance_enforcement = + caps->module_compliance_enforcement; + cfg->eee_entry_delay = caps->eee_entry_delay; +} + +/** + * ixgbe_aci_set_phy_cfg - set PHY configuration + * @hw: pointer to the HW struct + * @cfg: structure with PHY configuration data to be set + * + * Set the various PHY configuration parameters supported on the Port + * using ACI command (0x0601). + * One or more of the Set PHY config parameters may be ignored in an MFP + * mode as the PF may not have the privilege to set some of the PHY Config + * parameters. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg) +{ + struct ixgbe_aci_desc desc; + bool use_1p40_buff; + s32 status; + + if (!cfg) + return IXGBE_ERR_PARAM; + use_1p40_buff = hw->dev_caps.common_cap.eee_support ? true : false; + + /* Ensure that only valid bits of cfg->caps can be turned on. */ + if (cfg->caps & ~IXGBE_ACI_PHY_ENA_VALID_MASK) { + cfg->caps &= IXGBE_ACI_PHY_ENA_VALID_MASK; + } + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_phy_cfg); + desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + + if (use_1p40_buff) { + status = ixgbe_aci_send_cmd(hw, &desc, cfg, sizeof(*cfg)); + } else { + struct ixgbe_aci_cmd_set_phy_cfg_data_pre_1_40 cfg_obsolete; + + memcpy(&cfg_obsolete, cfg, sizeof(cfg_obsolete)); + + status = ixgbe_aci_send_cmd(hw, &desc, &cfg_obsolete, + sizeof(cfg_obsolete)); + } + + /* even if the old buffer is used no need to worry about conversion */ + if (!status) + hw->phy.curr_user_phy_cfg = *cfg; + + return status; +} + +/** + * ixgbe_aci_set_link_restart_an - set up link and restart AN + * @hw: pointer to the HW struct + * @ena_link: if true: enable link, if false: disable link + * + * Function sets up the link and restarts the Auto-Negotiation over the link. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_link_restart_an(struct ixgbe_hw *hw, bool ena_link) +{ + struct ixgbe_aci_cmd_restart_an *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.restart_an; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_restart_an); + + cmd->cmd_flags = IXGBE_ACI_RESTART_AN_LINK_RESTART; + if (ena_link) + cmd->cmd_flags |= IXGBE_ACI_RESTART_AN_LINK_ENABLE; + else + cmd->cmd_flags &= ~IXGBE_ACI_RESTART_AN_LINK_ENABLE; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_is_media_cage_present - check if media cage is present + * @hw: pointer to the HW struct + * + * Identify presence of media cage using the ACI command (0x06E0). + * + * Return: true if media cage is present, else false. If no cage, then + * media type is backplane or BASE-T. + */ +static bool ixgbe_is_media_cage_present(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_link_topo *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.get_link_topo; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo); + + cmd->addr.topo_params.node_type_ctx = + (IXGBE_ACI_LINK_TOPO_NODE_CTX_PORT << + IXGBE_ACI_LINK_TOPO_NODE_CTX_S); + + /* set node type */ + cmd->addr.topo_params.node_type_ctx |= + (IXGBE_ACI_LINK_TOPO_NODE_TYPE_M & + IXGBE_ACI_LINK_TOPO_NODE_TYPE_CAGE); + + /* Node type cage can be used to determine if cage is present. If AQC + * returns error (ENOENT), then no cage present. If no cage present then + * connection type is backplane or BASE-T. + */ + return ixgbe_aci_get_netlist_node(hw, cmd, NULL, NULL); +} + +/** + * ixgbe_get_media_type_from_phy_type - Gets media type based on phy type + * @hw: pointer to the HW struct + * + * Try to identify the media type based on the phy type. + * If more than one media type, the ixgbe_media_type_unknown is returned. + * First, phy_type_low is checked, then phy_type_high. + * If none are identified, the ixgbe_media_type_unknown is returned + * + * Return: type of a media based on phy type in form of enum. + */ +static enum ixgbe_media_type +ixgbe_get_media_type_from_phy_type(struct ixgbe_hw *hw) +{ + struct ixgbe_link_status *hw_link_info; + + if (!hw) + return ixgbe_media_type_unknown; + + hw_link_info = &hw->link.link_info; + if (hw_link_info->phy_type_low && hw_link_info->phy_type_high) + /* If more than one media type is selected, report unknown */ + return ixgbe_media_type_unknown; + + if (hw_link_info->phy_type_low) { + /* 1G SGMII is a special case where some DA cable PHYs + * may show this as an option when it really shouldn't + * be since SGMII is meant to be between a MAC and a PHY + * in a backplane. Try to detect this case and handle it + */ + if (hw_link_info->phy_type_low == IXGBE_PHY_TYPE_LOW_1G_SGMII && + (hw_link_info->module_type[IXGBE_ACI_MOD_TYPE_IDENT] == + IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE || + hw_link_info->module_type[IXGBE_ACI_MOD_TYPE_IDENT] == + IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE)) + return ixgbe_media_type_da; + + switch (hw_link_info->phy_type_low) { + case IXGBE_PHY_TYPE_LOW_1000BASE_SX: + case IXGBE_PHY_TYPE_LOW_1000BASE_LX: + case IXGBE_PHY_TYPE_LOW_10GBASE_SR: + case IXGBE_PHY_TYPE_LOW_10GBASE_LR: + case IXGBE_PHY_TYPE_LOW_25GBASE_SR: + case IXGBE_PHY_TYPE_LOW_25GBASE_LR: + return ixgbe_media_type_fiber; + case IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC: + case IXGBE_PHY_TYPE_LOW_25G_AUI_AOC_ACC: + return ixgbe_media_type_fiber; + case IXGBE_PHY_TYPE_LOW_100BASE_TX: + case IXGBE_PHY_TYPE_LOW_1000BASE_T: + case IXGBE_PHY_TYPE_LOW_2500BASE_T: + case IXGBE_PHY_TYPE_LOW_5GBASE_T: + case IXGBE_PHY_TYPE_LOW_10GBASE_T: + case IXGBE_PHY_TYPE_LOW_25GBASE_T: + return ixgbe_media_type_copper; + case IXGBE_PHY_TYPE_LOW_10G_SFI_DA: + case IXGBE_PHY_TYPE_LOW_25GBASE_CR: + case IXGBE_PHY_TYPE_LOW_25GBASE_CR_S: + case IXGBE_PHY_TYPE_LOW_25GBASE_CR1: + return ixgbe_media_type_da; + case IXGBE_PHY_TYPE_LOW_25G_AUI_C2C: + if (ixgbe_is_media_cage_present(hw)) + return ixgbe_media_type_aui; + fallthrough; + case IXGBE_PHY_TYPE_LOW_1000BASE_KX: + case IXGBE_PHY_TYPE_LOW_2500BASE_KX: + case IXGBE_PHY_TYPE_LOW_2500BASE_X: + case IXGBE_PHY_TYPE_LOW_5GBASE_KR: + case IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1: + case IXGBE_PHY_TYPE_LOW_10G_SFI_C2C: + case IXGBE_PHY_TYPE_LOW_25GBASE_KR: + case IXGBE_PHY_TYPE_LOW_25GBASE_KR1: + case IXGBE_PHY_TYPE_LOW_25GBASE_KR_S: + return ixgbe_media_type_backplane; + } + } else { + switch (hw_link_info->phy_type_high) { + case IXGBE_PHY_TYPE_HIGH_10BASE_T: + return ixgbe_media_type_copper; + } + } + return ixgbe_media_type_unknown; +} + +/** + * ixgbe_update_link_info - update status of the HW network link + * @hw: pointer to the HW struct + * + * Update the status of the HW network link. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_update_link_info(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_phy_caps_data *pcaps; + struct ixgbe_link_status *li; + s32 status; + + if (!hw) + return IXGBE_ERR_PARAM; + + li = &hw->link.link_info; + + status = ixgbe_aci_get_link_info(hw, true, NULL); + if (status) + return status; + + if (li->link_info & IXGBE_ACI_MEDIA_AVAILABLE) { + pcaps = (struct ixgbe_aci_cmd_get_phy_caps_data *) + ixgbe_malloc(hw, sizeof(*pcaps)); + if (!pcaps) + return IXGBE_ERR_OUT_OF_MEM; + + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_TOPO_CAP_MEDIA, + pcaps); + + if (status == IXGBE_SUCCESS) + memcpy(li->module_type, &pcaps->module_type, + sizeof(li->module_type)); + + ixgbe_free(hw, pcaps); + } + + return status; +} + +/** + * ixgbe_get_link_status - get status of the HW network link + * @hw: pointer to the HW struct + * @link_up: pointer to bool (true/false = linkup/linkdown) + * + * Variable link_up is true if link is up, false if link is down. + * The variable link_up is invalid if status is non zero. As a + * result of this call, link status reporting becomes enabled + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_link_status(struct ixgbe_hw *hw, bool *link_up) +{ + s32 status = IXGBE_SUCCESS; + + if (!hw || !link_up) + return IXGBE_ERR_PARAM; + + if (hw->link.get_link_info) { + status = ixgbe_update_link_info(hw); + if (status) { + return status; + } + } + + *link_up = hw->link.link_info.link_info & IXGBE_ACI_LINK_UP; + + return status; +} + +/** + * ixgbe_aci_get_link_info - get the link status + * @hw: pointer to the HW struct + * @ena_lse: enable/disable LinkStatusEvent reporting + * @link: pointer to link status structure - optional + * + * Get the current Link Status using ACI command (0x607). + * The current link can be optionally provided to update + * the status. + * + * Return: the link status of the adapter. + */ +s32 ixgbe_aci_get_link_info(struct ixgbe_hw *hw, bool ena_lse, + struct ixgbe_link_status *link) +{ + struct ixgbe_aci_cmd_get_link_status_data link_data = { 0 }; + struct ixgbe_aci_cmd_get_link_status *resp; + struct ixgbe_link_status *li_old, *li; + struct ixgbe_fc_info *hw_fc_info; + struct ixgbe_aci_desc desc; + bool tx_pause, rx_pause; + u8 cmd_flags; + s32 status; + + if (!hw) + return IXGBE_ERR_PARAM; + + li_old = &hw->link.link_info_old; + li = &hw->link.link_info; + hw_fc_info = &hw->fc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_status); + cmd_flags = (ena_lse) ? IXGBE_ACI_LSE_ENA : IXGBE_ACI_LSE_DIS; + resp = &desc.params.get_link_status; + resp->cmd_flags = cmd_flags; + + status = ixgbe_aci_send_cmd(hw, &desc, &link_data, sizeof(link_data)); + + if (status != IXGBE_SUCCESS) + return status; + + /* save off old link status information */ + *li_old = *li; + + /* update current link status information */ + li->link_speed = IXGBE_LE16_TO_CPU(link_data.link_speed); + li->phy_type_low = IXGBE_LE64_TO_CPU(link_data.phy_type_low); + li->phy_type_high = IXGBE_LE64_TO_CPU(link_data.phy_type_high); + li->link_info = link_data.link_info; + li->link_cfg_err = link_data.link_cfg_err; + li->an_info = link_data.an_info; + li->ext_info = link_data.ext_info; + li->max_frame_size = IXGBE_LE16_TO_CPU(link_data.max_frame_size); + li->fec_info = link_data.cfg & IXGBE_ACI_FEC_MASK; + li->topo_media_conflict = link_data.topo_media_conflict; + li->pacing = link_data.cfg & (IXGBE_ACI_CFG_PACING_M | + IXGBE_ACI_CFG_PACING_TYPE_M); + li->eee_status = link_data.eee_status; + + /* update fc info */ + tx_pause = !!(link_data.an_info & IXGBE_ACI_LINK_PAUSE_TX); + rx_pause = !!(link_data.an_info & IXGBE_ACI_LINK_PAUSE_RX); + if (tx_pause && rx_pause) + hw_fc_info->current_mode = ixgbe_fc_full; + else if (tx_pause) + hw_fc_info->current_mode = ixgbe_fc_tx_pause; + else if (rx_pause) + hw_fc_info->current_mode = ixgbe_fc_rx_pause; + else + hw_fc_info->current_mode = ixgbe_fc_none; + + li->lse_ena = !!(resp->cmd_flags & IXGBE_ACI_LSE_IS_ENABLED); + + /* save link status information */ + if (link) + *link = *li; + + /* flag cleared so calling functions don't call AQ again */ + hw->link.get_link_info = false; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_aci_set_event_mask - set event mask + * @hw: pointer to the HW struct + * @port_num: port number of the physical function + * @mask: event mask to be set + * + * Set the event mask using ACI command (0x0613). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_event_mask(struct ixgbe_hw *hw, u8 port_num, u16 mask) +{ + struct ixgbe_aci_cmd_set_event_mask *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.set_event_mask; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_event_mask); + + cmd->event_mask = IXGBE_CPU_TO_LE16(mask); + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_configure_lse - enable/disable link status events + * @hw: pointer to the HW struct + * @activate: bool value deciding if lse should be enabled nor disabled + * @mask: event mask to be set; a set bit means deactivation of the + * corresponding event + * + * Set the event mask and then enable or disable link status events + * + * Return: the exit code of the operation. + */ +s32 ixgbe_configure_lse(struct ixgbe_hw *hw, bool activate, u16 mask) +{ + s32 rc; + + rc = ixgbe_aci_set_event_mask(hw, (u8)hw->bus.func, mask); + if (rc) { + return rc; + } + + /* Enabling link status events generation by fw */ + rc = ixgbe_aci_get_link_info(hw, activate, NULL); + if (rc) { + return rc; + } + return IXGBE_SUCCESS; +} + +#ifndef NO_PTP_SUPPORT +/** + * ixgbe_set_ptp_by_phy - Set PTP timestamping by PHY + * @hw: pointer to the HW struct + * @ptp_request: timestamp mode request + * @flags: timestamp mode flags + * + * Set PTP by PHY using ACI command (0x0634). + * + * Return: 0 on success, negative error code otherwise + */ +s32 ixgbe_set_ptp_by_phy(struct ixgbe_hw *hw, u8 ptp_request, u8 flags) +{ + struct ixgbe_aci_cmd_set_ptp_by_phy *cmd; + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_ptp_by_phy); + cmd = &desc.params.set_ptp_by_phy; + cmd->ptp_request = ptp_request; + cmd->flags = flags; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_get_ptp_by_phy - Get PTP timestamping by PHY + * @hw: pointer to the HW struct + * @ptp_config: timestamp mode config + * @flags: timestamp mode flags + * @max_drift_thresh: maximal PHY clock drift threshold + * + * Get PTP by PHY using ACI command (0x0635). + * + * Return: 0 on success, negative error code otherwise + */ +s32 ixgbe_get_ptp_by_phy(struct ixgbe_hw *hw, u8 *ptp_config, u8 *flags, + u16 *max_drift_thresh) +{ + struct ixgbe_aci_cmd_get_ptp_by_phy_resp *resp; + struct ixgbe_aci_desc desc; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_ptp_by_phy); + resp = &desc.params.get_ptp_by_phy_resp; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (!status) { + *ptp_config = resp->ptp_config; + *flags = resp->flags; + *max_drift_thresh = IXGBE_LE16_TO_CPU(resp->maxDriftThreshold); + } + + return status; +} + +#endif /* !NO_PTP_SUPPORT */ +/** + * ixgbe_aci_get_netlist_node - get a node handle + * @hw: pointer to the hw struct + * @cmd: get_link_topo AQ structure + * @node_part_number: output node part number if node found + * @node_handle: output node handle parameter if node found + * + * Get the netlist node and assigns it to + * the provided handle using ACI command (0x06E0). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo *cmd, + u8 *node_part_number, u16 *node_handle) +{ + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo); + desc.params.get_link_topo = *cmd; + + if (ixgbe_aci_send_cmd(hw, &desc, NULL, 0)) + return IXGBE_ERR_NOT_SUPPORTED; + + if (node_handle) + *node_handle = + IXGBE_LE16_TO_CPU(desc.params.get_link_topo.addr.handle); + if (node_part_number) + *node_part_number = desc.params.get_link_topo.node_part_num; + + return IXGBE_SUCCESS; +} + +#if !defined(NO_PTP_SUPPORT) +/** + * ixgbe_aci_get_netlist_node_pin - get a node pin handle + * @hw: pointer to the hw struct + * @cmd: get_link_topo_pin AQ structure + * @node_handle: output node handle parameter if node found + * + * Get the netlist node pin and assign it to + * the provided handle using ACI command (0x06E1). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_netlist_node_pin(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo_pin *cmd, + u16 *node_handle) +{ + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo_pin); + desc.params.get_link_topo_pin = *cmd; + + if (ixgbe_aci_send_cmd(hw, &desc, NULL, 0)) + return IXGBE_ERR_NOT_SUPPORTED; + + if (node_handle) + *node_handle = + IXGBE_LE16_TO_CPU(desc.params.get_link_topo_pin.addr.handle); + + return IXGBE_SUCCESS; +} +#endif /* !NO_PTP_SUPPORT */ + +/** + * ixgbe_find_netlist_node - find a node handle + * @hw: pointer to the hw struct + * @node_type_ctx: type of netlist node to look for + * @node_part_number: node part number to look for + * @node_handle: output parameter if node found - optional + * + * Find and return the node handle for a given node type and part number in the + * netlist. When found IXGBE_SUCCESS is returned, IXGBE_ERR_NOT_SUPPORTED + * otherwise. If @node_handle provided, it would be set to found node handle. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_find_netlist_node(struct ixgbe_hw *hw, u8 node_type_ctx, + u8 node_part_number, u16 *node_handle) +{ + struct ixgbe_aci_cmd_get_link_topo cmd; + u8 rec_node_part_number; + u16 rec_node_handle; + s32 status; + u8 idx; + + for (idx = 0; idx < IXGBE_MAX_NETLIST_SIZE; idx++) { + memset(&cmd, 0, sizeof(cmd)); + + cmd.addr.topo_params.node_type_ctx = + (node_type_ctx << IXGBE_ACI_LINK_TOPO_NODE_TYPE_S); + cmd.addr.topo_params.index = idx; + + status = ixgbe_aci_get_netlist_node(hw, &cmd, + &rec_node_part_number, + &rec_node_handle); + if (status) + return status; + + if (rec_node_part_number == node_part_number) { + if (node_handle) + *node_handle = rec_node_handle; + return IXGBE_SUCCESS; + } + } + + return IXGBE_ERR_NOT_SUPPORTED; +} + +/** + * ixgbe_aci_read_i2c - read I2C register value + * @hw: pointer to the hw struct + * @topo_addr: topology address for a device to communicate with + * @bus_addr: 7-bit I2C bus address + * @addr: I2C memory address (I2C offset) with up to 16 bits + * @params: I2C parameters: bit [7] - Repeated start, + * bits [6:5] data offset size, + * bit [4] - I2C address type, bits [3:0] - data size + * to read (0-16 bytes) + * @data: pointer to data (0 to 16 bytes) to be read from the I2C device + * + * Read the value of the I2C pin register using ACI command (0x06E2). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_read_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data) +{ + struct ixgbe_aci_desc desc = { 0 }; + struct ixgbe_aci_cmd_i2c *cmd; + u8 data_size; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_i2c); + cmd = &desc.params.read_write_i2c; + + if (!data) + return IXGBE_ERR_PARAM; + + data_size = (params & IXGBE_ACI_I2C_DATA_SIZE_M) >> + IXGBE_ACI_I2C_DATA_SIZE_S; + + cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(bus_addr); + cmd->topo_addr = topo_addr; + cmd->i2c_params = params; + cmd->i2c_addr = addr; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (!status) { + struct ixgbe_aci_cmd_read_i2c_resp *resp; + u8 i; + + resp = &desc.params.read_i2c_resp; + for (i = 0; i < data_size; i++) { + *data = resp->i2c_data[i]; + data++; + } + } + + return status; +} + +/** + * ixgbe_aci_write_i2c - write a value to I2C register + * @hw: pointer to the hw struct + * @topo_addr: topology address for a device to communicate with + * @bus_addr: 7-bit I2C bus address + * @addr: I2C memory address (I2C offset) with up to 16 bits + * @params: I2C parameters: bit [4] - I2C address type, bits [3:0] - data size + * to write (0-7 bytes) + * @data: pointer to data (0 to 4 bytes) to be written to the I2C device + * + * Write a value to the I2C pin register using ACI command (0x06E3). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_write_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data) +{ + struct ixgbe_aci_desc desc = { 0 }; + struct ixgbe_aci_cmd_i2c *cmd; + u8 i, data_size; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_write_i2c); + cmd = &desc.params.read_write_i2c; + + data_size = (params & IXGBE_ACI_I2C_DATA_SIZE_M) >> + IXGBE_ACI_I2C_DATA_SIZE_S; + + /* data_size limited to 4 */ + if (data_size > 4) + return IXGBE_ERR_PARAM; + + cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(bus_addr); + cmd->topo_addr = topo_addr; + cmd->i2c_params = params; + cmd->i2c_addr = addr; + + for (i = 0; i < data_size; i++) { + cmd->i2c_data[i] = *data; + data++; + } + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_set_port_id_led - set LED value for the given port + * @hw: pointer to the HW struct + * @orig_mode: set LED original mode + * + * Set LED value for the given port (0x06E9) + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_port_id_led(struct ixgbe_hw *hw, bool orig_mode) +{ + struct ixgbe_aci_cmd_set_port_id_led *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.set_port_id_led; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_port_id_led); + + cmd->lport_num = (u8)hw->bus.func; + cmd->lport_num_valid = IXGBE_ACI_PORT_ID_PORT_NUM_VALID; + + if (orig_mode) + cmd->ident_mode = IXGBE_ACI_PORT_IDENT_LED_ORIG; + else + cmd->ident_mode = IXGBE_ACI_PORT_IDENT_LED_BLINK; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_set_gpio - set GPIO pin state + * @hw: pointer to the hw struct + * @gpio_ctrl_handle: GPIO controller node handle + * @pin_idx: IO Number of the GPIO that needs to be set + * @value: SW provide IO value to set in the LSB + * + * Set the GPIO pin state that is a part of the topology + * using ACI command (0x06EC). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool value) +{ + struct ixgbe_aci_cmd_gpio *cmd; + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_gpio); + cmd = &desc.params.read_write_gpio; + cmd->gpio_ctrl_handle = IXGBE_CPU_TO_LE16(gpio_ctrl_handle); + cmd->gpio_num = pin_idx; + cmd->gpio_val = value ? 1 : 0; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_get_gpio - get GPIO pin state + * @hw: pointer to the hw struct + * @gpio_ctrl_handle: GPIO controller node handle + * @pin_idx: IO Number of the GPIO that needs to be set + * @value: IO value read + * + * Get the value of a GPIO signal which is part of the topology + * using ACI command (0x06ED). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool *value) +{ + struct ixgbe_aci_cmd_gpio *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_gpio); + cmd = &desc.params.read_write_gpio; + cmd->gpio_ctrl_handle = IXGBE_CPU_TO_LE16(gpio_ctrl_handle); + cmd->gpio_num = pin_idx; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (status) + return status; + + *value = !!cmd->gpio_val; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_aci_sff_eeprom - read/write SFF EEPROM + * @hw: pointer to the HW struct + * @lport: bits [7:0] = logical port, bit [8] = logical port valid + * @bus_addr: I2C bus address of the eeprom (typically 0xA0, 0=topo default) + * @mem_addr: I2C offset. lower 8 bits for address, 8 upper bits zero padding. + * @page: QSFP page + * @page_bank_ctrl: configuration of SFF/CMIS paging and banking control + * @data: pointer to data buffer to be read/written to the I2C device. + * @length: 1-16 for read, 1 for write. + * @write: 0 read, 1 for write. + * + * Read/write SFF EEPROM using ACI command (0x06EE). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr, + u16 mem_addr, u8 page, u8 page_bank_ctrl, u8 *data, + u8 length, bool write) +{ + struct ixgbe_aci_cmd_sff_eeprom *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + if (!data || (mem_addr & 0xff00)) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_sff_eeprom); + cmd = &desc.params.read_write_sff_param; + desc.flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + cmd->lport_num = (u8)(lport & 0xff); + cmd->lport_num_valid = (u8)((lport >> 8) & 0x01); + cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(((bus_addr >> 1) & + IXGBE_ACI_SFF_I2CBUS_7BIT_M) | + ((page_bank_ctrl << + IXGBE_ACI_SFF_PAGE_BANK_CTRL_S) & + IXGBE_ACI_SFF_PAGE_BANK_CTRL_M)); + cmd->i2c_offset = IXGBE_CPU_TO_LE16(mem_addr & 0xff); + cmd->module_page = page; + if (write) + cmd->i2c_bus_addr |= IXGBE_CPU_TO_LE16(IXGBE_ACI_SFF_IS_WRITE); + + status = ixgbe_aci_send_cmd(hw, &desc, data, length); + return status; +} + +/** + * ixgbe_aci_prog_topo_dev_nvm - program Topology Device NVM + * @hw: pointer to the hardware structure + * @topo_params: pointer to structure storing topology parameters for a device + * + * Program Topology Device NVM using ACI command (0x06F2). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_prog_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params) +{ + struct ixgbe_aci_cmd_prog_topo_dev_nvm *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.prog_topo_dev_nvm; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_prog_topo_dev_nvm); + + memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params)); + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_read_topo_dev_nvm - read Topology Device NVM + * @hw: pointer to the hardware structure + * @topo_params: pointer to structure storing topology parameters for a device + * @start_address: byte offset in the topology device NVM + * @data: pointer to data buffer + * @data_size: number of bytes to be read from the topology device NVM + * Read Topology Device NVM (0x06F3) + * + * Read Topology of Device NVM using ACI command (0x06F3). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_read_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params, + u32 start_address, u8 *data, u8 data_size) +{ + struct ixgbe_aci_cmd_read_topo_dev_nvm *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + if (!data || data_size == 0 || + data_size > IXGBE_ACI_READ_TOPO_DEV_NVM_DATA_READ_SIZE) + return IXGBE_ERR_PARAM; + + cmd = &desc.params.read_topo_dev_nvm; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_topo_dev_nvm); + + desc.datalen = IXGBE_CPU_TO_LE16(data_size); + memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params)); + cmd->start_address = IXGBE_CPU_TO_LE32(start_address); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (status) + return status; + + memcpy(data, cmd->data_read, data_size); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_acquire_nvm - Generic request for acquiring the NVM ownership + * @hw: pointer to the HW structure + * @access: NVM access type (read or write) + * + * Request NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_acquire_nvm(struct ixgbe_hw *hw, + enum ixgbe_aci_res_access_type access) +{ + u32 fla; + + /* Skip if we are in blank NVM programming mode */ + fla = IXGBE_READ_REG(hw, GLNVM_FLA); + if ((fla & GLNVM_FLA_LOCKED_M) == 0) + return IXGBE_SUCCESS; + + return ixgbe_acquire_res(hw, IXGBE_NVM_RES_ID, access, + IXGBE_NVM_TIMEOUT); +} + +/** + * ixgbe_release_nvm - Generic request for releasing the NVM ownership + * @hw: pointer to the HW structure + * + * Release NVM ownership. + */ +void ixgbe_release_nvm(struct ixgbe_hw *hw) +{ + u32 fla; + + /* Skip if we are in blank NVM programming mode */ + fla = IXGBE_READ_REG(hw, GLNVM_FLA); + if ((fla & GLNVM_FLA_LOCKED_M) == 0) + return; + + ixgbe_release_res(hw, IXGBE_NVM_RES_ID); +} + + +/** + * ixgbe_aci_read_nvm - read NVM + * @hw: pointer to the HW struct + * @module_typeid: module pointer location in words from the NVM beginning + * @offset: byte offset from the module beginning + * @length: length of the section to be read (in bytes from the offset) + * @data: command buffer (size [bytes] = length) + * @last_command: tells if this is the last command in a series + * @read_shadow_ram: tell if this is a shadow RAM read + * + * Read the NVM using ACI command (0x0701). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_read_nvm(struct ixgbe_hw *hw, u16 module_typeid, u32 offset, + u16 length, void *data, bool last_command, + bool read_shadow_ram) +{ + struct ixgbe_aci_desc desc; + struct ixgbe_aci_cmd_nvm *cmd; + + cmd = &desc.params.nvm; + + if (offset > IXGBE_ACI_NVM_MAX_OFFSET) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_read); + + if (!read_shadow_ram && module_typeid == IXGBE_ACI_NVM_START_POINT) + cmd->cmd_flags |= IXGBE_ACI_NVM_FLASH_ONLY; + + /* If this is the last command in a series, set the proper flag. */ + if (last_command) + cmd->cmd_flags |= IXGBE_ACI_NVM_LAST_CMD; + cmd->module_typeid = IXGBE_CPU_TO_LE16(module_typeid); + cmd->offset_low = IXGBE_CPU_TO_LE16(offset & 0xFFFF); + cmd->offset_high = (offset >> 16) & 0xFF; + cmd->length = IXGBE_CPU_TO_LE16(length); + + return ixgbe_aci_send_cmd(hw, &desc, data, length); +} + +/** + * ixgbe_aci_erase_nvm - erase NVM sector + * @hw: pointer to the HW struct + * @module_typeid: module pointer location in words from the NVM beginning + * + * Erase the NVM sector using the ACI command (0x0702). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_erase_nvm(struct ixgbe_hw *hw, u16 module_typeid) +{ + struct ixgbe_aci_desc desc; + struct ixgbe_aci_cmd_nvm *cmd; + s32 status; + __le16 len; + + /* read a length value from SR, so module_typeid is equal to 0 */ + /* calculate offset where module size is placed from bytes to words */ + /* set last command and read from SR values to true */ + status = ixgbe_aci_read_nvm(hw, 0, 2 * module_typeid + 2, 2, &len, true, + true); + if (status) + return status; + + cmd = &desc.params.nvm; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_erase); + + cmd->module_typeid = IXGBE_CPU_TO_LE16(module_typeid); + cmd->length = len; + cmd->offset_low = 0; + cmd->offset_high = 0; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_update_nvm - update NVM + * @hw: pointer to the HW struct + * @module_typeid: module pointer location in words from the NVM beginning + * @offset: byte offset from the module beginning + * @length: length of the section to be written (in bytes from the offset) + * @data: command buffer (size [bytes] = length) + * @last_command: tells if this is the last command in a series + * @command_flags: command parameters + * + * Update the NVM using the ACI command (0x0703). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_update_nvm(struct ixgbe_hw *hw, u16 module_typeid, + u32 offset, u16 length, void *data, + bool last_command, u8 command_flags) +{ + struct ixgbe_aci_desc desc; + struct ixgbe_aci_cmd_nvm *cmd; + + cmd = &desc.params.nvm; + + /* In offset the highest byte must be zeroed. */ + if (offset & 0xFF000000) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_write); + + cmd->cmd_flags |= command_flags; + + /* If this is the last command in a series, set the proper flag. */ + if (last_command) + cmd->cmd_flags |= IXGBE_ACI_NVM_LAST_CMD; + cmd->module_typeid = IXGBE_CPU_TO_LE16(module_typeid); + cmd->offset_low = IXGBE_CPU_TO_LE16(offset & 0xFFFF); + cmd->offset_high = (offset >> 16) & 0xFF; + cmd->length = IXGBE_CPU_TO_LE16(length); + + desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + + return ixgbe_aci_send_cmd(hw, &desc, data, length); +} + +/** + * ixgbe_nvm_validate_checksum - validate checksum + * @hw: pointer to the HW struct + * + * Verify NVM PFA checksum validity using ACI command (0x0706). + * If the checksum verification failed, IXGBE_ERR_NVM_CHECKSUM is returned. + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_nvm_checksum *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + cmd = &desc.params.nvm_checksum; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_checksum); + cmd->flags = IXGBE_ACI_NVM_CHECKSUM_VERIFY; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + ixgbe_release_nvm(hw); + + if (!status) + if (IXGBE_LE16_TO_CPU(cmd->checksum) != + IXGBE_ACI_NVM_CHECKSUM_CORRECT) { + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "Invalid Shadow Ram checksum"); + status = IXGBE_ERR_NVM_CHECKSUM; + } + + return status; +} + +/** + * ixgbe_nvm_recalculate_checksum - recalculate checksum + * @hw: pointer to the HW struct + * + * Recalculate NVM PFA checksum using ACI command (0x0706). + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_nvm_recalculate_checksum(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_nvm_checksum *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); + if (status) + return status; + + cmd = &desc.params.nvm_checksum; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_checksum); + cmd->flags = IXGBE_ACI_NVM_CHECKSUM_RECALC; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_nvm_write_activate - NVM activate write + * @hw: pointer to the HW struct + * @cmd_flags: flags for write activate command + * @response_flags: response indicators from firmware + * + * Update the control word with the required banks' validity bits + * and dumps the Shadow RAM to flash using ACI command (0x0707). + * + * cmd_flags controls which banks to activate, the preservation level to use + * when activating the NVM bank, and whether an EMP reset is required for + * activation. + * + * Note that the 16bit cmd_flags value is split between two separate 1 byte + * flag values in the descriptor. + * + * On successful return of the firmware command, the response_flags variable + * is updated with the flags reported by firmware indicating certain status, + * such as whether EMP reset is enabled. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_nvm_write_activate(struct ixgbe_hw *hw, u16 cmd_flags, + u8 *response_flags) +{ + struct ixgbe_aci_desc desc; + struct ixgbe_aci_cmd_nvm *cmd; + s32 status; + + cmd = &desc.params.nvm; + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_nvm_write_activate); + + cmd->cmd_flags = LO_BYTE(cmd_flags); + cmd->offset_high = HI_BYTE(cmd_flags); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (!status && response_flags) + *response_flags = cmd->cmd_flags; + + return status; +} + +/** + * ixgbe_get_flash_bank_offset - Get offset into requested flash bank + * @hw: pointer to the HW structure + * @bank: whether to read from the active or inactive flash bank + * @module: the module to read from + * + * Based on the module, lookup the module offset from the beginning of the + * flash. + * + * Return: the flash offset. Note that a value of zero is invalid and must be + * treated as an error. + */ +static u32 ixgbe_get_flash_bank_offset(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u16 module) +{ + struct ixgbe_bank_info *banks = &hw->flash.banks; + enum ixgbe_flash_bank active_bank; + bool second_bank_active; + u32 offset, size; + + switch (module) { + case E610_SR_1ST_NVM_BANK_PTR: + offset = banks->nvm_ptr; + size = banks->nvm_size; + active_bank = banks->nvm_bank; + break; + case E610_SR_1ST_OROM_BANK_PTR: + offset = banks->orom_ptr; + size = banks->orom_size; + active_bank = banks->orom_bank; + break; + case E610_SR_NETLIST_BANK_PTR: + offset = banks->netlist_ptr; + size = banks->netlist_size; + active_bank = banks->netlist_bank; + break; + default: + return 0; + } + + switch (active_bank) { + case IXGBE_1ST_FLASH_BANK: + second_bank_active = false; + break; + case IXGBE_2ND_FLASH_BANK: + second_bank_active = true; + break; + default: + return 0; + } + + /* The second flash bank is stored immediately following the first + * bank. Based on whether the 1st or 2nd bank is active, and whether + * we want the active or inactive bank, calculate the desired offset. + */ + switch (bank) { + case IXGBE_ACTIVE_FLASH_BANK: + return offset + (second_bank_active ? size : 0); + case IXGBE_INACTIVE_FLASH_BANK: + return offset + (second_bank_active ? 0 : size); + } + + return 0; +} + +/** + * ixgbe_read_flash_module - Read a word from one of the main NVM modules + * @hw: pointer to the HW structure + * @bank: which bank of the module to read + * @module: the module to read + * @offset: the offset into the module in bytes + * @data: storage for the word read from the flash + * @length: bytes of data to read + * + * Read data from the specified flash module. The bank parameter indicates + * whether or not to read from the active bank or the inactive bank of that + * module. + * + * The word will be read using flat NVM access, and relies on the + * hw->flash.banks data being setup by ixgbe_determine_active_flash_banks() + * during initialization. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_flash_module(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u16 module, u32 offset, u8 *data, u32 length) +{ + s32 status; + u32 start; + + start = ixgbe_get_flash_bank_offset(hw, bank, module); + if (!start) { + return IXGBE_ERR_PARAM; + } + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + status = ixgbe_read_flat_nvm(hw, start + offset, &length, data, false); + + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_read_netlist_module - Read data from the netlist module area + * @hw: pointer to the HW structure + * @bank: whether to read from the active or inactive module + * @offset: offset into the netlist to read from + * @data: storage for returned word value + * + * Read a word from the specified netlist bank. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_netlist_module(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u32 offset, u16 *data) +{ + __le16 data_local; + s32 status; + + status = ixgbe_read_flash_module(hw, bank, E610_SR_NETLIST_BANK_PTR, + offset * sizeof(u16), + (u8 *)&data_local, + sizeof(u16)); + if (!status) + *data = IXGBE_LE16_TO_CPU(data_local); + + return status; +} + +/** + * ixgbe_read_nvm_module - Read from the active main NVM module + * @hw: pointer to the HW structure + * @bank: whether to read from active or inactive NVM module + * @offset: offset into the NVM module to read, in words + * @data: storage for returned word value + * + * Read the specified word from the active NVM module. This includes the CSS + * header at the start of the NVM module. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_nvm_module(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u32 offset, u16 *data) +{ + __le16 data_local; + s32 status; + + status = ixgbe_read_flash_module(hw, bank, E610_SR_1ST_NVM_BANK_PTR, + offset * sizeof(u16), + (u8 *)&data_local, + sizeof(u16)); + if (!status) + *data = IXGBE_LE16_TO_CPU(data_local); + + return status; +} + +/** + * ixgbe_read_orom_module - Read from the active Option ROM module + * @hw: pointer to the HW structure + * @bank: whether to read from active or inactive OROM module + * @offset: offset into the OROM module to read, in words + * @data: storage for returned word value + * + * Read the specified word from the active Option ROM module of the flash. + * Note that unlike the NVM module, the CSS data is stored at the end of the + * module instead of at the beginning. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_orom_module(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u32 offset, u16 *data) +{ + __le16 data_local; + s32 status; + + status = ixgbe_read_flash_module(hw, bank, E610_SR_1ST_OROM_BANK_PTR, + offset * sizeof(u16), + (u8 *)&data_local, + sizeof(u16)); + if (!status) + *data = IXGBE_LE16_TO_CPU(data_local); + + return status; +} + +/** + * ixgbe_get_nvm_css_hdr_len - Read the CSS header length from the + * NVM CSS header + * @hw: pointer to the HW struct + * @bank: whether to read from the active or inactive flash bank + * @hdr_len: storage for header length in words + * + * Read the CSS header length from the NVM CSS header and add the + * Authentication header size, and then convert to words. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_get_nvm_css_hdr_len(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u32 *hdr_len) +{ + u16 hdr_len_l, hdr_len_h; + u32 hdr_len_dword; + s32 status; + + status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_HDR_LEN_L, + &hdr_len_l); + if (status) + return status; + + status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_HDR_LEN_H, + &hdr_len_h); + if (status) + return status; + + /* CSS header length is in DWORD, so convert to words and add + * authentication header size + */ + hdr_len_dword = hdr_len_h << 16 | hdr_len_l; + *hdr_len = (hdr_len_dword * 2) + IXGBE_NVM_AUTH_HEADER_LEN; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank + * @hw: pointer to the HW structure + * @bank: whether to read from the active or inactive NVM module + * @offset: offset into the Shadow RAM copy to read, in words + * @data: storage for returned word value + * + * Read the specified word from the copy of the Shadow RAM found in the + * specified NVM module. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_nvm_sr_copy(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u32 offset, u16 *data) +{ + u32 hdr_len; + s32 status; + + status = ixgbe_get_nvm_css_hdr_len(hw, bank, &hdr_len); + if (status) + return status; + + hdr_len = ROUND_UP(hdr_len, 32); + + return ixgbe_read_nvm_module(hw, bank, hdr_len + offset, data); +} + +/** + * ixgbe_get_nvm_minsrevs - Get the minsrevs values from flash + * @hw: pointer to the HW struct + * @minsrevs: structure to store NVM and OROM minsrev values + * + * Read the Minimum Security Revision TLV and extract + * the revision values from the flash image + * into a readable structure for processing. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_nvm_minsrevs(struct ixgbe_hw *hw, + struct ixgbe_minsrev_info *minsrevs) +{ + struct ixgbe_aci_cmd_nvm_minsrev data; + s32 status; + u16 valid; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + status = ixgbe_aci_read_nvm(hw, IXGBE_ACI_NVM_MINSREV_MOD_ID, + 0, sizeof(data), &data, + true, false); + + ixgbe_release_nvm(hw); + + if (status) + return status; + + valid = IXGBE_LE16_TO_CPU(data.validity); + + /* Extract NVM minimum security revision */ + if (valid & IXGBE_ACI_NVM_MINSREV_NVM_VALID) { + u16 minsrev_l = IXGBE_LE16_TO_CPU(data.nvm_minsrev_l); + u16 minsrev_h = IXGBE_LE16_TO_CPU(data.nvm_minsrev_h); + + minsrevs->nvm = minsrev_h << 16 | minsrev_l; + minsrevs->nvm_valid = true; + } + + /* Extract the OROM minimum security revision */ + if (valid & IXGBE_ACI_NVM_MINSREV_OROM_VALID) { + u16 minsrev_l = IXGBE_LE16_TO_CPU(data.orom_minsrev_l); + u16 minsrev_h = IXGBE_LE16_TO_CPU(data.orom_minsrev_h); + + minsrevs->orom = minsrev_h << 16 | minsrev_l; + minsrevs->orom_valid = true; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_update_nvm_minsrevs - Update minsrevs TLV data in flash + * @hw: pointer to the HW struct + * @minsrevs: minimum security revision information + * + * Update the NVM or Option ROM minimum security revision fields in the PFA + * area of the flash. Reads the minsrevs->nvm_valid and minsrevs->orom_valid + * fields to determine what update is being requested. If the valid bit is not + * set for that module, then the associated minsrev will be left as is. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_update_nvm_minsrevs(struct ixgbe_hw *hw, + struct ixgbe_minsrev_info *minsrevs) +{ + struct ixgbe_aci_cmd_nvm_minsrev data; + s32 status; + + if (!minsrevs->nvm_valid && !minsrevs->orom_valid) { + return IXGBE_ERR_PARAM; + } + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); + if (status) + return status; + + /* Get current data */ + status = ixgbe_aci_read_nvm(hw, IXGBE_ACI_NVM_MINSREV_MOD_ID, 0, + sizeof(data), &data, true, false); + if (status) + goto exit_release_res; + + if (minsrevs->nvm_valid) { + data.nvm_minsrev_l = IXGBE_CPU_TO_LE16(minsrevs->nvm & 0xFFFF); + data.nvm_minsrev_h = IXGBE_CPU_TO_LE16(minsrevs->nvm >> 16); + data.validity |= + IXGBE_CPU_TO_LE16(IXGBE_ACI_NVM_MINSREV_NVM_VALID); + } + + if (minsrevs->orom_valid) { + data.orom_minsrev_l = IXGBE_CPU_TO_LE16(minsrevs->orom & 0xFFFF); + data.orom_minsrev_h = IXGBE_CPU_TO_LE16(minsrevs->orom >> 16); + data.validity |= + IXGBE_CPU_TO_LE16(IXGBE_ACI_NVM_MINSREV_OROM_VALID); + } + + /* Update flash data */ + status = ixgbe_aci_update_nvm(hw, IXGBE_ACI_NVM_MINSREV_MOD_ID, 0, + sizeof(data), &data, false, + IXGBE_ACI_NVM_SPECIAL_UPDATE); + if (status) + goto exit_release_res; + + /* Dump the Shadow RAM to the flash */ + status = ixgbe_nvm_write_activate(hw, 0, NULL); + +exit_release_res: + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_get_nvm_srev - Read the security revision from the NVM CSS header + * @hw: pointer to the HW struct + * @bank: whether to read from the active or inactive flash bank + * @srev: storage for security revision + * + * Read the security revision out of the CSS header of the active NVM module + * bank. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_get_nvm_srev(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, u32 *srev) +{ + u16 srev_l, srev_h; + s32 status; + + status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_SREV_L, &srev_l); + if (status) + return status; + + status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_SREV_H, &srev_h); + if (status) + return status; + + *srev = srev_h << 16 | srev_l; + + return IXGBE_SUCCESS; +} + +#define IXGBE_OROM_STEP 512U + +/** + * ixgbe_get_orom_civd_data - Get the combo version information from Option ROM + * @hw: pointer to the HW struct + * @bank: whether to read from the active or inactive flash module + * @civd: storage for the Option ROM CIVD data. + * + * Searches through the Option ROM flash contents to locate the CIVD data for + * the image. + * + * Return: the exit code of the operation. + */ +static s32 +ixgbe_get_orom_civd_data(struct ixgbe_hw *hw, enum ixgbe_bank_select bank, + struct ixgbe_orom_civd_info *civd) +{ + u32 offset, orom_size = hw->flash.banks.orom_size; + u8 *orom_data; + s32 status; + + if (!orom_size) + return IXGBE_ERR_PARAM; + + orom_data = ixgbe_malloc(hw, orom_size); + if (!orom_data) + return IXGBE_ERR_OUT_OF_MEM; + + status = ixgbe_read_flash_module(hw, bank, + E610_SR_1ST_OROM_BANK_PTR, 0, + orom_data, orom_size); + if (status) { + status = IXGBE_ERR_NVM; + goto exit; + } + + /* The CIVD section is located in the Option ROM aligned to 512 bytes. + * The first 4 bytes must contain the ASCII characters "$CIV". + * A simple modulo 256 sum of all of the bytes of the structure must + * equal 0. + */ + for (offset = 0; offset + IXGBE_OROM_STEP <= orom_size; + offset += IXGBE_OROM_STEP) { + struct ixgbe_orom_civd_info *tmp; + u8 sum = 0, i; + + tmp = (struct ixgbe_orom_civd_info *)&orom_data[offset]; + + /* Skip forward until we find a matching signature */ + if (memcmp("$CIV", tmp->signature, sizeof(tmp->signature)) != 0) + continue; + + /* Verify that the simple checksum is zero */ + for (i = 0; i < sizeof(*tmp); i++) + sum += ((u8 *)tmp)[i]; + + if (sum) { + status = IXGBE_ERR_NVM; + goto exit; + } + + *civd = *tmp; + status = IXGBE_SUCCESS; + goto exit; + } + status = IXGBE_ERR_DOES_NOT_EXIST; +exit: + ixgbe_free(hw, orom_data); + return status; +} + +/** + * ixgbe_get_orom_srev - Read the security revision from the OROM CSS header + * @hw: pointer to the HW struct + * @bank: whether to read from active or inactive flash module + * @srev: storage for security revision + * + * Read the security revision out of the CSS header of the active OROM module + * bank. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_get_orom_srev(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + u32 *srev) +{ + u32 orom_size_word = hw->flash.banks.orom_size / 2; + u32 css_start, hdr_len; + u16 srev_l, srev_h; + s32 status; + + status = ixgbe_get_nvm_css_hdr_len(hw, bank, &hdr_len); + if (status) + return status; + + if (orom_size_word < hdr_len) { + return IXGBE_ERR_CONFIG; + } + + /* calculate how far into the Option ROM the CSS header starts. Note + * that ixgbe_read_orom_module takes a word offset + */ + css_start = orom_size_word - hdr_len; + status = ixgbe_read_orom_module(hw, bank, + css_start + IXGBE_NVM_CSS_SREV_L, + &srev_l); + if (status) + return status; + + status = ixgbe_read_orom_module(hw, bank, + css_start + IXGBE_NVM_CSS_SREV_H, + &srev_h); + if (status) + return status; + + *srev = srev_h << 16 | srev_l; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_orom_ver_info - Read Option ROM version information + * @hw: pointer to the HW struct + * @bank: whether to read from the active or inactive flash module + * @orom: pointer to Option ROM info structure + * + * Read Option ROM version and security revision from the Option ROM flash + * section. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_get_orom_ver_info(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + struct ixgbe_orom_info *orom) +{ + struct ixgbe_orom_civd_info civd; + u32 combo_ver; + s32 status; + + status = ixgbe_get_orom_civd_data(hw, bank, &civd); + if (status) { + return status; + } + + combo_ver = IXGBE_LE32_TO_CPU(civd.combo_ver); + + orom->major = (u8)((combo_ver & IXGBE_OROM_VER_MASK) >> + IXGBE_OROM_VER_SHIFT); + orom->patch = (u8)(combo_ver & IXGBE_OROM_VER_PATCH_MASK); + orom->build = (u16)((combo_ver & IXGBE_OROM_VER_BUILD_MASK) >> + IXGBE_OROM_VER_BUILD_SHIFT); + + status = ixgbe_get_orom_srev(hw, bank, &orom->srev); + if (status) { + return status; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_inactive_orom_ver - Read Option ROM version from the inactive bank + * @hw: pointer to the HW structure + * @orom: storage for Option ROM version information + * + * Reads the Option ROM version and security revision data for the inactive + * section of flash. Used to access version data for a pending update that has + * not yet been activated. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_inactive_orom_ver(struct ixgbe_hw *hw, + struct ixgbe_orom_info *orom) +{ + return ixgbe_get_orom_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, orom); +} + +/** + * ixgbe_get_nvm_ver_info - Read NVM version information + * @hw: pointer to the HW struct + * @bank: whether to read from the active or inactive flash bank + * @nvm: pointer to NVM info structure + * + * Read the NVM EETRACK ID and map version of the main NVM image bank, filling + * in the nvm info structure. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_get_nvm_ver_info(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + struct ixgbe_nvm_info *nvm) +{ + u16 eetrack_lo, eetrack_hi, ver; + s32 status; + + status = ixgbe_read_nvm_sr_copy(hw, bank, + E610_SR_NVM_DEV_STARTER_VER, &ver); + if (status) { + return status; + } + + nvm->major = (ver & E610_NVM_VER_HI_MASK) >> E610_NVM_VER_HI_SHIFT; + nvm->minor = (ver & E610_NVM_VER_LO_MASK) >> E610_NVM_VER_LO_SHIFT; + + status = ixgbe_read_nvm_sr_copy(hw, bank, E610_SR_NVM_EETRACK_LO, + &eetrack_lo); + if (status) { + return status; + } + status = ixgbe_read_nvm_sr_copy(hw, bank, E610_SR_NVM_EETRACK_HI, + &eetrack_hi); + if (status) { + return status; + } + + nvm->eetrack = (eetrack_hi << 16) | eetrack_lo; + + status = ixgbe_get_nvm_srev(hw, bank, &nvm->srev); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_inactive_nvm_ver - Read Option ROM version from the inactive bank + * @hw: pointer to the HW structure + * @nvm: storage for Option ROM version information + * + * Reads the NVM EETRACK ID, Map version, and security revision of the + * inactive NVM bank. Used to access version data for a pending update that + * has not yet been activated. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm) +{ + return ixgbe_get_nvm_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, nvm); +} + +/** + * ixgbe_get_active_nvm_ver - Read Option ROM version from the active bank + * @hw: pointer to the HW structure + * @nvm: storage for Option ROM version information + * + * Reads the NVM EETRACK ID, Map version, and security revision of the + * active NVM bank. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm) +{ + return ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, nvm); +} + +/** + * ixgbe_get_netlist_info + * @hw: pointer to the HW struct + * @bank: whether to read from the active or inactive flash bank + * @netlist: pointer to netlist version info structure + * + * Get the netlist version information from the requested bank. Reads the Link + * Topology section to find the Netlist ID block and extract the relevant + * information into the netlist version structure. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_get_netlist_info(struct ixgbe_hw *hw, + enum ixgbe_bank_select bank, + struct ixgbe_netlist_info *netlist) +{ + u16 module_id, length, node_count, i; + u16 *id_blk; + s32 status; + + status = ixgbe_read_netlist_module(hw, bank, IXGBE_NETLIST_TYPE_OFFSET, + &module_id); + if (status) + return status; + + if (module_id != IXGBE_NETLIST_LINK_TOPO_MOD_ID) { + return IXGBE_ERR_NVM; + } + + status = ixgbe_read_netlist_module(hw, bank, IXGBE_LINK_TOPO_MODULE_LEN, + &length); + if (status) + return status; + + /* sanity check that we have at least enough words to store the + * netlist ID block + */ + if (length < IXGBE_NETLIST_ID_BLK_SIZE) { + return IXGBE_ERR_NVM; + } + + status = ixgbe_read_netlist_module(hw, bank, IXGBE_LINK_TOPO_NODE_COUNT, + &node_count); + if (status) + return status; + node_count &= IXGBE_LINK_TOPO_NODE_COUNT_M; + + id_blk = (u16 *)ixgbe_calloc(hw, IXGBE_NETLIST_ID_BLK_SIZE, + sizeof(*id_blk)); + if (!id_blk) + return IXGBE_ERR_NO_SPACE; + + /* Read out the entire Netlist ID Block at once. */ + status = ixgbe_read_flash_module(hw, bank, E610_SR_NETLIST_BANK_PTR, + IXGBE_NETLIST_ID_BLK_OFFSET(node_count) * sizeof(u16), + (u8 *)id_blk, + IXGBE_NETLIST_ID_BLK_SIZE * sizeof(u16)); + if (status) + goto exit_error; + + for (i = 0; i < IXGBE_NETLIST_ID_BLK_SIZE; i++) + id_blk[i] = IXGBE_LE16_TO_CPU(((__le16 *)id_blk)[i]); + + netlist->major = id_blk[IXGBE_NETLIST_ID_BLK_MAJOR_VER_HIGH] << 16 | + id_blk[IXGBE_NETLIST_ID_BLK_MAJOR_VER_LOW]; + netlist->minor = id_blk[IXGBE_NETLIST_ID_BLK_MINOR_VER_HIGH] << 16 | + id_blk[IXGBE_NETLIST_ID_BLK_MINOR_VER_LOW]; + netlist->type = id_blk[IXGBE_NETLIST_ID_BLK_TYPE_HIGH] << 16 | + id_blk[IXGBE_NETLIST_ID_BLK_TYPE_LOW]; + netlist->rev = id_blk[IXGBE_NETLIST_ID_BLK_REV_HIGH] << 16 | + id_blk[IXGBE_NETLIST_ID_BLK_REV_LOW]; + netlist->cust_ver = id_blk[IXGBE_NETLIST_ID_BLK_CUST_VER]; + /* Read the left most 4 bytes of SHA */ + netlist->hash = id_blk[IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(15)] << 16 | + id_blk[IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(14)]; + +exit_error: + ixgbe_free(hw, id_blk); + + return status; +} + +/** + * ixgbe_get_inactive_netlist_ver + * @hw: pointer to the HW struct + * @netlist: pointer to netlist version info structure + * + * Read the netlist version data from the inactive netlist bank. Used to + * extract version data of a pending flash update in order to display the + * version data. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_inactive_netlist_ver(struct ixgbe_hw *hw, + struct ixgbe_netlist_info *netlist) +{ + return ixgbe_get_netlist_info(hw, IXGBE_INACTIVE_FLASH_BANK, netlist); +} + +/** + * ixgbe_read_sr_pointer - Read the value of a Shadow RAM pointer word + * @hw: pointer to the HW structure + * @offset: the word offset of the Shadow RAM word to read + * @pointer: pointer value read from Shadow RAM + * + * Read the given Shadow RAM word, and convert it to a pointer value specified + * in bytes. This function assumes the specified offset is a valid pointer + * word. + * + * Each pointer word specifies whether it is stored in word size or 4KB + * sector size by using the highest bit. The reported pointer value will be in + * bytes, intended for flat NVM reads. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_sr_pointer(struct ixgbe_hw *hw, u16 offset, u32 *pointer) +{ + s32 status; + u16 value; + + status = ixgbe_read_ee_aci_E610(hw, offset, &value); + if (status) + return status; + + /* Determine if the pointer is in 4KB or word units */ + if (value & IXGBE_SR_NVM_PTR_4KB_UNITS) + *pointer = (value & ~IXGBE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024; + else + *pointer = value * 2; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_sr_area_size - Read an area size from a Shadow RAM word + * @hw: pointer to the HW structure + * @offset: the word offset of the Shadow RAM to read + * @size: size value read from the Shadow RAM + * + * Read the given Shadow RAM word, and convert it to an area size value + * specified in bytes. This function assumes the specified offset is a valid + * area size word. + * + * Each area size word is specified in 4KB sector units. This function reports + * the size in bytes, intended for flat NVM reads. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_sr_area_size(struct ixgbe_hw *hw, u16 offset, u32 *size) +{ + s32 status; + u16 value; + + status = ixgbe_read_ee_aci_E610(hw, offset, &value); + if (status) + return status; + + /* Area sizes are always specified in 4KB units */ + *size = value * 4 * 1024; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_discover_flash_size - Discover the available flash size. + * @hw: pointer to the HW struct + * + * The device flash could be up to 16MB in size. However, it is possible that + * the actual size is smaller. Use bisection to determine the accessible size + * of flash memory. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_discover_flash_size(struct ixgbe_hw *hw) +{ + u32 min_size = 0, max_size = IXGBE_ACI_NVM_MAX_OFFSET + 1; + s32 status; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + while ((max_size - min_size) > 1) { + u32 offset = (max_size + min_size) / 2; + u32 len = 1; + u8 data; + + status = ixgbe_read_flat_nvm(hw, offset, &len, &data, false); + if (status == IXGBE_ERR_ACI_ERROR && + hw->aci.last_status == IXGBE_ACI_RC_EINVAL) { + status = IXGBE_SUCCESS; + max_size = offset; + } else if (!status) { + min_size = offset; + } else { + /* an unexpected error occurred */ + goto err_read_flat_nvm; + } + } + + hw->flash.flash_size = max_size; + +err_read_flat_nvm: + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_determine_active_flash_banks - Discover active bank for each module + * @hw: pointer to the HW struct + * + * Read the Shadow RAM control word and determine which banks are active for + * the NVM, OROM, and Netlist modules. Also read and calculate the associated + * pointer and size. These values are then cached into the ixgbe_flash_info + * structure for later use in order to calculate the correct offset to read + * from the active module. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_determine_active_flash_banks(struct ixgbe_hw *hw) +{ + struct ixgbe_bank_info *banks = &hw->flash.banks; + u16 ctrl_word; + s32 status; + + status = ixgbe_read_ee_aci_E610(hw, E610_SR_NVM_CTRL_WORD, &ctrl_word); + if (status) { + return status; + } + + /* Check that the control word indicates validity */ + if ((ctrl_word & IXGBE_SR_CTRL_WORD_1_M) >> IXGBE_SR_CTRL_WORD_1_S != + IXGBE_SR_CTRL_WORD_VALID) { + return IXGBE_ERR_CONFIG; + } + + if (!(ctrl_word & IXGBE_SR_CTRL_WORD_NVM_BANK)) + banks->nvm_bank = IXGBE_1ST_FLASH_BANK; + else + banks->nvm_bank = IXGBE_2ND_FLASH_BANK; + + if (!(ctrl_word & IXGBE_SR_CTRL_WORD_OROM_BANK)) + banks->orom_bank = IXGBE_1ST_FLASH_BANK; + else + banks->orom_bank = IXGBE_2ND_FLASH_BANK; + + if (!(ctrl_word & IXGBE_SR_CTRL_WORD_NETLIST_BANK)) + banks->netlist_bank = IXGBE_1ST_FLASH_BANK; + else + banks->netlist_bank = IXGBE_2ND_FLASH_BANK; + + status = ixgbe_read_sr_pointer(hw, E610_SR_1ST_NVM_BANK_PTR, + &banks->nvm_ptr); + if (status) { + return status; + } + + status = ixgbe_read_sr_area_size(hw, E610_SR_NVM_BANK_SIZE, + &banks->nvm_size); + if (status) { + return status; + } + + status = ixgbe_read_sr_pointer(hw, E610_SR_1ST_OROM_BANK_PTR, + &banks->orom_ptr); + if (status) { + return status; + } + + status = ixgbe_read_sr_area_size(hw, E610_SR_OROM_BANK_SIZE, + &banks->orom_size); + if (status) { + return status; + } + + status = ixgbe_read_sr_pointer(hw, E610_SR_NETLIST_BANK_PTR, + &banks->netlist_ptr); + if (status) { + return status; + } + + status = ixgbe_read_sr_area_size(hw, E610_SR_NETLIST_BANK_SIZE, + &banks->netlist_size); + if (status) { + return status; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_nvm - initializes NVM setting + * @hw: pointer to the HW struct + * + * Read and populate NVM settings such as Shadow RAM size, + * max_timeout, and blank_nvm_mode + * + * Return: the exit code of the operation. + */ +s32 ixgbe_init_nvm(struct ixgbe_hw *hw) +{ + struct ixgbe_flash_info *flash = &hw->flash; + u32 fla, gens_stat; + s32 status; + u8 sr_size; + + /* The SR size is stored regardless of the NVM programming mode + * as the blank mode may be used in the factory line. + */ + gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS); + sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S; + + /* Switching to words (sr_size contains power of 2) */ + flash->sr_words = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB; + + /* Check if we are in the normal or blank NVM programming mode */ + fla = IXGBE_READ_REG(hw, GLNVM_FLA); + if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */ + flash->blank_nvm_mode = false; + } else { + /* Blank programming mode */ + flash->blank_nvm_mode = true; + return IXGBE_ERR_NVM_BLANK_MODE; + } + + status = ixgbe_discover_flash_size(hw); + if (status) { + return status; + } + + status = ixgbe_determine_active_flash_banks(hw); + if (status) { + return status; + } + + status = ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, + &flash->nvm); + if (status) { + return status; + } + status = ixgbe_get_orom_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, + &flash->orom); + + /* read the netlist version information */ + status = ixgbe_get_netlist_info(hw, IXGBE_ACTIVE_FLASH_BANK, + &flash->netlist); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_aci_nvm_update_empr - NVM update EMPR + * @hw: pointer to the HW struct + * + * Update empr using ACI command (0x0709). This command allows SW to + * request an EMPR to activate new FW. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_nvm_update_empr(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_update_empr); + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/* ixgbe_nvm_set_pkg_data - NVM set package data + * @hw: pointer to the HW struct + * @del_pkg_data_flag: If is set then the current pkg_data store by FW + * is deleted. + * If bit is set to 1, then buffer should be size 0. + * @data: pointer to buffer + * @length: length of the buffer + * + * Set package data using ACI command (0x070A). + * This command is equivalent to the reception of + * a PLDM FW Update GetPackageData cmd. This command should be sent + * as part of the NVM update as the first cmd in the flow. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_nvm_set_pkg_data(struct ixgbe_hw *hw, bool del_pkg_data_flag, + u8 *data, u16 length) +{ + struct ixgbe_aci_cmd_nvm_pkg_data *cmd; + struct ixgbe_aci_desc desc; + + if (length != 0 && !data) + return IXGBE_ERR_PARAM; + + cmd = &desc.params.pkg_data; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_pkg_data); + desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + + if (del_pkg_data_flag) + cmd->cmd_flags |= IXGBE_ACI_NVM_PKG_DELETE; + + return ixgbe_aci_send_cmd(hw, &desc, data, length); +} + +/* ixgbe_nvm_pass_component_tbl - NVM pass component table + * @hw: pointer to the HW struct + * @data: pointer to buffer + * @length: length of the buffer + * @transfer_flag: parameter for determining stage of the update + * @comp_response: a pointer to the response from the 0x070B AQC. + * @comp_response_code: a pointer to the response code from the 0x070B AQC. + * + * Pass component table using ACI command (0x070B). This command is equivalent + * to the reception of a PLDM FW Update PassComponentTable cmd. + * This command should be sent once per component. It can be only sent after + * Set Package Data cmd and before actual update. FW will assume these + * commands are going to be sent until the TransferFlag is set to End or + * StartAndEnd. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_nvm_pass_component_tbl(struct ixgbe_hw *hw, u8 *data, u16 length, + u8 transfer_flag, u8 *comp_response, + u8 *comp_response_code) +{ + struct ixgbe_aci_cmd_nvm_pass_comp_tbl *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + if (!data || !comp_response || !comp_response_code) + return IXGBE_ERR_PARAM; + + cmd = &desc.params.pass_comp_tbl; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_nvm_pass_component_tbl); + desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + + cmd->transfer_flag = transfer_flag; + status = ixgbe_aci_send_cmd(hw, &desc, data, length); + + if (!status) { + *comp_response = cmd->component_response; + *comp_response_code = cmd->component_response_code; + } + return status; +} + +/** + * ixgbe_sanitize_operate - Clear the user data + * @hw: pointer to the HW struct + * + * Clear user data from NVM using ACI command (0x070C). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_sanitize_operate(struct ixgbe_hw *hw) +{ + s32 status; + u8 values; + + u8 cmd_flags = IXGBE_ACI_SANITIZE_REQ_OPERATE | + IXGBE_ACI_SANITIZE_OPERATE_SUBJECT_CLEAR; + + status = ixgbe_sanitize_nvm(hw, cmd_flags, &values); + if (status) + return status; + if ((!(values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_DONE) && + !(values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_DONE)) || + ((values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_DONE) && + !(values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_SUCCESS)) || + ((values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_DONE) && + !(values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_SUCCESS))) + return IXGBE_ERR_ACI_ERROR; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_sanitize_nvm - Sanitize NVM + * @hw: pointer to the HW struct + * @cmd_flags: flag to the ACI command + * @values: values returned from the command + * + * Sanitize NVM using ACI command (0x070C). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_sanitize_nvm(struct ixgbe_hw *hw, u8 cmd_flags, u8 *values) +{ + struct ixgbe_aci_desc desc; + struct ixgbe_aci_cmd_nvm_sanitization *cmd; + s32 status; + + cmd = &desc.params.nvm_sanitization; + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_sanitization); + cmd->cmd_flags = cmd_flags; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (values) + *values = cmd->values; + + return status; +} + +/** + * ixgbe_read_sr_word_aci - Reads Shadow RAM via ACI + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) + * @data: word read from the Shadow RAM + * + * Reads one 16 bit word from the Shadow RAM using ixgbe_read_flat_nvm. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_read_sr_word_aci(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + u32 bytes = sizeof(u16); + __le16 data_local; + s32 status; + + status = ixgbe_read_flat_nvm(hw, offset * sizeof(u16), &bytes, + (u8 *)&data_local, true); + if (status) + return status; + + *data = IXGBE_LE16_TO_CPU(data_local); + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_sr_buf_aci - Reads Shadow RAM buf via ACI + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) + * @words: (in) number of words to read; (out) number of words actually read + * @data: words read from the Shadow RAM + * + * Reads 16 bit words (data buf) from the Shadow RAM. Ownership of the NVM is + * taken before reading the buffer and later released. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_read_sr_buf_aci(struct ixgbe_hw *hw, u16 offset, u16 *words, + u16 *data) +{ + u32 bytes = *words * 2, i; + s32 status; + + status = ixgbe_read_flat_nvm(hw, offset * 2, &bytes, (u8 *)data, true); + + *words = bytes / 2; + + for (i = 0; i < *words; i++) + data[i] = IXGBE_LE16_TO_CPU(((__le16 *)data)[i]); + + return status; +} + +/** + * ixgbe_read_flat_nvm - Read portion of NVM by flat offset + * @hw: pointer to the HW struct + * @offset: offset from beginning of NVM + * @length: (in) number of bytes to read; (out) number of bytes actually read + * @data: buffer to return data in (sized to fit the specified length) + * @read_shadow_ram: if true, read from shadow RAM instead of NVM + * + * Reads a portion of the NVM, as a flat memory space. This function correctly + * breaks read requests across Shadow RAM sectors, prevents Shadow RAM size + * from being exceeded in case of Shadow RAM read requests and ensures that no + * single read request exceeds the maximum 4KB read for a single admin command. + * + * Returns a status code on failure. Note that the data pointer may be + * partially updated if some reads succeed before a failure. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length, + u8 *data, bool read_shadow_ram) +{ + u32 inlen = *length; + u32 bytes_read = 0; + bool last_cmd; + s32 status; + + *length = 0; + + /* Verify the length of the read if this is for the Shadow RAM */ + if (read_shadow_ram && ((offset + inlen) > + (hw->eeprom.word_size * 2u))) { + return IXGBE_ERR_PARAM; + } + + do { + u32 read_size, sector_offset; + + /* ixgbe_aci_read_nvm cannot read more than 4KB at a time. + * Additionally, a read from the Shadow RAM may not cross over + * a sector boundary. Conveniently, the sector size is also 4KB. + */ + sector_offset = offset % IXGBE_ACI_MAX_BUFFER_SIZE; + read_size = MIN_T(u32, + IXGBE_ACI_MAX_BUFFER_SIZE - sector_offset, + inlen - bytes_read); + + last_cmd = !(bytes_read + read_size < inlen); + + /* ixgbe_aci_read_nvm takes the length as a u16. Our read_size + * is calculated using a u32, but the IXGBE_ACI_MAX_BUFFER_SIZE + * maximum size guarantees that it will fit within the 2 bytes. + */ + status = ixgbe_aci_read_nvm(hw, IXGBE_ACI_NVM_START_POINT, + offset, (u16)read_size, + data + bytes_read, last_cmd, + read_shadow_ram); + if (status) + break; + + bytes_read += read_size; + offset += read_size; + } while (!last_cmd); + + *length = bytes_read; + return status; +} + +/** + * ixgbe_aci_alternate_write - write to alternate structure + * @hw: pointer to the hardware structure + * @reg_addr0: address of first dword to be written + * @reg_val0: value to be written under 'reg_addr0' + * @reg_addr1: address of second dword to be written + * @reg_val1: value to be written under 'reg_addr1' + * + * Write one or two dwords to alternate structure using ACI command (0x0900). + * Fields are indicated by 'reg_addr0' and 'reg_addr1' register numbers. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_write(struct ixgbe_hw *hw, u32 reg_addr0, + u32 reg_val0, u32 reg_addr1, u32 reg_val1) +{ + struct ixgbe_aci_cmd_read_write_alt_direct *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.read_write_alt_direct; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_write_alt_direct); + cmd->dword0_addr = IXGBE_CPU_TO_LE32(reg_addr0); + cmd->dword1_addr = IXGBE_CPU_TO_LE32(reg_addr1); + cmd->dword0_value = IXGBE_CPU_TO_LE32(reg_val0); + cmd->dword1_value = IXGBE_CPU_TO_LE32(reg_val1); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + return status; +} + +/** + * ixgbe_aci_alternate_read - read from alternate structure + * @hw: pointer to the hardware structure + * @reg_addr0: address of first dword to be read + * @reg_val0: pointer for data read from 'reg_addr0' + * @reg_addr1: address of second dword to be read + * @reg_val1: pointer for data read from 'reg_addr1' + * + * Read one or two dwords from alternate structure using ACI command (0x0902). + * Fields are indicated by 'reg_addr0' and 'reg_addr1' register numbers. + * If 'reg_val1' pointer is not passed then only register at 'reg_addr0' + * is read. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_read(struct ixgbe_hw *hw, u32 reg_addr0, + u32 *reg_val0, u32 reg_addr1, u32 *reg_val1) +{ + struct ixgbe_aci_cmd_read_write_alt_direct *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.read_write_alt_direct; + + if (!reg_val0) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_alt_direct); + cmd->dword0_addr = IXGBE_CPU_TO_LE32(reg_addr0); + cmd->dword1_addr = IXGBE_CPU_TO_LE32(reg_addr1); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + if (status == IXGBE_SUCCESS) { + *reg_val0 = IXGBE_LE32_TO_CPU(cmd->dword0_value); + + if (reg_val1) + *reg_val1 = IXGBE_LE32_TO_CPU(cmd->dword1_value); + } + + return status; +} + +/** + * ixgbe_aci_alternate_write_done - check if writing to alternate structure + * is done + * @hw: pointer to the HW structure. + * @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS + * @reset_needed: indicates the SW should trigger GLOBAL reset + * + * Indicates to the FW that alternate structures have been changed. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_write_done(struct ixgbe_hw *hw, u8 bios_mode, + bool *reset_needed) +{ + struct ixgbe_aci_cmd_done_alt_write *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.done_alt_write; + + if (!reset_needed) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_done_alt_write); + cmd->flags = bios_mode; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (!status) + *reset_needed = (IXGBE_LE16_TO_CPU(cmd->flags) & + IXGBE_ACI_RESP_RESET_NEEDED) != 0; + + return status; +} + +/** + * ixgbe_aci_alternate_clear - clear alternate structure + * @hw: pointer to the HW structure. + * + * Clear the alternate structures of the port from which the function + * is called. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_clear(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_desc desc; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_clear_port_alt_write); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + return status; +} + +/** + * ixgbe_aci_get_internal_data - get internal FW/HW data + * @hw: pointer to the hardware structure + * @cluster_id: specific cluster to dump + * @table_id: table ID within cluster + * @start: index of line in the block to read + * @buf: dump buffer + * @buf_size: dump buffer size + * @ret_buf_size: return buffer size (returned by FW) + * @ret_next_cluster: next cluster to read (returned by FW) + * @ret_next_table: next block to read (returned by FW) + * @ret_next_index: next index to read (returned by FW) + * + * Get internal FW/HW data using ACI command (0xFF08) for debug purposes. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_internal_data(struct ixgbe_hw *hw, u16 cluster_id, + u16 table_id, u32 start, void *buf, + u16 buf_size, u16 *ret_buf_size, + u16 *ret_next_cluster, u16 *ret_next_table, + u32 *ret_next_index) +{ + struct ixgbe_aci_cmd_debug_dump_internals *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.debug_dump; + + if (buf_size == 0 || !buf) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_debug_dump_internals); + + cmd->cluster_id = IXGBE_CPU_TO_LE16(cluster_id); + cmd->table_id = IXGBE_CPU_TO_LE16(table_id); + cmd->idx = IXGBE_CPU_TO_LE32(start); + + status = ixgbe_aci_send_cmd(hw, &desc, buf, buf_size); + + if (!status) { + if (ret_buf_size) + *ret_buf_size = IXGBE_LE16_TO_CPU(desc.datalen); + if (ret_next_cluster) + *ret_next_cluster = IXGBE_LE16_TO_CPU(cmd->cluster_id); + if (ret_next_table) + *ret_next_table = IXGBE_LE16_TO_CPU(cmd->table_id); + if (ret_next_index) + *ret_next_index = IXGBE_LE32_TO_CPU(cmd->idx); + } + + return status; +} + +/** + * ixgbe_validate_nvm_rw_reg - Check that an NVM access request is valid + * @cmd: NVM access command structure + * + * Validates that an NVM access structure is request to read or write a valid + * register offset. First validates that the module and flags are correct, and + * then ensures that the register offset is one of the accepted registers. + * + * Return: 0 if the register access is valid, out of range error code otherwise. + */ +static s32 +ixgbe_validate_nvm_rw_reg(struct ixgbe_nvm_access_cmd *cmd) +{ + u16 i; + + switch (cmd->offset) { + case GL_HICR: + case GL_HICR_EN: /* Note, this register is read only */ + case GL_FWSTS: + case GL_MNG_FWSM: + case GLNVM_GENS: + case GLNVM_FLA: + case GL_FWRESETCNT: + return 0; + default: + break; + } + + for (i = 0; i <= GL_HIDA_MAX_INDEX; i++) + if (cmd->offset == (u32)GL_HIDA(i)) + return 0; + + for (i = 0; i <= GL_HIBA_MAX_INDEX; i++) + if (cmd->offset == (u32)GL_HIBA(i)) + return 0; + + /* All other register offsets are not valid */ + return IXGBE_ERR_OUT_OF_RANGE; +} + +/** + * ixgbe_nvm_access_read - Handle an NVM read request + * @hw: pointer to the HW struct + * @cmd: NVM access command to process + * @data: storage for the register value read + * + * Process an NVM access request to read a register. + * + * Return: 0 if the register read is valid and successful, + * out of range error code otherwise. + */ +static s32 ixgbe_nvm_access_read(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data) +{ + s32 status; + + /* Always initialize the output data, even on failure */ + memset(&data->regval, 0, cmd->data_size); + + /* Make sure this is a valid read/write access request */ + status = ixgbe_validate_nvm_rw_reg(cmd); + if (status) + return status; + + hw_dbg(hw, "NVM access: reading register %08x\n", cmd->offset); + + /* Read the register and store the contents in the data field */ + data->regval = IXGBE_READ_REG(hw, cmd->offset); + + return 0; +} + +/** + * ixgbe_nvm_access_write - Handle an NVM write request + * @hw: pointer to the HW struct + * @cmd: NVM access command to process + * @data: NVM access data to write + * + * Process an NVM access request to write a register. + * + * Return: 0 if the register write is valid and successful, + * out of range error code otherwise. + */ +static s32 ixgbe_nvm_access_write(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data) +{ + s32 status; + + /* Make sure this is a valid read/write access request */ + status = ixgbe_validate_nvm_rw_reg(cmd); + if (status) + return status; + + /* Reject requests to write to read-only registers */ + switch (cmd->offset) { + case GL_HICR_EN: + return IXGBE_ERR_OUT_OF_RANGE; + default: + break; + } + + hw_dbg(hw, "NVM access: writing register %08x with value %08x\n", + cmd->offset, data->regval); + + /* Write the data field to the specified register */ + IXGBE_WRITE_REG(hw, cmd->offset, data->regval); + + return 0; +} + +/** + * ixgbe_handle_nvm_access - Handle an NVM access request + * @hw: pointer to the HW struct + * @cmd: NVM access command info + * @data: pointer to read or return data + * + * Process an NVM access request. Read the command structure information and + * determine if it is valid. If not, report an error indicating the command + * was invalid. + * + * For valid commands, perform the necessary function, copying the data into + * the provided data buffer. + * + * Return: 0 if the nvm access request is valid and successful, + * error code otherwise. + */ +s32 ixgbe_handle_nvm_access(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data) +{ + switch (cmd->command) { + case IXGBE_NVM_CMD_READ: + return ixgbe_nvm_access_read(hw, cmd, data); + case IXGBE_NVM_CMD_WRITE: + return ixgbe_nvm_access_write(hw, cmd, data); + default: + return IXGBE_ERR_PARAM; + } +} + +/** + * ixgbe_aci_set_health_status_config - Configure FW health events + * @hw: pointer to the HW struct + * @event_source: type of diagnostic events to enable + * + * Configure the health status event types that the firmware will send to this + * PF using ACI command (0xFF20). The supported event types are: PF-specific, + * all PFs, and global. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_health_status_config(struct ixgbe_hw *hw, u8 event_source) +{ + struct ixgbe_aci_cmd_set_health_status_config *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.set_health_status_config; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_set_health_status_config); + + cmd->event_source = event_source; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_fwlog_cache_cfg - Cache FW logging config + * @hw: pointer to the HW structure + * @cfg: config to cache + * + * Cache FW logging config. + */ +static void ixgbe_fwlog_cache_cfg(struct ixgbe_hw *hw, + struct ixgbe_fwlog_cfg *cfg) +{ + hw->fwlog_cfg = *cfg; +} + +/** + * ixgbe_fwlog_valid_module_entries - validate all the module entry IDs and + * log levels + * @hw: pointer to the HW structure + * @entries: entries to validate + * @num_entries: number of entries to validate + * + * Checks if all the module entry IDs and log levels are valid. + * + * Return: true if all the module entry IDs and log levels are valid, + * otherwise false. + */ +static bool ixgbe_fwlog_valid_module_entries(struct ixgbe_hw *hw, + struct ixgbe_fwlog_module_entry *entries, + u16 num_entries) +{ + u16 i; + + UNREFERENCED_1PARAMETER(hw); + + if (!entries) { + return false; + } + + if (!num_entries) { + return false; + } + + for (i = 0; i < num_entries; i++) { + struct ixgbe_fwlog_module_entry *entry = &entries[i]; + + if (entry->module_id >= IXGBE_ACI_FW_LOG_ID_MAX) { + return false; + } + + if (entry->log_level >= IXGBE_FWLOG_LEVEL_INVALID) { + return false; + } + } + + return true; +} + +/** + * ixgbe_fwlog_valid_cfg - validate configuration + * @hw: pointer to the HW structure + * @cfg: config to validate + * + * Validate the entire configuration. + * + * Return: true if the entire configuration is valid, otherwise false. + */ +static bool ixgbe_fwlog_valid_cfg(struct ixgbe_hw *hw, + struct ixgbe_fwlog_cfg *cfg) +{ + if (!cfg) { + return false; + } + + if (cfg->log_resolution < IXGBE_ACI_FW_LOG_MIN_RESOLUTION || + cfg->log_resolution > IXGBE_ACI_FW_LOG_MAX_RESOLUTION) { + return false; + } + + if (!ixgbe_fwlog_valid_module_entries(hw, cfg->module_entries, + IXGBE_ACI_FW_LOG_ID_MAX)) + return false; + + return true; +} + +/** + * ixgbe_aci_fwlog_set - Set FW logging configuration + * @hw: pointer to the HW structure + * @entries: entries to configure + * @num_entries: number of @entries + * @options: options from ixgbe_fwlog_cfg->options structure + * @log_resolution: logging resolution + * + * Set FW logging configuration using ACI command (0xFF30). + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_aci_fwlog_set(struct ixgbe_hw *hw, + struct ixgbe_fwlog_module_entry *entries, + u16 num_entries, u16 options, u16 log_resolution) +{ + struct ixgbe_aci_cmd_fw_log_cfg_resp fw_modules[IXGBE_ACI_FW_LOG_ID_MAX]; + struct ixgbe_aci_cmd_fw_log *cmd; + struct ixgbe_aci_desc desc; + s32 status; + u16 i; + + if (num_entries > IXGBE_ACI_FW_LOG_ID_MAX) + return IXGBE_ERR_PARAM; + + for (i = 0; i < num_entries; i++) { + fw_modules[i].module_identifier = + IXGBE_CPU_TO_LE16(entries[i].module_id); + fw_modules[i].log_level = entries[i].log_level; + } + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_fw_logs_config); + desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD); + + cmd = &desc.params.fw_log; + + cmd->cmd_flags = IXGBE_ACI_FW_LOG_CONF_SET_VALID; + cmd->ops.cfg.log_resolution = IXGBE_CPU_TO_LE16(log_resolution); + cmd->ops.cfg.mdl_cnt = IXGBE_CPU_TO_LE16(num_entries); + + if (options & IXGBE_FWLOG_OPTION_ARQ_ENA) + cmd->cmd_flags |= IXGBE_ACI_FW_LOG_CONF_AQ_EN; + if (options & IXGBE_FWLOG_OPTION_UART_ENA) + cmd->cmd_flags |= IXGBE_ACI_FW_LOG_CONF_UART_EN; + + status = ixgbe_aci_send_cmd(hw, &desc, fw_modules, + sizeof(*fw_modules) * num_entries); + + return status; +} + +/** + * ixgbe_fwlog_supported - Cached for whether FW supports FW logging or not + * @hw: pointer to the HW structure + * + * This will always return false if called before ixgbe_init_hw(), so it must be + * called after ixgbe_init_hw(). + * + * Return: true if FW supports FW logging. + * If this function is called before ixgbe_init_hw(), return false. + */ +bool ixgbe_fwlog_supported(struct ixgbe_hw *hw) +{ + return hw->fwlog_support_ena; +} + +/** + * ixgbe_fwlog_set - Set the firmware logging settings + * @hw: pointer to the HW structure + * @cfg: config used to set firmware logging + * + * Call this function whenever the driver needs to set the firmware + * logging configuration. It can be called on initialization, reset, or during + * runtime. + * + * If the PF wishes to receive FW logging then it must register via + * ixgbe_fwlog_register. Note, that ixgbe_fwlog_register does not need to + * be called for init. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_fwlog_set(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg) +{ + s32 status; + + if (!ixgbe_fwlog_supported(hw)) + return IXGBE_ERR_NOT_SUPPORTED; + + if (!ixgbe_fwlog_valid_cfg(hw, cfg)) + return IXGBE_ERR_PARAM; + + status = ixgbe_aci_fwlog_set(hw, cfg->module_entries, + IXGBE_ACI_FW_LOG_ID_MAX, cfg->options, + cfg->log_resolution); + if (!status) + ixgbe_fwlog_cache_cfg(hw, cfg); + + return status; +} + +/** + * ixgbe_fwlog_update_cached_entries - Update module entries in cached + * FW logging config + * @hw: pointer to the HW structure + * @entries: entries to cache + * @num_entries: number of @entries + * + * Update module entries in cached FW logging config. + */ +static void ixgbe_fwlog_update_cached_entries(struct ixgbe_hw *hw, + struct ixgbe_fwlog_module_entry *entries, + u16 num_entries) +{ + u16 i; + + for (i = 0; i < num_entries; i++) { + struct ixgbe_fwlog_module_entry *updated = &entries[i]; + u16 j; + + for (j = 0; j < IXGBE_ACI_FW_LOG_ID_MAX; j++) { + struct ixgbe_fwlog_module_entry *cached = + &hw->fwlog_cfg.module_entries[j]; + + if (cached->module_id == updated->module_id) { + cached->log_level = updated->log_level; + break; + } + } + } +} + +/** + * ixgbe_fwlog_update_modules - Update the log level 1 or more + * FW logging modules + * @hw: pointer to the HW structure + * @entries: array of ixgbe_fwlog_module_entry(s) + * @num_entries: number of entries + * + * Update the log level of 1 or more FW logging modules via module ID. + * + * Only the entries passed in will be affected. All other firmware logging + * settings will be unaffected. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_fwlog_update_modules(struct ixgbe_hw *hw, + struct ixgbe_fwlog_module_entry *entries, + u16 num_entries) +{ + struct ixgbe_fwlog_cfg cfg; + s32 status; + + if (!ixgbe_fwlog_supported(hw)) + return IXGBE_ERR_NOT_SUPPORTED; + + if (num_entries > IXGBE_ACI_FW_LOG_ID_MAX) + return IXGBE_ERR_PARAM; + + if (!ixgbe_fwlog_valid_module_entries(hw, entries, num_entries)) + return IXGBE_ERR_PARAM; + + status = ixgbe_fwlog_get(hw, &cfg); + if (status) + goto status_out; + + status = ixgbe_aci_fwlog_set(hw, entries, num_entries, cfg.options, + cfg.log_resolution); + if (!status) + ixgbe_fwlog_update_cached_entries(hw, entries, num_entries); + +status_out: + return status; +} + +/** + * ixgbe_aci_fwlog_register - Register PF for firmware logging events. + * @hw: pointer to the HW structure + * @reg: true to register and false to unregister + * + * Register a PF for firmware logging events using ACI command (0xFF31). + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_aci_fwlog_register(struct ixgbe_hw *hw, bool reg) +{ + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_fw_logs_register); + + if (reg) + desc.params.fw_log.cmd_flags = IXGBE_ACI_FW_LOG_AQ_REGISTER; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_fwlog_register - Register the PF for firmware logging + * @hw: pointer to the HW structure + * + * After this call the PF will start to receive firmware logging based on the + * configuration set in ixgbe_fwlog_set. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_fwlog_register(struct ixgbe_hw *hw) +{ + s32 status; + + if (!ixgbe_fwlog_supported(hw)) + return IXGBE_ERR_NOT_SUPPORTED; + + status = ixgbe_aci_fwlog_register(hw, true); + + if (!status) + hw->fwlog_cfg.options |= IXGBE_FWLOG_OPTION_IS_REGISTERED; + + return status; +} + +/** + * ixgbe_fwlog_unregister - Unregister the PF from firmware logging + * @hw: pointer to the HW structure + * + * Make an attempt to unregister the PF from firmware logging. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_fwlog_unregister(struct ixgbe_hw *hw) +{ + s32 status; + + if (!ixgbe_fwlog_supported(hw)) + return IXGBE_ERR_NOT_SUPPORTED; + + status = ixgbe_aci_fwlog_register(hw, false); + if (!status) + hw->fwlog_cfg.options &= ~IXGBE_FWLOG_OPTION_IS_REGISTERED; + + return status; +} + +/** + * ixgbe_aci_fwlog_get - Get the current firmware logging configuration + * @hw: pointer to the HW structure + * @cfg: firmware logging configuration to populate + * + * Make an attempt to get the current firmware logging + * configuration using ACI command (0xFF32). + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_aci_fwlog_get(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg) +{ + struct ixgbe_aci_cmd_fw_log_cfg_resp *fw_modules; + struct ixgbe_aci_cmd_fw_log *cmd; + struct ixgbe_aci_desc desc; + u16 i, module_id_cnt; + u8 *buf = NULL; + s32 status; + + memset(cfg, 0, sizeof(*cfg)); + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_fw_logs_query); + cmd = &desc.params.fw_log; + + cmd->cmd_flags = IXGBE_ACI_FW_LOG_AQ_QUERY; + + buf = (u8*)ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE); + if (!buf) + return IXGBE_ERR_OUT_OF_MEM; + + status = ixgbe_aci_send_cmd(hw, &desc, buf, IXGBE_ACI_MAX_BUFFER_SIZE); + if (status) { + goto status_out; + } + + module_id_cnt = IXGBE_LE16_TO_CPU(cmd->ops.cfg.mdl_cnt); + if (module_id_cnt >= IXGBE_ACI_FW_LOG_ID_MAX) { + module_id_cnt = IXGBE_ACI_FW_LOG_ID_MAX; + } + + cfg->log_resolution = (u8)IXGBE_LE16_TO_CPU(cmd->ops.cfg.log_resolution); + if (cmd->cmd_flags & IXGBE_ACI_FW_LOG_CONF_AQ_EN) + cfg->options |= IXGBE_FWLOG_OPTION_ARQ_ENA; + if (cmd->cmd_flags & IXGBE_ACI_FW_LOG_CONF_UART_EN) + cfg->options |= IXGBE_FWLOG_OPTION_UART_ENA; + if (cmd->cmd_flags & IXGBE_ACI_FW_LOG_QUERY_REGISTERED) + cfg->options |= IXGBE_FWLOG_OPTION_IS_REGISTERED; + + fw_modules = (struct ixgbe_aci_cmd_fw_log_cfg_resp *)buf; + + for (i = 0; i < module_id_cnt; i++) { + struct ixgbe_aci_cmd_fw_log_cfg_resp *fw_module = &fw_modules[i]; + + cfg->module_entries[i].module_id = + IXGBE_LE16_TO_CPU(fw_module->module_identifier); + cfg->module_entries[i].log_level = fw_module->log_level; + } + +status_out: + if (buf) + ixgbe_free(hw, buf); + return status; +} + +/** + * ixgbe_fwlog_set_support_ena - Set if FW logging is supported by FW + * @hw: pointer to the HW struct + * + * If FW returns success to the ixgbe_aci_fwlog_get call then it supports FW + * logging, else it doesn't. Set the fwlog_support_ena flag accordingly. + * + * This function is only meant to be called during driver init to determine if + * the FW support FW logging. + * + * Return: the exit code of the operation. + */ +void ixgbe_fwlog_set_support_ena(struct ixgbe_hw *hw) +{ + struct ixgbe_fwlog_cfg cfg; + s32 status; + + hw->fwlog_support_ena = false; + + /* don't call ixgbe_fwlog_get() because that would overwrite the cached + * configuration from the call to ixgbe_fwlog_init(), which is expected + * to be called prior to this function + */ + status = ixgbe_aci_fwlog_get(hw, &cfg); + if (!status) + hw->fwlog_support_ena = true; +} + +/** + * ixgbe_fwlog_get - Get the firmware logging settings + * @hw: pointer to the HW structure + * @cfg: config to populate based on current firmware logging settings + * + * Get the current firmware logging settings. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_fwlog_get(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg) +{ + s32 status; + + if (!ixgbe_fwlog_supported(hw)) + return IXGBE_ERR_NOT_SUPPORTED; + + if (!cfg) + return IXGBE_ERR_PARAM; + + status = ixgbe_aci_fwlog_get(hw, cfg); + if (status) + return status; + + ixgbe_fwlog_cache_cfg(hw, cfg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fwlog_event_dump - Dump the event received over the Admin Receive Queue + * @hw: pointer to the HW structure + * @desc: Admin Receive Queue descriptor + * @buf: buffer that contains the FW log event data + * + * If the driver receives the ixgbe_aci_opc_fw_logs_event on the Admin Receive + * Queue, then it should call this function to dump the FW log data. + */ +void ixgbe_fwlog_event_dump(struct ixgbe_hw *hw, + struct ixgbe_aci_desc *desc, void *buf) +{ + if (!ixgbe_fwlog_supported(hw)) + return; + + ixgbe_info_fwlog(hw, 32, 1, (u8 *)buf, + IXGBE_LE16_TO_CPU(desc->datalen)); +} + +/** + * ixgbe_init_ops_E610 - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type for E610. + * Does not touch the hardware. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_init_ops_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val; + + ret_val = ixgbe_init_ops_X550(hw); + /* TODO Additional ops overrides for e610 to go here */ + + /* MAC */ + mac->ops.reset_hw = ixgbe_reset_hw_E610; + mac->ops.start_hw = ixgbe_start_hw_E610; + mac->ops.get_media_type = ixgbe_get_media_type_E610; + mac->ops.get_supported_physical_layer = + ixgbe_get_supported_physical_layer_E610; + mac->ops.get_san_mac_addr = NULL; + mac->ops.set_san_mac_addr = NULL; + mac->ops.get_wwn_prefix = NULL; + mac->ops.setup_link = ixgbe_setup_link_E610; + mac->ops.check_link = ixgbe_check_link_E610; + mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_E610; + mac->ops.setup_fc = ixgbe_setup_fc_E610; + mac->ops.fc_autoneg = ixgbe_fc_autoneg_E610; + mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_E610; + mac->ops.disable_rx = ixgbe_disable_rx_E610; + mac->ops.setup_eee = ixgbe_setup_eee_E610; + mac->ops.fw_recovery_mode = ixgbe_fw_recovery_mode_E610; + mac->ops.fw_rollback_mode = ixgbe_fw_rollback_mode_E610; + mac->ops.get_fw_tsam_mode = ixgbe_get_fw_tsam_mode_E610; + mac->ops.get_fw_version = ixgbe_aci_get_fw_ver; + mac->ops.get_nvm_version = ixgbe_get_active_nvm_ver; + mac->ops.get_thermal_sensor_data = NULL; + mac->ops.init_thermal_sensor_thresh = NULL; + + /* PHY */ + phy->ops.init = ixgbe_init_phy_ops_E610; + phy->ops.identify = ixgbe_identify_phy_E610; + + if (hw->device_id == IXGBE_DEV_ID_E610_2_5G_T) + phy->eee_speeds_supported = IXGBE_LINK_SPEED_2_5GB_FULL; + else + phy->eee_speeds_supported = IXGBE_LINK_SPEED_2_5GB_FULL | + IXGBE_LINK_SPEED_5GB_FULL | + IXGBE_LINK_SPEED_10GB_FULL; + + phy->eee_speeds_advertised = phy->eee_speeds_supported; + + /* Additional ops overrides for e610 to go here */ + eeprom->ops.init_params = ixgbe_init_eeprom_params_E610; + eeprom->ops.read = ixgbe_read_ee_aci_E610; + eeprom->ops.read_buffer = ixgbe_read_ee_aci_buffer_E610; + eeprom->ops.write = NULL; + eeprom->ops.write_buffer = NULL; + eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_E610; + eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_E610; + eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_E610; + eeprom->ops.read_pba_string = ixgbe_read_pba_string_E610; + + /* Initialize bus function number */ + hw->mac.ops.set_lan_id(hw); + + return ret_val; +} + +/** + * ixgbe_reset_hw_E610 - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks + * and clears all interrupts, and perform a reset. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_reset_hw_E610(struct ixgbe_hw *hw) +{ + u32 swfw_mask = hw->phy.phy_semaphore_mask; + u32 ctrl, i; + s32 status; + + DEBUGFUNC("ixgbe_reset_hw_E610"); + + /* Call adapter stop to disable tx/rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); + if (status != IXGBE_SUCCESS) + goto reset_hw_out; + + /* flush pending Tx transactions */ + ixgbe_clear_tx_pending(hw); + + status = hw->phy.ops.init(hw); + if (status != IXGBE_SUCCESS) + hw_dbg(hw, "Failed to initialize PHY ops, STATUS = %d\n", + status); +mac_reset_top: + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return IXGBE_ERR_SWFW_SYNC; + } + ctrl = IXGBE_CTRL_RST; + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + + /* Poll for reset bit to self-clear indicating reset is complete */ + for (i = 0; i < 10; i++) { + usec_delay(1); + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST_MASK)) + break; + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { + status = IXGBE_ERR_RESET_FAILED; + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "Reset polling failed to complete.\n"); + } + msec_delay(100); + + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + goto mac_reset_top; + } + + /* Set the Rx packet buffer size. */ + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. Also reset num_rar_entries to 128, + * since we modify this value when programming the SAN MAC address. + */ + hw->mac.num_rar_entries = 128; + hw->mac.ops.init_rx_addrs(hw); + +reset_hw_out: + return status; +} +/** + * ixgbe_start_hw_E610 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Gets firmware version and if API version matches it + * starts the hardware using the generic start_hw function + * and the generation start_hw function. + * Then performs revision-specific operations, if any. + **/ +s32 ixgbe_start_hw_E610(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + + ret_val = hw->mac.ops.get_fw_version(hw); + if (ret_val) + goto out; + + ret_val = ixgbe_start_hw_generic(hw); + if (ret_val != IXGBE_SUCCESS) + goto out; + + ixgbe_start_hw_gen2(hw); + +out: + return ret_val; +} + +/** + * ixgbe_get_media_type_E610 - Gets media type + * @hw: pointer to the HW struct + * + * In order to get the media type, the function gets PHY + * capabilities and later on use them to identify the PHY type + * checking phy_type_high and phy_type_low. + * + * Return: the type of media in form of ixgbe_media_type enum + * or ixgbe_media_type_unknown in case of an error. + */ +enum ixgbe_media_type ixgbe_get_media_type_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_phy_caps_data pcaps; + u64 phy_mask = 0; + s32 rc; + u8 i; + + rc = ixgbe_update_link_info(hw); + if (rc) { + return ixgbe_media_type_unknown; + } + + /* If there is no link but PHY (dongle) is available SW should use + * Get PHY Caps admin command instead of Get Link Status, find most + * significant bit that is set in PHY types reported by the command + * and use it to discover media type. + */ + if (!(hw->link.link_info.link_info & IXGBE_ACI_LINK_UP) && + (hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE)) { + /* Get PHY Capabilities */ + rc = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_TOPO_CAP_MEDIA, + &pcaps); + if (rc) { + return ixgbe_media_type_unknown; + } + + /* Check if there is some bit set in phy_type_high */ + for (i = 64; i > 0; i--) { + phy_mask = (u64)((u64)1 << (i - 1)); + if ((pcaps.phy_type_high & phy_mask) != 0) { + /* If any bit is set treat it as PHY type */ + hw->link.link_info.phy_type_high = phy_mask; + hw->link.link_info.phy_type_low = 0; + break; + } + phy_mask = 0; + } + + /* If nothing found in phy_type_high search in phy_type_low */ + if (phy_mask == 0) { + for (i = 64; i > 0; i--) { + phy_mask = (u64)((u64)1 << (i - 1)); + if ((pcaps.phy_type_low & phy_mask) != 0) { + /* If any bit is set treat it as PHY type */ + hw->link.link_info.phy_type_high = 0; + hw->link.link_info.phy_type_low = phy_mask; + break; + } + } + } + + } + + /* Based on link status or search above try to discover media type */ + hw->phy.media_type = ixgbe_get_media_type_from_phy_type(hw); + + return hw->phy.media_type; +} + +/** + * ixgbe_get_supported_physical_layer_E610 - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + * + * Return: the exit code of the operation. + **/ +u64 ixgbe_get_supported_physical_layer_E610(struct ixgbe_hw *hw) +{ + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + struct ixgbe_aci_cmd_get_phy_caps_data pcaps; + u64 phy_type; + s32 rc; + + rc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_TOPO_CAP_MEDIA, + &pcaps); + if (rc) + return IXGBE_PHYSICAL_LAYER_UNKNOWN; + + phy_type = IXGBE_LE64_TO_CPU(pcaps.phy_type_low); + if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_T) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if(phy_type & IXGBE_PHY_TYPE_LOW_1000BASE_T) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if(phy_type & IXGBE_PHY_TYPE_LOW_100BASE_TX) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_LR) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_LR; + if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_SR) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_SR; + if(phy_type & IXGBE_PHY_TYPE_LOW_1000BASE_KX) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; + if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR; + if(phy_type & IXGBE_PHY_TYPE_LOW_1000BASE_SX) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_SX; + if(phy_type & IXGBE_PHY_TYPE_LOW_2500BASE_KX) + physical_layer |= IXGBE_PHYSICAL_LAYER_2500BASE_KX; + if(phy_type & IXGBE_PHY_TYPE_LOW_2500BASE_T) + physical_layer |= IXGBE_PHYSICAL_LAYER_2500BASE_T; + if(phy_type & IXGBE_PHY_TYPE_LOW_5GBASE_T) + physical_layer |= IXGBE_PHYSICAL_LAYER_5000BASE_T; + + phy_type = IXGBE_LE64_TO_CPU(pcaps.phy_type_high); + if(phy_type & IXGBE_PHY_TYPE_HIGH_10BASE_T) + physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T; + + return physical_layer; +} + +/** + * ixgbe_setup_link_E610 - Set up link + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait: true when waiting for completion is needed + * + * Set up the link with the specified speed. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_setup_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait) +{ + + /* Simply request FW to perform proper PHY setup */ + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); +} + +/** + * ixgbe_check_link_E610 - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Determine if the link is up and the current link speed + * using ACI command (0x0607). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_check_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + s32 rc; + u32 i; + + if (!speed || !link_up) + return IXGBE_ERR_PARAM; + + /* Set get_link_info flag to ensure that fresh + * link information will be obtained from FW + * by sending Get Link Status admin command. */ + hw->link.get_link_info = true; + + /* Update link information in adapter context. */ + rc = ixgbe_get_link_status(hw, link_up); + if (rc) + return rc; + + /* Wait for link up if it was requested. */ + if (link_up_wait_to_complete && *link_up == false) { + for (i = 0; i < hw->mac.max_link_up_time; i++) { + msec_delay(100); + hw->link.get_link_info = true; + rc = ixgbe_get_link_status(hw, link_up); + if (rc) + return rc; + if (*link_up) + break; + } + } + + /* Use link information in adapter context updated by the call + * to ixgbe_get_link_status() to determine current link speed. + * Link speed information is valid only when link up was + * reported by FW. */ + if (*link_up) { + switch (hw->link.link_info.link_speed) { + case IXGBE_ACI_LINK_SPEED_10MB: + *speed = IXGBE_LINK_SPEED_10_FULL; + break; + case IXGBE_ACI_LINK_SPEED_100MB: + *speed = IXGBE_LINK_SPEED_100_FULL; + break; + case IXGBE_ACI_LINK_SPEED_1000MB: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + case IXGBE_ACI_LINK_SPEED_2500MB: + *speed = IXGBE_LINK_SPEED_2_5GB_FULL; + break; + case IXGBE_ACI_LINK_SPEED_5GB: + *speed = IXGBE_LINK_SPEED_5GB_FULL; + break; + case IXGBE_ACI_LINK_SPEED_10GB: + *speed = IXGBE_LINK_SPEED_10GB_FULL; + break; + default: + *speed = IXGBE_LINK_SPEED_UNKNOWN; + break; + } + } else { + *speed = IXGBE_LINK_SPEED_UNKNOWN; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_link_capabilities_E610 - Determine link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: true when autoneg or autotry is enabled + * + * Determine speed and AN parameters of a link. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_link_capabilities_E610(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + + if (!speed || !autoneg) + return IXGBE_ERR_PARAM; + + *autoneg = true; + *speed = hw->phy.speeds_supported; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_cfg_phy_fc - Configure PHY Flow Control (FC) data based on FC mode + * @hw: pointer to hardware structure + * @cfg: PHY configuration data to set FC mode + * @req_mode: FC mode to configure + * + * Configures PHY Flow Control according to the provided configuration. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_cfg_phy_fc(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg, + enum ixgbe_fc_mode req_mode) +{ + struct ixgbe_aci_cmd_get_phy_caps_data* pcaps = NULL; + s32 status = IXGBE_SUCCESS; + u8 pause_mask = 0x0; + + if (!cfg) + return IXGBE_ERR_PARAM; + + switch (req_mode) { + case ixgbe_fc_full: + pause_mask |= IXGBE_ACI_PHY_EN_TX_LINK_PAUSE; + pause_mask |= IXGBE_ACI_PHY_EN_RX_LINK_PAUSE; + break; + case ixgbe_fc_rx_pause: + pause_mask |= IXGBE_ACI_PHY_EN_RX_LINK_PAUSE; + break; + case ixgbe_fc_tx_pause: + pause_mask |= IXGBE_ACI_PHY_EN_TX_LINK_PAUSE; + break; + default: + break; + } + + /* clear the old pause settings */ + cfg->caps &= ~(IXGBE_ACI_PHY_EN_TX_LINK_PAUSE | + IXGBE_ACI_PHY_EN_RX_LINK_PAUSE); + + /* set the new capabilities */ + cfg->caps |= pause_mask; + + if (pcaps) + ixgbe_free(hw, pcaps); + return status; +} + +/** + * ixgbe_setup_fc_E610 - Set up flow control + * @hw: pointer to hardware structure + * + * Set up flow control. This has to be done during init time. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_setup_fc_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_phy_caps_data pcaps = { 0 }; + struct ixgbe_aci_cmd_set_phy_cfg_data cfg = { 0 }; + s32 status; + + /* Get the current PHY config */ + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_ACTIVE_CFG, &pcaps); + if (status) + return status; + + ixgbe_copy_phy_caps_to_cfg(&pcaps, &cfg); + + /* Configure the set PHY data */ + status = ixgbe_cfg_phy_fc(hw, &cfg, hw->fc.requested_mode); + if (status) + return status; + + /* If the capabilities have changed, then set the new config */ + if (cfg.caps != pcaps.caps) { + cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT; + + status = ixgbe_aci_set_phy_cfg(hw, &cfg); + if (status) + return status; + } + + return status; +} + +/** + * ixgbe_fc_autoneg_E610 - Configure flow control + * @hw: pointer to hardware structure + * + * Configure Flow Control. + */ +void ixgbe_fc_autoneg_E610(struct ixgbe_hw *hw) +{ + s32 status; + + /* Get current link status. + * Current FC mode will be stored in the hw context. */ + status = ixgbe_aci_get_link_info(hw, false, NULL); + if (status) { + goto out; + } + + /* Check if the link is up */ + if (!(hw->link.link_info.link_info & IXGBE_ACI_LINK_UP)) { + status = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + /* Check if auto-negotiation has completed */ + if (!(hw->link.link_info.an_info & IXGBE_ACI_AN_COMPLETED)) { + status = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + +out: + if (status == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = true; + } else { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + } +} + +/** + * ixgbe_set_fw_drv_ver_E610 - Send driver version to FW + * @hw: pointer to the HW structure + * @maj: driver version major number + * @minor: driver version minor number + * @build: driver version build number + * @sub: driver version sub build number + * @len: length of driver_ver string + * @driver_ver: driver string + * + * Send driver version number to Firmware using ACI command (0x0002). + * + * Return: the exit code of the operation. + * IXGBE_SUCCESS - OK + * IXGBE_ERR_PARAM - incorrect parameters were given + * IXGBE_ERR_ACI_ERROR - encountered an error during sending the command + * IXGBE_ERR_ACI_TIMEOUT - a timeout occurred + * IXGBE_ERR_OUT_OF_MEM - ran out of memory + */ +s32 ixgbe_set_fw_drv_ver_E610(struct ixgbe_hw *hw, u8 maj, u8 minor, u8 build, + u8 sub, u16 len, const char *driver_ver) +{ + size_t limited_len = min(len, (u16)IXGBE_DRV_VER_STR_LEN_E610); + struct ixgbe_driver_ver dv; + + DEBUGFUNC("ixgbe_set_fw_drv_ver_E610"); + + if (!len || !driver_ver) + return IXGBE_ERR_PARAM; + + dv.major_ver = maj; + dv.minor_ver = minor; + dv.build_ver = build; + dv.subbuild_ver = sub; + + memset(dv.driver_string, 0, IXGBE_DRV_VER_STR_LEN_E610); + memcpy(dv.driver_string, driver_ver, limited_len); + + return ixgbe_aci_send_driver_ver(hw, &dv); +} + +/** + * ixgbe_disable_rx_E610 - Disable RX unit + * @hw: pointer to hardware structure + * + * Disable RX DMA unit on E610 with use of ACI command (0x000C). + * + * Return: the exit code of the operation. + */ +void ixgbe_disable_rx_E610(struct ixgbe_hw *hw) +{ + u32 rxctrl; + + DEBUGFUNC("ixgbe_disable_rx_E610"); + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + u32 pfdtxgswc; + s32 status; + + pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) { + pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben = true; + } else { + hw->mac.set_lben = false; + } + + status = ixgbe_aci_disable_rxen(hw); + + /* If we fail - disable RX using register write */ + if (status) { + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + rxctrl &= ~IXGBE_RXCTRL_RXEN; + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); + } + } + } +} + +/** + * ixgbe_setup_eee_E610 - Enable/disable EEE support + * @hw: pointer to the HW structure + * @enable_eee: boolean flag to enable EEE + * + * Enables/disable EEE based on enable_eee flag. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_setup_eee_E610(struct ixgbe_hw *hw, bool enable_eee) +{ + struct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 }; + struct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 }; + u16 eee_cap = 0; + s32 status; + + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps); + if (status != IXGBE_SUCCESS) + return status; + + ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg); + + phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LINK; + phy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT; + + /* setup only speeds which are defined for [0x0601/0x0600].eee_cap */ + if (enable_eee) { + if (hw->phy.eee_speeds_advertised & IXGBE_LINK_SPEED_100_FULL) + eee_cap |= IXGBE_ACI_PHY_EEE_EN_100BASE_TX; + if (hw->phy.eee_speeds_advertised & IXGBE_LINK_SPEED_1GB_FULL) + eee_cap |= IXGBE_ACI_PHY_EEE_EN_1000BASE_T; + if (hw->phy.eee_speeds_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) + eee_cap |= IXGBE_ACI_PHY_EEE_EN_2_5GBASE_T; + if (hw->phy.eee_speeds_advertised & IXGBE_LINK_SPEED_5GB_FULL) + eee_cap |= IXGBE_ACI_PHY_EEE_EN_5GBASE_T; + if (hw->phy.eee_speeds_advertised & IXGBE_LINK_SPEED_10GB_FULL) + eee_cap |= IXGBE_ACI_PHY_EEE_EN_10GBASE_T; + } + + phy_cfg.eee_cap = IXGBE_CPU_TO_LE16(eee_cap); + + status = ixgbe_aci_set_phy_cfg(hw, &phy_cfg); + + return status; +} + +/** + * ixgbe_fw_recovery_mode_E610 - Check FW NVM recovery mode + * @hw: pointer to hardware structure + * + * Checks FW NVM recovery mode by + * reading the value of the dedicated register. + * + * Return: true if FW is in recovery mode, otherwise false. + */ +bool ixgbe_fw_recovery_mode_E610(struct ixgbe_hw *hw) +{ + u32 fwsm = IXGBE_READ_REG(hw, GL_MNG_FWSM); + + return !!(fwsm & GL_MNG_FWSM_FW_MODES_RECOVERY_M); +} + +/** + * ixgbe_fw_rollback_mode_E610 - Check FW NVM Rollback + * @hw: pointer to hardware structure + * + * Checks FW NVM Rollback mode by reading the + * value of the dedicated register. + * + * Return: true if FW is in Rollback mode, otherwise false. + */ +bool ixgbe_fw_rollback_mode_E610(struct ixgbe_hw *hw) +{ + u32 fwsm = IXGBE_READ_REG(hw, GL_MNG_FWSM); + + return !!(fwsm & GL_MNG_FWSM_FW_MODES_ROLLBACK_M); +} + +/** + * ixgbe_get_fw_tsam_mode_E610 - Check FW NVM Thermal Sensor Autonomous Mode + * @hw: pointer to hardware structure + * + * Checks Thermal Sensor Autonomous Mode by reading the + * value of the dedicated register. + * + * Return: true if FW is in TSAM, otherwise false. + */ +bool ixgbe_get_fw_tsam_mode_E610(struct ixgbe_hw *hw) +{ + u32 fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_X550EM_a); + + return !!(fwsm & IXGBE_FWSM_TS_ENABLED); +} + +/** + * ixgbe_init_phy_ops_E610 - PHY specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY type was not known. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_init_phy_ops_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val; + + phy->ops.identify_sfp = ixgbe_identify_module_E610; + phy->ops.read_reg = NULL; /* PHY reg access is not required */ + phy->ops.write_reg = NULL; + phy->ops.read_reg_mdi = NULL; + phy->ops.write_reg_mdi = NULL; + phy->ops.setup_link = ixgbe_setup_phy_link_E610; + phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_E610; + phy->ops.read_i2c_byte = NULL; /* disabled for E610 */ + phy->ops.write_i2c_byte = NULL; /* disabled for E610 */ + phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_E610; + phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_E610; + phy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_E610; + phy->ops.i2c_bus_clear = NULL; /* do not use generic implementation */ + phy->ops.check_overtemp = ixgbe_check_overtemp_E610; + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) + phy->ops.set_phy_power = ixgbe_set_phy_power_E610; + else + phy->ops.set_phy_power = NULL; + phy->ops.enter_lplu = ixgbe_enter_lplu_E610; + phy->ops.handle_lasi = NULL; /* no implementation for E610 */ + phy->ops.read_i2c_byte_unlocked = NULL; /* disabled for E610 */ + phy->ops.write_i2c_byte_unlocked = NULL; /* disabled for E610 */ + + /* TODO: Set functions pointers based on device ID */ + + /* Identify the PHY */ + ret_val = phy->ops.identify(hw); + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* TODO: Set functions pointers based on PHY type */ + + return ret_val; +} + +/** + * ixgbe_identify_phy_E610 - Identify PHY + * @hw: pointer to hardware structure + * + * Determine PHY type, supported speeds and PHY ID. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_identify_phy_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_phy_caps_data pcaps; + s32 rc; + + /* Set PHY type */ + hw->phy.type = ixgbe_phy_fw; + + rc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_TOPO_CAP_MEDIA, + &pcaps); + if (rc) + return rc; + + if (!(pcaps.module_compliance_enforcement & + IXGBE_ACI_MOD_ENFORCE_STRICT_MODE)) { + /* Handle lenient mode */ + rc = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_TOPO_CAP_NO_MEDIA, + &pcaps); + if (rc) + return rc; + } + + /* Determine supported speeds */ + hw->phy.speeds_supported = IXGBE_LINK_SPEED_UNKNOWN; + + if (pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10BASE_T || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10M_SGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10_FULL; + if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_100BASE_TX || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_100M_SGMII || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_100M_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL; + if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_T || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_SX || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_LX || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_KX || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1G_SGMII || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_1G_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL; + if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_T || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_X || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_KX || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_SGMII || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL; + if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_T || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_KR || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_5G_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; + if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_T || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_DA || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_SR || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_LR || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1 || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC || + pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_C2C || + pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10G_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL; + + /* Initialize autoneg speeds */ + if (!hw->phy.autoneg_advertised) + hw->phy.autoneg_advertised = hw->phy.speeds_supported; + + /* Set PHY ID */ + memcpy(&hw->phy.id, pcaps.phy_id_oui, sizeof(u32)); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_identify_module_E610 - Identify SFP module type + * @hw: pointer to hardware structure + * + * Identify the SFP module type. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_identify_module_E610(struct ixgbe_hw *hw) +{ + bool media_available; + u8 module_type; + s32 rc; + + rc = ixgbe_update_link_info(hw); + if (rc) + goto err; + + media_available = + (hw->link.link_info.link_info & + IXGBE_ACI_MEDIA_AVAILABLE) ? true : false; + + if (media_available) { + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + + /* Get module type from hw context updated by ixgbe_update_link_info() */ + module_type = hw->link.link_info.module_type[IXGBE_ACI_MOD_TYPE_IDENT]; + + if ((module_type & IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE) || + (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE)) { + hw->phy.sfp_type = ixgbe_sfp_type_da_cu; + } else if (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_SR) { + hw->phy.sfp_type = ixgbe_sfp_type_sr; + } else if ((module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LR) || + (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LRM)) { + hw->phy.sfp_type = ixgbe_sfp_type_lr; + } + rc = IXGBE_SUCCESS; + } else { + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + rc = IXGBE_ERR_SFP_NOT_PRESENT; + } +err: + return rc; +} + +/** + * ixgbe_setup_phy_link_E610 - Sets up firmware-controlled PHYs + * @hw: pointer to hardware structure + * + * Set the parameters for the firmware-controlled PHYs. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_setup_phy_link_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_phy_caps_data pcaps; + struct ixgbe_aci_cmd_set_phy_cfg_data pcfg; + u8 rmode = IXGBE_ACI_REPORT_TOPO_CAP_MEDIA; + u64 sup_phy_type_low, sup_phy_type_high; + s32 rc; + + rc = ixgbe_aci_get_link_info(hw, false, NULL); + if (rc) { + goto err; + } + + /* If media is not available get default config */ + if (!(hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE)) + rmode = IXGBE_ACI_REPORT_DFLT_CFG; + + rc = ixgbe_aci_get_phy_caps(hw, false, rmode, &pcaps); + if (rc) { + goto err; + } + + sup_phy_type_low = pcaps.phy_type_low; + sup_phy_type_high = pcaps.phy_type_high; + + /* Get Active configuration to avoid unintended changes */ + rc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_ACTIVE_CFG, + &pcaps); + if (rc) { + goto err; + } + ixgbe_copy_phy_caps_to_cfg(&pcaps, &pcfg); + + /* Set default PHY types for a given speed */ + pcfg.phy_type_low = 0; + pcfg.phy_type_high = 0; + + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL) { + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10BASE_T; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10M_SGMII; + } + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) { + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_100BASE_TX; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_100M_SGMII; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_100M_USXGMII; + } + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) { + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_T; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_SX; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_LX; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_KX; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1G_SGMII; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_1G_USXGMII; + } + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) { + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_2500BASE_T; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_2500BASE_X; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_2500BASE_KX; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_2500M_SGMII; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_2500M_USXGMII; + } + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) { + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_5GBASE_T; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_5GBASE_KR; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_5G_USXGMII; + } + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) { + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_T; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10G_SFI_DA; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_SR; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_LR; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC; + pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10G_SFI_C2C; + pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10G_USXGMII; + } + + /* Mask the set values to avoid requesting unsupported link types */ + pcfg.phy_type_low &= sup_phy_type_low; + pcfg.phy_type_high &= sup_phy_type_high; + + if (pcfg.phy_type_high != pcaps.phy_type_high || + pcfg.phy_type_low != pcaps.phy_type_low || + pcfg.caps != pcaps.caps) { + pcfg.caps |= IXGBE_ACI_PHY_ENA_LINK; + pcfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT; + + rc = ixgbe_aci_set_phy_cfg(hw, &pcfg); + } + +err: + return rc; +} + +/** + * ixgbe_get_phy_firmware_version_E610 - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + * + * Determines PHY FW version based on response to Get PHY Capabilities + * admin command (0x0600). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_phy_firmware_version_E610(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + struct ixgbe_aci_cmd_get_phy_caps_data pcaps; + s32 status; + + if (!firmware_version) + return IXGBE_ERR_PARAM; + + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_ACTIVE_CFG, + &pcaps); + if (status) + return status; + + /* TODO: determine which bytes of the 8-byte phy_fw_ver + * field should be written to the 2-byte firmware_version + * output argument. */ + memcpy(firmware_version, pcaps.phy_fw_ver, sizeof(u16)); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_i2c_sff8472_E610 - Reads 8 bit word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: byte offset at address 0xA2 + * @sff8472_data: value read + * + * Performs byte read operation from SFP module's SFF-8472 data over I2C. + * + * Return: the exit code of the operation. + **/ +s32 ixgbe_read_i2c_sff8472_E610(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data) +{ + return ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR2, + byte_offset, 0, + IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE, + sff8472_data, 1, false); +} + +/** + * ixgbe_read_i2c_eeprom_E610 - Reads 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to read + * @eeprom_data: value read + * + * Performs byte read operation from SFP module's EEPROM over I2C interface. + * + * Return: the exit code of the operation. + **/ +s32 ixgbe_read_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data) +{ + return ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR, + byte_offset, 0, + IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE, + eeprom_data, 1, false); +} + +/** + * ixgbe_write_i2c_eeprom_E610 - Writes 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to write + * @eeprom_data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface. + * + * Return: the exit code of the operation. + **/ +s32 ixgbe_write_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data) +{ + return ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR, + byte_offset, 0, + IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE, + &eeprom_data, 1, true); +} + +/** + * ixgbe_check_overtemp_E610 - Check firmware-controlled PHYs for overtemp + * @hw: pointer to hardware structure + * + * Get the link status and check if the PHY temperature alarm detected. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_check_overtemp_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_link_status_data link_data = { 0 }; + struct ixgbe_aci_cmd_get_link_status *resp; + struct ixgbe_aci_desc desc; + s32 status = IXGBE_SUCCESS; + + if (!hw) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_status); + resp = &desc.params.get_link_status; + resp->cmd_flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_LSE_NOP); + + status = ixgbe_aci_send_cmd(hw, &desc, &link_data, sizeof(link_data)); + if (status != IXGBE_SUCCESS) + return status; + + if (link_data.ext_info & IXGBE_ACI_LINK_PHY_TEMP_ALARM) { + ERROR_REPORT1(IXGBE_ERROR_CAUTION, + "PHY Temperature Alarm detected"); + status = IXGBE_ERR_OVERTEMP; + } + + return status; +} + +/** + * ixgbe_set_phy_power_E610 - Control power for copper PHY + * @hw: pointer to hardware structure + * @on: true for on, false for off + * + * Set the power on/off of the PHY + * by getting its capabilities and setting the appropriate + * configuration parameters. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_set_phy_power_E610(struct ixgbe_hw *hw, bool on) +{ + struct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 }; + struct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 }; + s32 status; + + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps); + if (status != IXGBE_SUCCESS) + return status; + + ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg); + + if (on) { + phy_cfg.caps &= ~IXGBE_ACI_PHY_ENA_LOW_POWER; + } else { + phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LOW_POWER; + } + + /* PHY is already in requested power mode */ + if (phy_caps.caps == phy_cfg.caps) + return IXGBE_SUCCESS; + + phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LINK; + phy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT; + + status = ixgbe_aci_set_phy_cfg(hw, &phy_cfg); + + return status; +} + +/** + * ixgbe_enter_lplu_E610 - Transition to low power states + * @hw: pointer to hardware structure + * + * Configures Low Power Link Up on transition to low power states + * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the + * X557 PHY immediately prior to entering LPLU. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_enter_lplu_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 }; + struct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 }; + s32 status; + + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps); + if (status != IXGBE_SUCCESS) + return status; + + ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg); + + phy_cfg.low_power_ctrl_an |= IXGBE_ACI_PHY_EN_D3COLD_LOW_POWER_AUTONEG; + + status = ixgbe_aci_set_phy_cfg(hw, &phy_cfg); + + return status; +} + +/** + * ixgbe_init_eeprom_params_E610 - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_init_eeprom_params_E610(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 gens_stat; + u8 sr_size; + + if (eeprom->type == ixgbe_eeprom_uninitialized) { + eeprom->type = ixgbe_flash; + + gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS); + sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> + GLNVM_GENS_SR_SIZE_S; + + /* Switching to words (sr_size contains power of 2) */ + eeprom->word_size = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB; + + hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", + eeprom->type, eeprom->word_size); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_ee_aci_E610 - Read EEPROM word using the admin command. + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the ACI. + * If the EEPROM params are not initialized, the function + * initialize them before proceeding with reading. + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_read_ee_aci_E610(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + s32 status; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + status = ixgbe_init_eeprom_params(hw); + if (status) + return status; + } + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + status = ixgbe_read_sr_word_aci(hw, offset, data); + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_read_ee_aci_buffer_E610- Read EEPROM word(s) using admin commands. + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @words: number of words + * @data: word(s) read from the EEPROM + * + * Reads a 16 bit word(s) from the EEPROM using the ACI. + * If the EEPROM params are not initialized, the function + * initialize them before proceeding with reading. + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_read_ee_aci_buffer_E610(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data) +{ + s32 status; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + status = ixgbe_init_eeprom_params(hw); + if (status) + return status; + } + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + status = ixgbe_read_sr_buf_aci(hw, offset, &words, data); + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_calc_eeprom_checksum_E610 - Calculates and returns the checksum + * @hw: pointer to hardware structure + * + * Calculate SW Checksum that covers the whole 64kB shadow RAM + * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD + * is customer specific and unknown. Therefore, this function skips all maximum + * possible size of VPD (1kB). + * If the EEPROM params are not initialized, the function + * initializes them before proceeding. + * The function acquires and then releases the NVM ownership. + * + * Return: the negative error code on error, or the 16-bit checksum + */ +s32 ixgbe_calc_eeprom_checksum_E610(struct ixgbe_hw *hw) +{ + bool nvm_acquired = false; + u16 pcie_alt_module = 0; + u16 checksum_local = 0; + u16 checksum = 0; + u16 vpd_module; + void *vmem; + s32 status; + u16 *data; + u16 i; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + status = ixgbe_init_eeprom_params(hw); + if (status) + return status; + } + + vmem = ixgbe_calloc(hw, IXGBE_SR_SECTOR_SIZE_IN_WORDS, sizeof(u16)); + if (!vmem) + return IXGBE_ERR_OUT_OF_MEM; + data = (u16 *)vmem; + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + goto ixgbe_calc_sr_checksum_exit; + nvm_acquired = true; + + /* read pointer to VPD area */ + status = ixgbe_read_sr_word_aci(hw, E610_SR_VPD_PTR, &vpd_module); + if (status) + goto ixgbe_calc_sr_checksum_exit; + + /* read pointer to PCIe Alt Auto-load module */ + status = ixgbe_read_sr_word_aci(hw, E610_SR_PCIE_ALT_AUTO_LOAD_PTR, + &pcie_alt_module); + if (status) + goto ixgbe_calc_sr_checksum_exit; + + /* Calculate SW checksum that covers the whole 64kB shadow RAM + * except the VPD and PCIe ALT Auto-load modules + */ + for (i = 0; i < hw->eeprom.word_size; i++) { + /* Read SR page */ + if ((i % IXGBE_SR_SECTOR_SIZE_IN_WORDS) == 0) { + u16 words = IXGBE_SR_SECTOR_SIZE_IN_WORDS; + + status = ixgbe_read_sr_buf_aci(hw, i, &words, data); + if (status != IXGBE_SUCCESS) + goto ixgbe_calc_sr_checksum_exit; + } + + /* Skip Checksum word */ + if (i == E610_SR_SW_CHECKSUM_WORD) + continue; + /* Skip VPD module (convert byte size to word count) */ + if (i >= (u32)vpd_module && + i < ((u32)vpd_module + E610_SR_VPD_SIZE_WORDS)) + continue; + /* Skip PCIe ALT module (convert byte size to word count) */ + if (i >= (u32)pcie_alt_module && + i < ((u32)pcie_alt_module + E610_SR_PCIE_ALT_SIZE_WORDS)) + continue; + + checksum_local += data[i % IXGBE_SR_SECTOR_SIZE_IN_WORDS]; + } + + checksum = (u16)IXGBE_SR_SW_CHECKSUM_BASE - checksum_local; + +ixgbe_calc_sr_checksum_exit: + if(nvm_acquired) + ixgbe_release_nvm(hw); + ixgbe_free(hw, vmem); + + if(!status) + return (s32)checksum; + else + return status; +} + +/** + * ixgbe_update_eeprom_checksum_E610 - Updates the EEPROM checksum and flash + * @hw: pointer to hardware structure + * + * After writing EEPROM to Shadow RAM, software sends the admin command + * to recalculate and update EEPROM checksum and instructs the hardware + * to update the flash. + * If the EEPROM params are not initialized, the function + * initialize them before proceeding. + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_update_eeprom_checksum_E610(struct ixgbe_hw *hw) +{ + s32 status; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + status = ixgbe_init_eeprom_params(hw); + if (status) + return status; + } + + status = ixgbe_nvm_recalculate_checksum(hw); + if (status) + return status; + status = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); + if (status) + return status; + + status = ixgbe_nvm_write_activate(hw, IXGBE_ACI_NVM_ACTIV_REQ_EMPR, + NULL); + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_validate_eeprom_checksum_E610 - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If the + * caller does not need checksum_val, the value can be NULL. + * If the EEPROM params are not initialized, the function + * initialize them before proceeding. + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_validate_eeprom_checksum_E610(struct ixgbe_hw *hw, u16 *checksum_val) +{ + u32 status; + + if (hw->eeprom.type == ixgbe_eeprom_uninitialized) { + status = ixgbe_init_eeprom_params(hw); + if (status) + return status; + } + + status = ixgbe_nvm_validate_checksum(hw); + + if (status) + return status; + + if (checksum_val) { + u16 tmp_checksum; + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + status = ixgbe_read_sr_word_aci(hw, E610_SR_SW_CHECKSUM_WORD, + &tmp_checksum); + ixgbe_release_nvm(hw); + + if (!status) + *checksum_val = tmp_checksum; + } + + return status; +} + +/** + * ixgbe_get_pfa_module_tlv - Reads sub module TLV from NVM PFA + * @hw: pointer to hardware structure + * @module_tlv: pointer to module TLV to return + * @module_tlv_len: pointer to module TLV length to return + * @module_type: module type requested + * + * Finds the requested sub module TLV type from the Preserved Field + * Area (PFA) and returns the TLV pointer and length. The caller can + * use these to read the variable length TLV value. + * + * Return: the exit code of the operation. + */ +STATIC s32 ixgbe_get_pfa_module_tlv(struct ixgbe_hw *hw, u16 *module_tlv, + u16 *module_tlv_len, u16 module_type) +{ + u16 pfa_len, pfa_ptr, pfa_end_ptr; + u16 next_tlv; + s32 status; + + status = ixgbe_read_ee_aci_E610(hw, E610_SR_PFA_PTR, &pfa_ptr); + if (status != IXGBE_SUCCESS) { + return status; + } + status = ixgbe_read_ee_aci_E610(hw, pfa_ptr, &pfa_len); + if (status != IXGBE_SUCCESS) { + return status; + } + /* Starting with first TLV after PFA length, iterate through the list + * of TLVs to find the requested one. + */ + next_tlv = pfa_ptr + 1; + pfa_end_ptr = pfa_ptr + pfa_len; + while (next_tlv < pfa_end_ptr) { + u16 tlv_sub_module_type, tlv_len; + + /* Read TLV type */ + status = ixgbe_read_ee_aci_E610(hw, next_tlv, + &tlv_sub_module_type); + if (status != IXGBE_SUCCESS) { + break; + } + /* Read TLV length */ + status = ixgbe_read_ee_aci_E610(hw, next_tlv + 1, &tlv_len); + if (status != IXGBE_SUCCESS) { + break; + } + if (tlv_sub_module_type == module_type) { + if (tlv_len) { + *module_tlv = next_tlv; + *module_tlv_len = tlv_len; + return IXGBE_SUCCESS; + } + return IXGBE_ERR_INVAL_SIZE; + } + /* Check next TLV, i.e. current TLV pointer + length + 2 words + * (for current TLV's type and length) + */ + next_tlv = next_tlv + tlv_len + 2; + } + /* Module does not exist */ + return IXGBE_ERR_DOES_NOT_EXIST; +} + +/** + * ixgbe_read_pba_string_E610 - Reads part number string from NVM + * @hw: pointer to hardware structure + * @pba_num: stores the part number string from the NVM + * @pba_num_size: part number string buffer length + * + * Reads the part number string from the NVM. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_read_pba_string_E610(struct ixgbe_hw *hw, u8 *pba_num, + u32 pba_num_size) +{ + u16 pba_tlv, pba_tlv_len; + u16 pba_word, pba_size; + s32 status; + u16 i; + + status = ixgbe_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len, + E610_SR_PBA_BLOCK_PTR); + if (status != IXGBE_SUCCESS) { + return status; + } + + /* pba_size is the next word */ + status = ixgbe_read_ee_aci_E610(hw, (pba_tlv + 2), &pba_size); + if (status != IXGBE_SUCCESS) { + return status; + } + + if (pba_tlv_len < pba_size) { + return IXGBE_ERR_INVAL_SIZE; + } + + /* Subtract one to get PBA word count (PBA Size word is included in + * total size) + */ + pba_size--; + if (pba_num_size < (((u32)pba_size * 2) + 1)) { + return IXGBE_ERR_PARAM; + } + + for (i = 0; i < pba_size; i++) { + status = ixgbe_read_ee_aci_E610(hw, (pba_tlv + 2 + 1) + i, + &pba_word); + if (status != IXGBE_SUCCESS) { + return status; + } + + pba_num[(i * 2)] = (pba_word >> 8) & 0xFF; + pba_num[(i * 2) + 1] = pba_word & 0xFF; + } + pba_num[(pba_size * 2)] = '\0'; + + return status; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.h new file mode 100644 index 0000000000..18b9723470 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_e610.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_E610_H_ +#define _IXGBE_E610_H_ + +#include "ixgbe_type.h" + +void ixgbe_init_aci(struct ixgbe_hw *hw); +void ixgbe_shutdown_aci(struct ixgbe_hw *hw); + +void ixgbe_aci_debug(struct ixgbe_hw *hw, void *desc, void *buf, u16 buf_len); + +s32 ixgbe_aci_send_cmd(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc, + void *buf, u16 buf_size); +bool ixgbe_aci_check_event_pending(struct ixgbe_hw *hw); +s32 ixgbe_aci_get_event(struct ixgbe_hw *hw, struct ixgbe_aci_event *e, + bool *pending); + +void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc *desc, u16 opcode); + +s32 ixgbe_aci_get_fw_ver(struct ixgbe_hw *hw); +s32 ixgbe_aci_send_driver_ver(struct ixgbe_hw *hw, struct ixgbe_driver_ver *dv); +s32 ixgbe_aci_set_pf_context(struct ixgbe_hw *hw, u8 pf_id); + +s32 ixgbe_acquire_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res, + enum ixgbe_aci_res_access_type access, u32 timeout); +void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res); +s32 ixgbe_aci_list_caps(struct ixgbe_hw *hw, void *buf, u16 buf_size, + u32 *cap_count, enum ixgbe_aci_opc opc); +s32 ixgbe_discover_dev_caps(struct ixgbe_hw *hw, + struct ixgbe_hw_dev_caps *dev_caps); +s32 ixgbe_discover_func_caps(struct ixgbe_hw* hw, + struct ixgbe_hw_func_caps* func_caps); +s32 ixgbe_get_caps(struct ixgbe_hw *hw); +s32 ixgbe_aci_disable_rxen(struct ixgbe_hw *hw); +s32 ixgbe_aci_get_phy_caps(struct ixgbe_hw *hw, bool qual_mods, u8 report_mode, + struct ixgbe_aci_cmd_get_phy_caps_data *pcaps); +bool ixgbe_phy_caps_equals_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg); +void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg); +s32 ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg); +s32 ixgbe_aci_set_link_restart_an(struct ixgbe_hw *hw, bool ena_link); +s32 ixgbe_update_link_info(struct ixgbe_hw *hw); +s32 ixgbe_get_link_status(struct ixgbe_hw *hw, bool *link_up); +s32 ixgbe_aci_get_link_info(struct ixgbe_hw *hw, bool ena_lse, + struct ixgbe_link_status *link); +s32 ixgbe_aci_set_event_mask(struct ixgbe_hw *hw, u8 port_num, u16 mask); +s32 ixgbe_configure_lse(struct ixgbe_hw *hw, bool activate, u16 mask); + +#ifndef NO_PTP_SUPPORT +s32 ixgbe_set_ptp_by_phy(struct ixgbe_hw *hw, u8 ptp_request, u8 flags); +s32 ixgbe_get_ptp_by_phy(struct ixgbe_hw *hw, u8 *ptp_config, u8 *flags, + u16 *max_drift_thresh); +#endif /* !NO_PTP_SUPPORT */ + +s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo *cmd, + u8 *node_part_number, u16 *node_handle); +#if !defined(NO_PTP_SUPPORT) +s32 ixgbe_aci_get_netlist_node_pin(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo_pin *cmd, + u16 *node_handle); +#endif /* !NO_PTP_SUPPORT */ +s32 ixgbe_find_netlist_node(struct ixgbe_hw *hw, u8 node_type_ctx, + u8 node_part_number, u16 *node_handle); +s32 ixgbe_aci_read_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data); +s32 ixgbe_aci_write_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data); +s32 ixgbe_aci_set_port_id_led(struct ixgbe_hw *hw, bool orig_mode); +s32 ixgbe_aci_set_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool value); +s32 ixgbe_aci_get_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool *value); +s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr, + u16 mem_addr, u8 page, u8 page_bank_ctrl, u8 *data, + u8 length, bool write); +s32 ixgbe_aci_prog_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params); +s32 ixgbe_aci_read_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params, + u32 start_address, u8 *data, u8 data_size); + +s32 ixgbe_acquire_nvm(struct ixgbe_hw *hw, + enum ixgbe_aci_res_access_type access); +void ixgbe_release_nvm(struct ixgbe_hw *hw); + +s32 ixgbe_aci_read_nvm(struct ixgbe_hw *hw, u16 module_typeid, u32 offset, + u16 length, void *data, bool last_command, + bool read_shadow_ram); + +s32 ixgbe_aci_erase_nvm(struct ixgbe_hw *hw, u16 module_typeid); +s32 ixgbe_aci_update_nvm(struct ixgbe_hw *hw, u16 module_typeid, + u32 offset, u16 length, void *data, + bool last_command, u8 command_flags); + +s32 ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw); +s32 ixgbe_nvm_recalculate_checksum(struct ixgbe_hw *hw); + +s32 ixgbe_nvm_write_activate(struct ixgbe_hw *hw, u16 cmd_flags, + u8 *response_flags); + +s32 ixgbe_get_nvm_minsrevs(struct ixgbe_hw *hw, struct ixgbe_minsrev_info *minsrevs); +s32 ixgbe_update_nvm_minsrevs(struct ixgbe_hw *hw, struct ixgbe_minsrev_info *minsrevs); +s32 ixgbe_get_inactive_orom_ver(struct ixgbe_hw *hw, struct ixgbe_orom_info *orom); +s32 ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm); +s32 ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm); +s32 ixgbe_get_inactive_netlist_ver(struct ixgbe_hw *hw, struct ixgbe_netlist_info *netlist); +s32 ixgbe_init_nvm(struct ixgbe_hw *hw); + +s32 ixgbe_aci_nvm_update_empr(struct ixgbe_hw *hw); +s32 ixgbe_nvm_set_pkg_data(struct ixgbe_hw *hw, bool del_pkg_data_flag, + u8 *data, u16 length); +s32 ixgbe_nvm_pass_component_tbl(struct ixgbe_hw *hw, u8 *data, u16 length, + u8 transfer_flag, u8 *comp_response, + u8 *comp_response_code); + +s32 ixgbe_sanitize_operate(struct ixgbe_hw *hw); +s32 ixgbe_sanitize_nvm(struct ixgbe_hw *hw, u8 cmd_flags, u8 *values); + +s32 ixgbe_read_sr_word_aci(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_sr_buf_aci(struct ixgbe_hw *hw, u16 offset, u16 *words, u16 *data); +s32 ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length, + u8 *data, bool read_shadow_ram); + +s32 ixgbe_aci_alternate_write(struct ixgbe_hw *hw, u32 reg_addr0, + u32 reg_val0, u32 reg_addr1, u32 reg_val1); +s32 ixgbe_aci_alternate_read(struct ixgbe_hw *hw, u32 reg_addr0, + u32 *reg_val0, u32 reg_addr1, u32 *reg_val1); +s32 ixgbe_aci_alternate_write_done(struct ixgbe_hw *hw, u8 bios_mode, + bool *reset_needed); +s32 ixgbe_aci_alternate_clear(struct ixgbe_hw *hw); + +s32 ixgbe_aci_get_internal_data(struct ixgbe_hw *hw, u16 cluster_id, + u16 table_id, u32 start, void *buf, + u16 buf_size, u16 *ret_buf_size, + u16 *ret_next_cluster, u16 *ret_next_table, + u32 *ret_next_index); + +s32 ixgbe_handle_nvm_access(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data); + +s32 ixgbe_aci_set_health_status_config(struct ixgbe_hw *hw, u8 event_source); +bool ixgbe_fwlog_supported(struct ixgbe_hw *hw); +s32 ixgbe_fwlog_set(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg); +s32 ixgbe_fwlog_update_modules(struct ixgbe_hw *hw, + struct ixgbe_fwlog_module_entry *entries, + u16 num_entries); +s32 ixgbe_fwlog_register(struct ixgbe_hw *hw); +s32 ixgbe_fwlog_unregister(struct ixgbe_hw *hw); +void ixgbe_fwlog_set_support_ena(struct ixgbe_hw *hw); +s32 ixgbe_fwlog_get(struct ixgbe_hw *hw, struct ixgbe_fwlog_cfg *cfg); +void ixgbe_fwlog_event_dump(struct ixgbe_hw *hw, + struct ixgbe_aci_desc *desc, void *buf); + +/* E610 operations */ +s32 ixgbe_reset_hw_E610(struct ixgbe_hw *hw); +s32 ixgbe_start_hw_E610(struct ixgbe_hw *hw); +enum ixgbe_media_type ixgbe_get_media_type_E610(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_E610(struct ixgbe_hw *hw); +s32 ixgbe_setup_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait); +s32 ixgbe_check_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); +s32 ixgbe_get_link_capabilities_E610(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); +s32 ixgbe_cfg_phy_fc(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg, + enum ixgbe_fc_mode req_mode); +s32 ixgbe_setup_fc_E610(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_E610(struct ixgbe_hw *hw); +s32 ixgbe_set_fw_drv_ver_E610(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, + u8 sub, u16 len, const char *driver_ver); +void ixgbe_disable_rx_E610(struct ixgbe_hw *hw); +s32 ixgbe_setup_eee_E610(struct ixgbe_hw *hw, bool enable_eee); +bool ixgbe_fw_recovery_mode_E610(struct ixgbe_hw *hw); +bool ixgbe_fw_rollback_mode_E610(struct ixgbe_hw *hw); +bool ixgbe_get_fw_tsam_mode_E610(struct ixgbe_hw *hw); +s32 ixgbe_init_phy_ops_E610(struct ixgbe_hw *hw); +s32 ixgbe_identify_phy_E610(struct ixgbe_hw *hw); +s32 ixgbe_identify_module_E610(struct ixgbe_hw *hw); +s32 ixgbe_setup_phy_link_E610(struct ixgbe_hw *hw); +s32 ixgbe_get_phy_firmware_version_E610(struct ixgbe_hw *hw, + u16 *firmware_version); +s32 ixgbe_read_i2c_sff8472_E610(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data); +s32 ixgbe_read_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data); +s32 ixgbe_write_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data); +s32 ixgbe_check_overtemp_E610(struct ixgbe_hw *hw); +s32 ixgbe_set_phy_power_E610(struct ixgbe_hw *hw, bool on); +s32 ixgbe_enter_lplu_E610(struct ixgbe_hw *hw); +s32 ixgbe_init_eeprom_params_E610(struct ixgbe_hw *hw); +s32 ixgbe_read_ee_aci_E610(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_ee_aci_buffer_E610(struct ixgbe_hw *hw, u16 offset, + u16 words, u16 *data); +s32 ixgbe_calc_eeprom_checksum_E610(struct ixgbe_hw *hw); +s32 ixgbe_update_eeprom_checksum_E610(struct ixgbe_hw *hw); +s32 ixgbe_validate_eeprom_checksum_E610(struct ixgbe_hw *hw, u16 *checksum_val); +s32 ixgbe_read_pba_string_E610(struct ixgbe_hw *hw, u8 *pba_num, u32 pba_num_size); + +#endif /* _IXGBE_E610_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ethtool.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ethtool.c new file mode 100644 index 0000000000..4c15ac31c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ethtool.c @@ -0,0 +1,6144 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* ethtool support for ixgbe */ + +#include "ixgbe.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef SIOCETHTOOL +#include + +#ifdef ETHTOOL_GMODULEINFO +#include "ixgbe_phy.h" +#endif +#ifdef HAVE_ETHTOOL_GET_TS_INFO +#include +#endif + +#ifndef ETH_GSTRING_LEN +#define ETH_GSTRING_LEN 32 +#endif + +#define IXGBE_ALL_RAR_ENTRIES 16 + +#ifdef HAVE_XDP_SUPPORT +#include +#endif +#include "ixgbe_txrx_common.h" +#ifdef ETHTOOL_OPS_COMPAT +#include "kcompat_ethtool.c" +#endif +#ifdef ETHTOOL_GSTATS +struct ixgbe_stats { + char stat_string[ETH_GSTRING_LEN]; + int sizeof_stat; + int stat_offset; +}; + +#define IXGBE_NETDEV_STAT(_net_stat) { \ + .stat_string = #_net_stat, \ + .sizeof_stat = sizeof_field(struct net_device_stats, _net_stat), \ + .stat_offset = offsetof(struct net_device_stats, _net_stat) \ +} +static const struct ixgbe_stats ixgbe_gstrings_net_stats[] = { + IXGBE_NETDEV_STAT(rx_packets), + IXGBE_NETDEV_STAT(tx_packets), + IXGBE_NETDEV_STAT(rx_bytes), + IXGBE_NETDEV_STAT(tx_bytes), + IXGBE_NETDEV_STAT(rx_errors), + IXGBE_NETDEV_STAT(tx_errors), + IXGBE_NETDEV_STAT(rx_dropped), + IXGBE_NETDEV_STAT(tx_dropped), + IXGBE_NETDEV_STAT(multicast), + IXGBE_NETDEV_STAT(collisions), + IXGBE_NETDEV_STAT(rx_over_errors), + IXGBE_NETDEV_STAT(rx_crc_errors), + IXGBE_NETDEV_STAT(rx_frame_errors), + IXGBE_NETDEV_STAT(rx_fifo_errors), + IXGBE_NETDEV_STAT(rx_missed_errors), + IXGBE_NETDEV_STAT(tx_aborted_errors), + IXGBE_NETDEV_STAT(tx_carrier_errors), + IXGBE_NETDEV_STAT(tx_fifo_errors), + IXGBE_NETDEV_STAT(tx_heartbeat_errors), +}; + +#define IXGBE_STAT(_name, _stat) { \ + .stat_string = _name, \ + .sizeof_stat = sizeof_field(struct ixgbe_adapter, _stat), \ + .stat_offset = offsetof(struct ixgbe_adapter, _stat) \ +} +static struct ixgbe_stats ixgbe_gstrings_stats[] = { + IXGBE_STAT("rx_pkts_nic", stats.gprc), + IXGBE_STAT("tx_pkts_nic", stats.gptc), + IXGBE_STAT("rx_bytes_nic", stats.gorc), + IXGBE_STAT("tx_bytes_nic", stats.gotc), + IXGBE_STAT("lsc_int", lsc_int), + IXGBE_STAT("tx_busy", tx_busy), + IXGBE_STAT("non_eop_descs", non_eop_descs), + IXGBE_STAT("broadcast", stats.bprc), + IXGBE_STAT("rx_no_buffer_count", stats.rnbc[0]) , + IXGBE_STAT("tx_timeout_count", tx_timeout_count), + IXGBE_STAT("tx_restart_queue", restart_queue), + IXGBE_STAT("rx_length_errors", stats.rlec), + IXGBE_STAT("rx_long_length_errors", stats.roc), + IXGBE_STAT("rx_short_length_errors", stats.ruc), + IXGBE_STAT("tx_flow_control_xon", stats.lxontxc), + IXGBE_STAT("rx_flow_control_xon", stats.lxonrxc), + IXGBE_STAT("tx_flow_control_xoff", stats.lxofftxc), + IXGBE_STAT("rx_flow_control_xoff", stats.lxoffrxc), + IXGBE_STAT("rx_csum_offload_errors", hw_csum_rx_error), + IXGBE_STAT("alloc_rx_page", alloc_rx_page), + IXGBE_STAT("alloc_rx_page_failed", alloc_rx_page_failed), + IXGBE_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed), + IXGBE_STAT("rx_no_dma_resources", hw_rx_no_dma_resources), + IXGBE_STAT("hw_rsc_aggregated", rsc_total_count), + IXGBE_STAT("hw_rsc_flushed", rsc_total_flush), +#ifdef HAVE_TX_MQ + IXGBE_STAT("fdir_match", stats.fdirmatch), + IXGBE_STAT("fdir_miss", stats.fdirmiss), + IXGBE_STAT("fdir_overflow", fdir_overflow), +#endif /* HAVE_TX_MQ */ +#if IS_ENABLED(CONFIG_FCOE) + IXGBE_STAT("fcoe_bad_fccrc", stats.fccrc), + IXGBE_STAT("fcoe_last_errors", stats.fclast), + IXGBE_STAT("rx_fcoe_dropped", stats.fcoerpdc), + IXGBE_STAT("rx_fcoe_packets", stats.fcoeprc), + IXGBE_STAT("rx_fcoe_dwords", stats.fcoedwrc), + IXGBE_STAT("fcoe_noddp", stats.fcoe_noddp), + IXGBE_STAT("fcoe_noddp_ext_buff", stats.fcoe_noddp_ext_buff), + IXGBE_STAT("tx_fcoe_packets", stats.fcoeptc), + IXGBE_STAT("tx_fcoe_dwords", stats.fcoedwtc), +#endif /* CONFIG_FCOE */ + IXGBE_STAT("os2bmc_rx_by_bmc", stats.o2bgptc), + IXGBE_STAT("os2bmc_tx_by_bmc", stats.b2ospc), + IXGBE_STAT("os2bmc_tx_by_host", stats.o2bspc), + IXGBE_STAT("os2bmc_rx_by_host", stats.b2ogprc), +#ifdef HAVE_PTP_1588_CLOCK + IXGBE_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts), + IXGBE_STAT("tx_hwtstamp_skipped", tx_hwtstamp_skipped), + IXGBE_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), +#endif /* HAVE_PTP_1588_CLOCK */ +}; + +/* ixgbe allocates num_tx_queues and num_rx_queues symmetrically so + * we set the num_rx_queues to evaluate to num_tx_queues. This is + * used because we do not have a good way to get the max number of + * rx queues with CONFIG_RPS disabled. + */ +#ifdef HAVE_TX_MQ +#ifdef HAVE_NETDEV_SELECT_QUEUE +#define IXGBE_NUM_RX_QUEUES netdev->num_tx_queues +#define IXGBE_NUM_TX_QUEUES netdev->num_tx_queues +#else +#define IXGBE_NUM_RX_QUEUES adapter->indices +#define IXGBE_NUM_TX_QUEUES adapter->indices +#endif /* HAVE_NETDEV_SELECT_QUEUE */ +#else /* HAVE_TX_MQ */ +#define IXGBE_NUM_TX_QUEUES 1 +#define IXGBE_NUM_RX_QUEUES ( \ + ((struct ixgbe_adapter *)netdev_priv(netdev))->num_rx_queues) +#endif /* HAVE_TX_MQ */ + +#define IXGBE_QUEUE_STATS_LEN ( \ + (IXGBE_NUM_TX_QUEUES + IXGBE_NUM_RX_QUEUES) * \ + (sizeof(struct ixgbe_queue_stats) / sizeof(u64))) +#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats) +#define IXGBE_NETDEV_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_net_stats) +#define IXGBE_PB_STATS_LEN ( \ + (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \ + sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \ + sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \ + sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \ + / sizeof(u64)) +#define IXGBE_VF_STATS_LEN \ + ((((struct ixgbe_adapter *)netdev_priv(netdev))->num_vfs) * \ + (sizeof(struct vf_stats) / sizeof(u64))) +#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + \ + IXGBE_NETDEV_STATS_LEN + \ + IXGBE_PB_STATS_LEN + \ + IXGBE_QUEUE_STATS_LEN + \ + IXGBE_VF_STATS_LEN) + +#endif /* ETHTOOL_GSTATS */ +#ifdef ETHTOOL_TEST +static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { + "Register test (offline)", "Eeprom test (offline)", + "Interrupt test (offline)", "Loopback test (offline)", + "Link test (on/offline)" +}; +#define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) +#endif /* ETHTOOL_TEST */ + +#ifdef HAVE_ETHTOOL_GET_SSET_COUNT +static const char ixgbe_priv_flags_strings[][ETH_GSTRING_LEN] = { +#define IXGBE_PRIV_FLAGS_FD_ATR BIT(0) + "flow-director-atr", +#ifdef HAVE_SWIOTLB_SKIP_CPU_SYNC +#define IXGBE_PRIV_FLAGS_LEGACY_RX BIT(1) + "legacy-rx", +#endif +#define IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF BIT(2) + "mdd-disable-vf", +}; + +#define IXGBE_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbe_priv_flags_strings) + +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ +/* currently supported speeds for 10G */ +#define ADVERTISED_MASK_10G (SUPPORTED_10000baseT_Full | SUPPORTED_10000baseKX4_Full | SUPPORTED_10000baseKR_Full) + +#define ixgbe_isbackplane(type) ((type == ixgbe_media_type_backplane)? true : false) + + +#ifdef ETHTOOL_GLINKSETTINGS +static void ixgbe_set_supported_10gtypes(struct ixgbe_hw *hw, + struct ethtool_link_ksettings *cmd) +{ + if (!ixgbe_isbackplane(hw->phy.media_type)) { + ethtool_link_ksettings_add_link_mode + (cmd, supported, 10000baseT_Full); + return; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_X550EM_X_KX4: + ethtool_link_ksettings_add_link_mode + (cmd, supported, 10000baseKX4_Full); + break; + case IXGBE_DEV_ID_82598_BX: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_XFI: + ethtool_link_ksettings_add_link_mode + (cmd, supported, 10000baseKR_Full); + break; + default: + ethtool_link_ksettings_add_link_mode + (cmd, supported, 10000baseKX4_Full); + ethtool_link_ksettings_add_link_mode + (cmd, supported, 10000baseKR_Full); + break; + } +} + +static void ixgbe_set_advertising_10gtypes(struct ixgbe_hw *hw, + struct ethtool_link_ksettings *cmd) +{ + if (!ixgbe_isbackplane(hw->phy.media_type)) { + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 10000baseT_Full); + return; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_X550EM_X_KX4: + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 10000baseKX4_Full); + break; + case IXGBE_DEV_ID_82598_BX: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_XFI: + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 10000baseKR_Full); + break; + default: + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 10000baseKX4_Full); + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 10000baseKR_Full); + break; + } +} + +/** + * ixgbe_get_link_ksettings - Retrieve link settings for the network device + * @netdev: Network device structure + * @cmd: Pointer to ethtool_link_ksettings structure to be filled with link settings + * + * This function populates the `ethtool_link_ksettings` structure with the + * supported and advertised link modes, port type, and speed for the specified + * network device. It considers the device's capabilities, PHY type, and + * current link status to determine the appropriate settings. + * + * Return: 0 on success. + */ +static int ixgbe_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + ixgbe_link_speed supported_link; + bool autoneg = false; + + ethtool_link_ksettings_zero_link_mode(cmd, supported); + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + + hw->mac.ops.get_link_capabilities(hw, &supported_link, &autoneg); + /* set the supported link speeds */ + if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) { + ixgbe_set_supported_10gtypes(hw, cmd); + ixgbe_set_advertising_10gtypes(hw, cmd); + } +#ifdef HAVE_ETHTOOL_5G_BITS + if (supported_link & IXGBE_LINK_SPEED_5GB_FULL) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 5000baseT_Full); +#endif +#ifdef HAVE_ETHTOOL_NEW_2500MB_BITS + if (supported_link & IXGBE_LINK_SPEED_2_5GB_FULL) + ethtool_link_ksettings_add_link_mode(cmd, supported, + 2500baseT_Full); +#endif + if (supported_link & IXGBE_LINK_SPEED_1GB_FULL) { + if (ixgbe_isbackplane(hw->phy.media_type)) { + ethtool_link_ksettings_add_link_mode(cmd, supported, + 1000baseKX_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 1000baseKX_Full); + } else { + ethtool_link_ksettings_add_link_mode(cmd, supported, + 1000baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 1000baseT_Full); + } + } + if (supported_link & IXGBE_LINK_SPEED_100_FULL) { + ethtool_link_ksettings_add_link_mode(cmd, supported, + 100baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 100baseT_Full); + } + if (supported_link & IXGBE_LINK_SPEED_10_FULL) { + ethtool_link_ksettings_add_link_mode(cmd, supported, + 10baseT_Full); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10baseT_Full); + } + + /* set the advertised speeds */ + if (hw->phy.autoneg_advertised) { + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 10baseT_Full); + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 100baseT_Full); + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + ixgbe_set_advertising_10gtypes(hw, cmd); + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) { + if (ethtool_link_ksettings_test_link_mode + (cmd, supported, 1000baseKX_Full)) + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 1000baseKX_Full); + else + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 1000baseT_Full); + } +#ifdef HAVE_ETHTOOL_5G_BITS + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) { + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 5000baseT_Full); + } +#endif +#ifdef HAVE_ETHTOOL_NEW_2500MB_BITS + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) { + ethtool_link_ksettings_add_link_mode(cmd, advertising, + 2500baseT_Full); + } +#endif + } else { + if (hw->phy.multispeed_fiber && !autoneg) { + if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) + ethtool_link_ksettings_add_link_mode + (cmd, advertising, 10000baseT_Full); + } + } + + if (autoneg) { + ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); + ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); + cmd->base.autoneg = AUTONEG_ENABLE; + } else { + cmd->base.autoneg = AUTONEG_DISABLE; + } + + /* Determine the remaining settings based on the PHY type. */ + switch (adapter->hw.phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_aq: + case ixgbe_phy_x550em_ext_t: + case ixgbe_phy_fw: + case ixgbe_phy_cu_unknown: + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); + cmd->base.port = PORT_TP; + break; + case ixgbe_phy_qt: + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); + cmd->base.port = PORT_FIBRE; + break; + case ixgbe_phy_nl: + case ixgbe_phy_sfp_passive_tyco: + case ixgbe_phy_sfp_passive_unknown: + case ixgbe_phy_sfp_ftl: + case ixgbe_phy_sfp_avago: + case ixgbe_phy_sfp_intel: + case ixgbe_phy_sfp_unknown: + case ixgbe_phy_qsfp_passive_unknown: + case ixgbe_phy_qsfp_active_unknown: + case ixgbe_phy_qsfp_intel: + case ixgbe_phy_qsfp_unknown: + switch (adapter->hw.phy.sfp_type) { + /* SFP+ devices, further checking needed */ + case ixgbe_sfp_type_da_cu: + case ixgbe_sfp_type_da_cu_core0: + case ixgbe_sfp_type_da_cu_core1: + ethtool_link_ksettings_add_link_mode(cmd, supported, + FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + FIBRE); + cmd->base.port = PORT_DA; + break; + case ixgbe_sfp_type_sr: + case ixgbe_sfp_type_lr: + case ixgbe_sfp_type_srlr_core0: + case ixgbe_sfp_type_srlr_core1: + case ixgbe_sfp_type_1g_sx_core0: + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: + ethtool_link_ksettings_add_link_mode(cmd, supported, + FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + FIBRE); + cmd->base.port = PORT_FIBRE; + break; + case ixgbe_sfp_type_not_present: + ethtool_link_ksettings_add_link_mode(cmd, supported, + FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + FIBRE); + cmd->base.port = PORT_NONE; + break; + case ixgbe_sfp_type_1g_cu_core0: + case ixgbe_sfp_type_1g_cu_core1: + ethtool_link_ksettings_add_link_mode(cmd, supported, + TP); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + TP); + cmd->base.port = PORT_TP; + break; + case ixgbe_sfp_type_unknown: + default: + ethtool_link_ksettings_add_link_mode(cmd, supported, + FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + FIBRE); + cmd->base.port = PORT_OTHER; + break; + } + break; + case ixgbe_phy_xaui: + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); + cmd->base.port = PORT_NONE; + break; + case ixgbe_phy_unknown: + case ixgbe_phy_generic: + case ixgbe_phy_sfp_unsupported: + default: + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); + cmd->base.port = PORT_OTHER; + break; + } + + /* Indicate pause support */ + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); + + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); + break; + case ixgbe_fc_rx_pause: + ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); + ethtool_link_ksettings_add_link_mode(cmd, advertising, + Asym_Pause); + break; + case ixgbe_fc_tx_pause: + ethtool_link_ksettings_add_link_mode(cmd, advertising, + Asym_Pause); + break; + default: + ethtool_link_ksettings_del_link_mode(cmd, advertising, Pause); + ethtool_link_ksettings_del_link_mode(cmd, advertising, + Asym_Pause); + } + + if (netif_carrier_ok(netdev)) { + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + cmd->base.speed = SPEED_10000; + break; + case IXGBE_LINK_SPEED_5GB_FULL: + cmd->base.speed = SPEED_5000; + break; +#ifdef SUPPORTED_2500baseX_Full + case IXGBE_LINK_SPEED_2_5GB_FULL: + cmd->base.speed = SPEED_2500; + break; +#endif /* SUPPORTED_2500baseX_Full */ + case IXGBE_LINK_SPEED_1GB_FULL: + cmd->base.speed = SPEED_1000; + break; + case IXGBE_LINK_SPEED_100_FULL: + cmd->base.speed = SPEED_100; + break; + case IXGBE_LINK_SPEED_10_FULL: + cmd->base.speed = SPEED_10; + break; + default: + break; + } + cmd->base.duplex = DUPLEX_FULL; + } else { + cmd->base.speed = SPEED_UNKNOWN; + cmd->base.duplex = DUPLEX_UNKNOWN; + } + + return 0; +} +#else /* ETHTOOL_GLINKSETTINGS */ +static __u32 ixgbe_backplane_type(struct ixgbe_hw *hw) +{ + __u32 mode = 0x00; + + switch (hw->device_id) { + case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_X550EM_X_KX4: + mode = SUPPORTED_10000baseKX4_Full; + break; + case IXGBE_DEV_ID_82598_BX: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_XFI: + mode = SUPPORTED_10000baseKR_Full; + break; + default: + mode = (SUPPORTED_10000baseKX4_Full | + SUPPORTED_10000baseKR_Full); + break; + } + return mode; +} + +/** + * ixgbe_get_settings - Retrieve link settings for the network device + * @netdev: Network device structure + * @ecmd: Pointer to ethtool_cmd structure to be filled with link settings + * + * This function populates the `ethtool_cmd` structure with the supported and + * advertised link modes, port type, speed, and duplex settings for the specified + * network device. It considers the device's capabilities, PHY type, and current + * link status to determine the appropriate settings. + * + * Return: 0 on success. + */ +static int ixgbe_get_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + ixgbe_link_speed supported_link; + bool autoneg = false; + + hw->mac.ops.get_link_capabilities(hw, &supported_link, &autoneg); + + /* set the supported link speeds */ + if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) + ecmd->supported |= (ixgbe_isbackplane(hw->phy.media_type)) ? + ixgbe_backplane_type(hw) : + SUPPORTED_10000baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_1GB_FULL) + ecmd->supported |= (ixgbe_isbackplane(hw->phy.media_type)) ? + SUPPORTED_1000baseKX_Full : + SUPPORTED_1000baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_100_FULL) + ecmd->supported |= SUPPORTED_100baseT_Full; + if (supported_link & IXGBE_LINK_SPEED_10_FULL) + ecmd->supported |= SUPPORTED_10baseT_Full; + + /* default advertised speed if phy.autoneg_advertised isn't set */ + ecmd->advertising = ecmd->supported; + + /* set the advertised speeds */ + if (hw->phy.autoneg_advertised) { + ecmd->advertising = 0; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL) + ecmd->advertising |= ADVERTISED_10baseT_Full; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + ecmd->advertising |= (ecmd->supported & ADVERTISED_MASK_10G); + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) { + if (ecmd->supported & SUPPORTED_1000baseKX_Full) + ecmd->advertising |= ADVERTISED_1000baseKX_Full; + else + ecmd->advertising |= ADVERTISED_1000baseT_Full; + } + } else { + if (hw->phy.multispeed_fiber && !autoneg) { + if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) + ecmd->advertising = ADVERTISED_10000baseT_Full; + } + } + + if (autoneg) { + ecmd->supported |= SUPPORTED_Autoneg; + ecmd->advertising |= ADVERTISED_Autoneg; + ecmd->autoneg = AUTONEG_ENABLE; + } else { + ecmd->autoneg = AUTONEG_DISABLE; + } + + ecmd->transceiver = XCVR_EXTERNAL; + + /* Determine the remaining settings based on the PHY type. */ + switch (adapter->hw.phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_aq: + case ixgbe_phy_x550em_ext_t: + case ixgbe_phy_fw: + case ixgbe_phy_cu_unknown: + ecmd->supported |= SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_TP; + ecmd->port = PORT_TP; + break; + case ixgbe_phy_qt: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_FIBRE; + break; + case ixgbe_phy_nl: + case ixgbe_phy_sfp_passive_tyco: + case ixgbe_phy_sfp_passive_unknown: + case ixgbe_phy_sfp_ftl: + case ixgbe_phy_sfp_avago: + case ixgbe_phy_sfp_intel: + case ixgbe_phy_sfp_unknown: + case ixgbe_phy_qsfp_passive_unknown: + case ixgbe_phy_qsfp_active_unknown: + case ixgbe_phy_qsfp_intel: + case ixgbe_phy_qsfp_unknown: + switch (adapter->hw.phy.sfp_type) { + /* SFP+ devices, further checking needed */ + case ixgbe_sfp_type_da_cu: + case ixgbe_sfp_type_da_cu_core0: + case ixgbe_sfp_type_da_cu_core1: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_DA; + break; + case ixgbe_sfp_type_sr: + case ixgbe_sfp_type_lr: + case ixgbe_sfp_type_srlr_core0: + case ixgbe_sfp_type_srlr_core1: + case ixgbe_sfp_type_1g_sx_core0: + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_FIBRE; + break; + case ixgbe_sfp_type_not_present: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_NONE; + break; + case ixgbe_sfp_type_1g_cu_core0: + case ixgbe_sfp_type_1g_cu_core1: + ecmd->supported |= SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_TP; + ecmd->port = PORT_TP; + break; + case ixgbe_sfp_type_unknown: + default: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_OTHER; + break; + } + break; + case ixgbe_phy_xaui: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_NONE; + break; + case ixgbe_phy_unknown: + case ixgbe_phy_generic: + case ixgbe_phy_sfp_unsupported: + default: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_OTHER; + break; + } + + /* Indicate pause support */ + ecmd->supported |= SUPPORTED_Pause; + + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + ecmd->advertising |= ADVERTISED_Pause; + break; + case ixgbe_fc_rx_pause: + ecmd->advertising |= ADVERTISED_Pause | + ADVERTISED_Asym_Pause; + break; + case ixgbe_fc_tx_pause: + ecmd->advertising |= ADVERTISED_Asym_Pause; + break; + default: + ecmd->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } + + if (netif_carrier_ok(netdev)) { + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + ethtool_cmd_speed_set(ecmd, SPEED_10000); + break; + case IXGBE_LINK_SPEED_5GB_FULL: + ethtool_cmd_speed_set(ecmd, SPEED_5000); + break; +#ifdef SUPPORTED_2500baseX_Full + case IXGBE_LINK_SPEED_2_5GB_FULL: + ethtool_cmd_speed_set(ecmd, SPEED_2500); + break; +#endif /* SUPPORTED_2500baseX_Full */ + case IXGBE_LINK_SPEED_1GB_FULL: + ethtool_cmd_speed_set(ecmd, SPEED_1000); + break; + case IXGBE_LINK_SPEED_100_FULL: + ethtool_cmd_speed_set(ecmd, SPEED_100); + break; + case IXGBE_LINK_SPEED_10_FULL: + ethtool_cmd_speed_set(ecmd, SPEED_10); + break; + default: + break; + } + ecmd->duplex = DUPLEX_FULL; + } else { + ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); + ecmd->duplex = DUPLEX_UNKNOWN; + } + + return 0; +} +#endif /* !ETHTOOL_GLINKSETTINGS */ + +#ifdef ETHTOOL_GLINKSETTINGS +/** + * ixgbe_set_link_ksettings - Set link settings for the network device + * @netdev: Network device structure + * @cmd: Pointer to ethtool_link_ksettings structure with desired link settings + * + * This function configures the link settings for the specified network device + * based on the provided `ethtool_link_ksettings` structure. It validates the + * requested settings, updates the advertised link speeds, and restarts + * auto-negotiation if necessary. The function supports both copper and + * multispeed fiber media types. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u32 advertised, old; + s32 err = 0; + + if (hw->phy.media_type == ixgbe_media_type_copper || + hw->phy.multispeed_fiber) { + /* + * this function does not support duplex forcing, but can + * limit the advertising of the adapter to the specified speed + */ + if (!bitmap_subset(cmd->link_modes.advertising, + cmd->link_modes.supported, + __ETHTOOL_LINK_MODE_MASK_NBITS)) + return -EINVAL; + + /* only allow one speed at a time if no autoneg */ + if (!cmd->base.autoneg && hw->phy.multispeed_fiber) { + if (ethtool_link_ksettings_test_link_mode + (cmd, advertising, 10000baseT_Full) && + ethtool_link_ksettings_test_link_mode + (cmd, advertising, 1000baseT_Full)) + return -EINVAL; + } + + old = hw->phy.autoneg_advertised; + advertised = 0; + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 10000baseT_Full)) + advertised |= IXGBE_LINK_SPEED_10GB_FULL; +#ifdef HAVE_ETHTOOL_5G_BITS + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 5000baseT_Full)) + advertised |= IXGBE_LINK_SPEED_5GB_FULL; +#endif +#ifdef HAVE_ETHTOOL_NEW_2500MB_BITS + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 2500baseT_Full)) + advertised |= IXGBE_LINK_SPEED_2_5GB_FULL; +#endif + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 1000baseT_Full)) + advertised |= IXGBE_LINK_SPEED_1GB_FULL; + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 100baseT_Full)) + advertised |= IXGBE_LINK_SPEED_100_FULL; + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 10baseT_Full)) + advertised |= IXGBE_LINK_SPEED_10_FULL; + + if (old == advertised) + return err; + /* this sets the link speed and restarts auto-neg */ + while (test_and_set_bit(__IXGBE_IN_SFP_INIT, adapter->state)) + usleep_range(1000, 2000); + + hw->mac.autotry_restart = true; + err = hw->mac.ops.setup_link(hw, advertised, true); + if (err) { + e_info(probe, "setup link failed with code %d\n", err); + hw->mac.ops.setup_link(hw, old, true); + } + clear_bit(__IXGBE_IN_SFP_INIT, adapter->state); + } else { + /* in this case we currently only support 10Gb/FULL */ + u32 speed = cmd->base.speed; + + if (cmd->base.autoneg == AUTONEG_ENABLE || + (!ethtool_link_ksettings_test_link_mode(cmd, advertising, + 10000baseT_Full)) || + (speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL)) + return -EINVAL; + } + + return err; +} +#else +/** + * ixgbe_set_settings - Set link settings for the network device + * @netdev: Network device structure + * @ecmd: Pointer to ethtool_cmd structure with desired link settings + * + * This function configures the link settings for the specified network device + * based on the provided `ethtool_cmd` structure. It validates the requested + * settings, updates the advertised link speeds, and restarts auto-negotiation + * if necessary. The function supports both copper and multispeed fiber media + * types, but does not support duplex forcing. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u32 advertised, old; + s32 err = 0; + + if ((hw->phy.media_type == ixgbe_media_type_copper) || + (hw->phy.multispeed_fiber)) { + /* + * this function does not support duplex forcing, but can + * limit the advertising of the adapter to the specified speed + */ + if (ecmd->advertising & ~ecmd->supported) + return -EINVAL; + + /* only allow one speed at a time if no autoneg */ + if (!ecmd->autoneg && hw->phy.multispeed_fiber) { + if (ecmd->advertising == + (ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full)) + return -EINVAL; + } + + old = hw->phy.autoneg_advertised; + advertised = 0; + if (ecmd->advertising & ADVERTISED_10000baseT_Full) + advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (ecmd->advertising & ADVERTISED_1000baseT_Full) + advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + if (ecmd->advertising & ADVERTISED_100baseT_Full) + advertised |= IXGBE_LINK_SPEED_100_FULL; + + if (ecmd->advertising & ADVERTISED_10baseT_Full) + advertised |= IXGBE_LINK_SPEED_10_FULL; + + if (old == advertised) + return err; + /* this sets the link speed and restarts auto-neg */ + while (test_and_set_bit(__IXGBE_IN_SFP_INIT, adapter->state)) + usleep_range(1000, 2000); + + hw->mac.autotry_restart = true; + err = hw->mac.ops.setup_link(hw, advertised, true); + if (err) { + e_info(probe, "setup link failed with code %d\n", err); + hw->mac.ops.setup_link(hw, old, true); + } + clear_bit(__IXGBE_IN_SFP_INIT, adapter->state); + } + else { + /* in this case we currently only support 10Gb/FULL */ + u32 speed = ethtool_cmd_speed(ecmd); + + if ((ecmd->autoneg == AUTONEG_ENABLE) || + (ecmd->advertising != ADVERTISED_10000baseT_Full) || + (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) + return -EINVAL; + } + + return err; +} +#endif /* !ETHTOOL_GLINKSETTINGS */ + +/** + * ixgbe_get_pauseparam - Retrieve pause parameters for the network device + * @netdev: Network device structure + * @pause: Pointer to ethtool_pauseparam structure to be filled with pause settings + * + * This function populates the `ethtool_pauseparam` structure with the current + * pause frame settings for the specified network device. It sets the receive + * and transmit pause parameters based on the device's current flow control mode + * and indicates whether autonegotiation of flow control is enabled. + */ +static void ixgbe_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + pause->rx_pause = 0; + pause->tx_pause = 0; + + if (ixgbe_device_supports_autoneg_fc(hw) && + !hw->fc.disable_fc_autoneg) + pause->autoneg = 1; + else + pause->autoneg = 0; + + if (hw->fc.current_mode == ixgbe_fc_rx_pause) { + pause->rx_pause = 1; + } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) { + pause->tx_pause = 1; + } else if (hw->fc.current_mode == ixgbe_fc_full) { + pause->rx_pause = 1; + pause->tx_pause = 1; + } +} + +/** + * ixgbe_set_pauseparam_E610 - Set pause parameters for E610 hardware + * @netdev: Network device structure + * @pause: Pointer to ethtool_pauseparam structure with desired pause settings + * + * This function configures the pause frame settings for E610 hardware based on + * the provided `ethtool_pauseparam` structure. It validates the settings, + * updates the flow control mode, and applies changes if necessary. The function + * does not support disabling autonegotiation for flow control. + * + * Return: 0 on success, or -EOPNOTSUPP if the configuration is not supported. + */ +static int ixgbe_set_pauseparam_E610(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_fc_info fc = hw->fc; + + + if (pause->autoneg == AUTONEG_DISABLE) { + netdev_info(netdev, + "Cannot disable autonegotiation for this device.\n"); + return -EOPNOTSUPP; + } + + /* some devices do not support autoneg of flow control */ + if ((pause->autoneg == AUTONEG_ENABLE) && + !ixgbe_device_supports_autoneg_fc(hw)) + return -EOPNOTSUPP; + + fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE); + + if (pause->rx_pause && pause->tx_pause) + fc.requested_mode = ixgbe_fc_full; + else if (pause->rx_pause) + fc.requested_mode = ixgbe_fc_rx_pause; + else if (pause->tx_pause) + fc.requested_mode = ixgbe_fc_tx_pause; + else + fc.requested_mode = ixgbe_fc_none; + + /* if the thing changed then we'll update and use new autoneg */ + if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) { + hw->fc = fc; + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + } + + return 0; +} + +/** + * ixgbe_set_pauseparam - Set pause frame parameters for the network device + * @netdev: Network device structure + * @pause: Pointer to ethtool_pauseparam structure with desired pause settings + * + * This function configures the pause frame settings for the specified network + * device based on the provided `ethtool_pauseparam` structure. It validates + * the settings, updates the flow control mode, and applies changes if necessary. + * The function does not support enabling autonegotiation of flow control on + * certain devices or when DCB is enabled on 82598 hardware. + * + * Return: 0 on success, or -EINVAL if the configuration is not supported. + */ +static int ixgbe_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_fc_info fc = hw->fc; + + /* 82598 does no support link flow control with DCB enabled */ + if ((hw->mac.type == ixgbe_mac_82598EB) && + (adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + return -EINVAL; + + /* some devices do not support autoneg of flow control */ + if ((pause->autoneg == AUTONEG_ENABLE) && + !ixgbe_device_supports_autoneg_fc(hw)) + return -EINVAL; + + fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE); + + if ((pause->rx_pause && pause->tx_pause) || pause->autoneg) + fc.requested_mode = ixgbe_fc_full; + else if (pause->rx_pause) + fc.requested_mode = ixgbe_fc_rx_pause; + else if (pause->tx_pause) + fc.requested_mode = ixgbe_fc_tx_pause; + else + fc.requested_mode = ixgbe_fc_none; + + /* if the thing changed then we'll update and use new autoneg */ + if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) { + hw->fc = fc; + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + } + + return 0; +} + +/** + * ixgbe_get_msglevel - Retrieve the message level for the network device + * @netdev: Network device structure + * + * This function returns the current message level for the specified network + * device, which controls the verbosity of the driver's logging output. + * + * Return: The current message level. + */ +static u32 ixgbe_get_msglevel(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + return adapter->msg_enable; +} + +/** + * ixgbe_set_msglevel - Set the message level for the network device + * @netdev: Network device structure + * @data: New message level to be set + * + * This function sets the message level for the specified network device, + * which controls the verbosity of the driver's logging output. + */ +static void ixgbe_set_msglevel(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + adapter->msg_enable = data; +} + +/** + * ixgbe_get_regs_len - Get the length of the hardware registers data + * @netdev: Network device structure (unused) + * + * This function returns the total length, in bytes, of the hardware registers + * data for the network device. The length is defined by the constant + * `IXGBE_REGS_LEN` multiplied by the size of a 32-bit integer. + * + * Return: The length of the hardware registers data in bytes. + */ +static int ixgbe_get_regs_len(struct net_device __always_unused *netdev) +{ +#define IXGBE_REGS_LEN 1145 + return IXGBE_REGS_LEN * sizeof(u32); +} + +#define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_) + +/** + * ixgbe_get_regs - Retrieve hardware registers for the network device + * @netdev: Network device structure + * @regs: Pointer to ethtool_regs structure to be filled with register info + * @p: Buffer to store the retrieved register values + * + * This function populates the provided buffer with the current values of + * various hardware registers for the specified network device. It organizes + * the registers into categories such as general, NVM, interrupt, flow control, + * and more, and fills the `ethtool_regs` structure with version information. + */ +static void ixgbe_get_regs(struct net_device *netdev, struct ethtool_regs *regs, + void *p) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u32 *regs_buff = p; + u8 i; + + memset(p, 0, IXGBE_REGS_LEN * sizeof(u32)); + + regs->version = hw->mac.type << 24 | hw->revision_id << 16 | + hw->device_id; + + /* General Registers */ + regs_buff[0] = IXGBE_R32_Q(hw, IXGBE_CTRL); + regs_buff[1] = IXGBE_R32_Q(hw, IXGBE_STATUS); + regs_buff[2] = IXGBE_R32_Q(hw, IXGBE_CTRL_EXT); + regs_buff[3] = IXGBE_R32_Q(hw, IXGBE_ESDP); + regs_buff[4] = IXGBE_R32_Q(hw, IXGBE_EODSDP); + regs_buff[5] = IXGBE_R32_Q(hw, IXGBE_LEDCTL); + regs_buff[6] = IXGBE_R32_Q(hw, IXGBE_FRTIMER); + regs_buff[7] = IXGBE_R32_Q(hw, IXGBE_TCPTIMER); + + /* NVM Register */ + regs_buff[8] = IXGBE_R32_Q(hw, IXGBE_EEC); + regs_buff[9] = IXGBE_R32_Q(hw, IXGBE_EERD); + regs_buff[10] = IXGBE_R32_Q(hw, IXGBE_FLA); + regs_buff[11] = IXGBE_R32_Q(hw, IXGBE_EEMNGCTL); + regs_buff[12] = IXGBE_R32_Q(hw, IXGBE_EEMNGDATA); + regs_buff[13] = IXGBE_R32_Q(hw, IXGBE_FLMNGCTL); + regs_buff[14] = IXGBE_R32_Q(hw, IXGBE_FLMNGDATA); + regs_buff[15] = IXGBE_R32_Q(hw, IXGBE_FLMNGCNT); + regs_buff[16] = IXGBE_R32_Q(hw, IXGBE_FLOP); + regs_buff[17] = IXGBE_R32_Q(hw, IXGBE_GRC); + + /* Interrupt */ + /* don't read EICR because it can clear interrupt causes, instead + * read EICS which is a shadow but doesn't clear EICR */ + regs_buff[18] = IXGBE_R32_Q(hw, IXGBE_EICS); + regs_buff[19] = IXGBE_R32_Q(hw, IXGBE_EICS); + regs_buff[20] = IXGBE_R32_Q(hw, IXGBE_EIMS); + regs_buff[21] = IXGBE_R32_Q(hw, IXGBE_EIMC); + regs_buff[22] = IXGBE_R32_Q(hw, IXGBE_EIAC); + regs_buff[23] = IXGBE_R32_Q(hw, IXGBE_EIAM); + regs_buff[24] = IXGBE_R32_Q(hw, IXGBE_EITR(0)); + regs_buff[25] = IXGBE_R32_Q(hw, IXGBE_IVAR(0)); + regs_buff[26] = IXGBE_R32_Q(hw, IXGBE_MSIXT); + regs_buff[27] = IXGBE_R32_Q(hw, IXGBE_MSIXPBA); + regs_buff[28] = IXGBE_R32_Q(hw, IXGBE_PBACL(0)); + regs_buff[29] = IXGBE_R32_Q(hw, IXGBE_GPIE); + + /* Flow Control */ + regs_buff[30] = IXGBE_R32_Q(hw, IXGBE_PFCTOP); + regs_buff[31] = IXGBE_R32_Q(hw, IXGBE_FCTTV(0)); + regs_buff[32] = IXGBE_R32_Q(hw, IXGBE_FCTTV(1)); + regs_buff[33] = IXGBE_R32_Q(hw, IXGBE_FCTTV(2)); + regs_buff[34] = IXGBE_R32_Q(hw, IXGBE_FCTTV(3)); + for (i = 0; i < 8; i++) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + regs_buff[35 + i] = IXGBE_R32_Q(hw, IXGBE_FCRTL(i)); + regs_buff[43 + i] = IXGBE_R32_Q(hw, IXGBE_FCRTH(i)); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_E610: + regs_buff[35 + i] = IXGBE_R32_Q(hw, + IXGBE_FCRTL_82599(i)); + regs_buff[43 + i] = IXGBE_R32_Q(hw, + IXGBE_FCRTH_82599(i)); + break; + default: + break; + } + } + regs_buff[51] = IXGBE_R32_Q(hw, IXGBE_FCRTV); + regs_buff[52] = IXGBE_R32_Q(hw, IXGBE_TFCS); + + /* Receive DMA */ + for (i = 0; i < 64; i++) + regs_buff[53 + i] = IXGBE_R32_Q(hw, IXGBE_RDBAL(i)); + for (i = 0; i < 64; i++) + regs_buff[117 + i] = IXGBE_R32_Q(hw, IXGBE_RDBAH(i)); + for (i = 0; i < 64; i++) + regs_buff[181 + i] = IXGBE_R32_Q(hw, IXGBE_RDLEN(i)); + for (i = 0; i < 64; i++) + regs_buff[245 + i] = IXGBE_R32_Q(hw, IXGBE_RDH(i)); + for (i = 0; i < 64; i++) + regs_buff[309 + i] = IXGBE_R32_Q(hw, IXGBE_RDT(i)); + for (i = 0; i < 64; i++) + regs_buff[373 + i] = IXGBE_R32_Q(hw, IXGBE_RXDCTL(i)); + for (i = 0; i < 16; i++) + regs_buff[437 + i] = IXGBE_R32_Q(hw, IXGBE_SRRCTL(i)); + for (i = 0; i < 16; i++) + regs_buff[453 + i] = IXGBE_R32_Q(hw, IXGBE_DCA_RXCTRL(i)); + regs_buff[469] = IXGBE_R32_Q(hw, IXGBE_RDRXCTL); + for (i = 0; i < 8; i++) + regs_buff[470 + i] = IXGBE_R32_Q(hw, IXGBE_RXPBSIZE(i)); + regs_buff[478] = IXGBE_R32_Q(hw, IXGBE_RXCTRL); + regs_buff[479] = IXGBE_R32_Q(hw, IXGBE_DROPEN); + + /* Receive */ + regs_buff[480] = IXGBE_R32_Q(hw, IXGBE_RXCSUM); + regs_buff[481] = IXGBE_R32_Q(hw, IXGBE_RFCTL); + for (i = 0; i < 16; i++) + regs_buff[482 + i] = IXGBE_R32_Q(hw, IXGBE_RAL(i)); + for (i = 0; i < 16; i++) + regs_buff[498 + i] = IXGBE_R32_Q(hw, IXGBE_RAH(i)); + regs_buff[514] = IXGBE_R32_Q(hw, IXGBE_PSRTYPE(0)); + regs_buff[515] = IXGBE_R32_Q(hw, IXGBE_FCTRL); + regs_buff[516] = IXGBE_R32_Q(hw, IXGBE_VLNCTRL); + regs_buff[517] = IXGBE_R32_Q(hw, IXGBE_MCSTCTRL); + regs_buff[518] = IXGBE_R32_Q(hw, IXGBE_MRQC); + regs_buff[519] = IXGBE_R32_Q(hw, IXGBE_VMD_CTL); + for (i = 0; i < 8; i++) + regs_buff[520 + i] = IXGBE_R32_Q(hw, IXGBE_IMIR(i)); + for (i = 0; i < 8; i++) + regs_buff[528 + i] = IXGBE_R32_Q(hw, IXGBE_IMIREXT(i)); + regs_buff[536] = IXGBE_R32_Q(hw, IXGBE_IMIRVP); + + /* Transmit */ + for (i = 0; i < 32; i++) + regs_buff[537 + i] = IXGBE_R32_Q(hw, IXGBE_TDBAL(i)); + for (i = 0; i < 32; i++) + regs_buff[569 + i] = IXGBE_R32_Q(hw, IXGBE_TDBAH(i)); + for (i = 0; i < 32; i++) + regs_buff[601 + i] = IXGBE_R32_Q(hw, IXGBE_TDLEN(i)); + for (i = 0; i < 32; i++) + regs_buff[633 + i] = IXGBE_R32_Q(hw, IXGBE_TDH(i)); + for (i = 0; i < 32; i++) + regs_buff[665 + i] = IXGBE_R32_Q(hw, IXGBE_TDT(i)); + for (i = 0; i < 32; i++) + regs_buff[697 + i] = IXGBE_R32_Q(hw, IXGBE_TXDCTL(i)); + for (i = 0; i < 32; i++) + regs_buff[729 + i] = IXGBE_R32_Q(hw, IXGBE_TDWBAL(i)); + for (i = 0; i < 32; i++) + regs_buff[761 + i] = IXGBE_R32_Q(hw, IXGBE_TDWBAH(i)); + regs_buff[793] = IXGBE_R32_Q(hw, IXGBE_DTXCTL); + for (i = 0; i < 16; i++) + regs_buff[794 + i] = IXGBE_R32_Q(hw, IXGBE_DCA_TXCTRL(i)); + regs_buff[810] = IXGBE_R32_Q(hw, IXGBE_TIPG); + for (i = 0; i < 8; i++) + regs_buff[811 + i] = IXGBE_R32_Q(hw, IXGBE_TXPBSIZE(i)); + regs_buff[819] = IXGBE_R32_Q(hw, IXGBE_MNGTXMAP); + + /* Wake Up */ + regs_buff[820] = IXGBE_R32_Q(hw, IXGBE_WUC); + regs_buff[821] = IXGBE_R32_Q(hw, IXGBE_WUFC); + regs_buff[822] = IXGBE_R32_Q(hw, IXGBE_WUS); + regs_buff[823] = IXGBE_R32_Q(hw, IXGBE_IPAV); + regs_buff[824] = IXGBE_R32_Q(hw, IXGBE_IP4AT); + regs_buff[825] = IXGBE_R32_Q(hw, IXGBE_IP6AT); + regs_buff[826] = IXGBE_R32_Q(hw, IXGBE_WUPL); + regs_buff[827] = IXGBE_R32_Q(hw, IXGBE_WUPM); + regs_buff[828] = IXGBE_R32_Q(hw, IXGBE_FHFT(0)); + + /* DCB */ + regs_buff[829] = IXGBE_R32_Q(hw, IXGBE_RMCS); /* same as FCCFG */ + regs_buff[831] = IXGBE_R32_Q(hw, IXGBE_PDPMCS); /* same as RTTPCS */ + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + regs_buff[830] = IXGBE_R32_Q(hw, IXGBE_DPMCS); + regs_buff[832] = IXGBE_R32_Q(hw, IXGBE_RUPPBMR); + for (i = 0; i < 8; i++) + regs_buff[833 + i] = + IXGBE_R32_Q(hw, IXGBE_RT2CR(i)); + for (i = 0; i < 8; i++) + regs_buff[841 + i] = + IXGBE_R32_Q(hw, IXGBE_RT2SR(i)); + for (i = 0; i < 8; i++) + regs_buff[849 + i] = + IXGBE_R32_Q(hw, IXGBE_TDTQ2TCCR(i)); + for (i = 0; i < 8; i++) + regs_buff[857 + i] = + IXGBE_R32_Q(hw, IXGBE_TDTQ2TCSR(i)); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + regs_buff[830] = IXGBE_R32_Q(hw, IXGBE_RTTDCS); + regs_buff[832] = IXGBE_R32_Q(hw, IXGBE_RTRPCS); + for (i = 0; i < 8; i++) + regs_buff[833 + i] = + IXGBE_R32_Q(hw, IXGBE_RTRPT4C(i)); + for (i = 0; i < 8; i++) + regs_buff[841 + i] = + IXGBE_R32_Q(hw, IXGBE_RTRPT4S(i)); + for (i = 0; i < 8; i++) + regs_buff[849 + i] = + IXGBE_R32_Q(hw, IXGBE_RTTDT2C(i)); + for (i = 0; i < 8; i++) + regs_buff[857 + i] = + IXGBE_R32_Q(hw, IXGBE_RTTDT2S(i)); + break; + default: + break; + } + + for (i = 0; i < 8; i++) + regs_buff[865 + i] = + IXGBE_R32_Q(hw, IXGBE_TDPT2TCCR(i)); /* same as RTTPT2C */ + for (i = 0; i < 8; i++) + regs_buff[873 + i] = + IXGBE_R32_Q(hw, IXGBE_TDPT2TCSR(i)); /* same as RTTPT2S */ + + /* Statistics */ + regs_buff[881] = IXGBE_GET_STAT(adapter, crcerrs); + regs_buff[882] = IXGBE_GET_STAT(adapter, illerrc); + regs_buff[883] = IXGBE_GET_STAT(adapter, errbc); + regs_buff[884] = IXGBE_GET_STAT(adapter, mspdc); + for (i = 0; i < 8; i++) + regs_buff[885 + i] = IXGBE_GET_STAT(adapter, mpc[i]); + regs_buff[893] = IXGBE_GET_STAT(adapter, mlfc); + regs_buff[894] = IXGBE_GET_STAT(adapter, mrfc); + regs_buff[895] = IXGBE_GET_STAT(adapter, rlec); + regs_buff[896] = IXGBE_GET_STAT(adapter, lxontxc); + regs_buff[897] = IXGBE_GET_STAT(adapter, lxonrxc); + regs_buff[898] = IXGBE_GET_STAT(adapter, lxofftxc); + regs_buff[899] = IXGBE_GET_STAT(adapter, lxoffrxc); + for (i = 0; i < 8; i++) + regs_buff[900 + i] = IXGBE_GET_STAT(adapter, pxontxc[i]); + for (i = 0; i < 8; i++) + regs_buff[908 + i] = IXGBE_GET_STAT(adapter, pxonrxc[i]); + for (i = 0; i < 8; i++) + regs_buff[916 + i] = IXGBE_GET_STAT(adapter, pxofftxc[i]); + for (i = 0; i < 8; i++) + regs_buff[924 + i] = IXGBE_GET_STAT(adapter, pxoffrxc[i]); + regs_buff[932] = IXGBE_GET_STAT(adapter, prc64); + regs_buff[933] = IXGBE_GET_STAT(adapter, prc127); + regs_buff[934] = IXGBE_GET_STAT(adapter, prc255); + regs_buff[935] = IXGBE_GET_STAT(adapter, prc511); + regs_buff[936] = IXGBE_GET_STAT(adapter, prc1023); + regs_buff[937] = IXGBE_GET_STAT(adapter, prc1522); + regs_buff[938] = IXGBE_GET_STAT(adapter, gprc); + regs_buff[939] = IXGBE_GET_STAT(adapter, bprc); + regs_buff[940] = IXGBE_GET_STAT(adapter, mprc); + regs_buff[941] = IXGBE_GET_STAT(adapter, gptc); + regs_buff[942] = IXGBE_GET_STAT(adapter, gorc); + regs_buff[944] = IXGBE_GET_STAT(adapter, gotc); + for (i = 0; i < 8; i++) + regs_buff[946 + i] = IXGBE_GET_STAT(adapter, rnbc[i]); + regs_buff[954] = IXGBE_GET_STAT(adapter, ruc); + regs_buff[955] = IXGBE_GET_STAT(adapter, rfc); + regs_buff[956] = IXGBE_GET_STAT(adapter, roc); + regs_buff[957] = IXGBE_GET_STAT(adapter, rjc); + regs_buff[958] = IXGBE_GET_STAT(adapter, mngprc); + regs_buff[959] = IXGBE_GET_STAT(adapter, mngpdc); + regs_buff[960] = IXGBE_GET_STAT(adapter, mngptc); + regs_buff[961] = IXGBE_GET_STAT(adapter, tor); + regs_buff[963] = IXGBE_GET_STAT(adapter, tpr); + regs_buff[964] = IXGBE_GET_STAT(adapter, tpt); + regs_buff[965] = IXGBE_GET_STAT(adapter, ptc64); + regs_buff[966] = IXGBE_GET_STAT(adapter, ptc127); + regs_buff[967] = IXGBE_GET_STAT(adapter, ptc255); + regs_buff[968] = IXGBE_GET_STAT(adapter, ptc511); + regs_buff[969] = IXGBE_GET_STAT(adapter, ptc1023); + regs_buff[970] = IXGBE_GET_STAT(adapter, ptc1522); + regs_buff[971] = IXGBE_GET_STAT(adapter, mptc); + regs_buff[972] = IXGBE_GET_STAT(adapter, bptc); + regs_buff[973] = IXGBE_GET_STAT(adapter, xec); + for (i = 0; i < 16; i++) + regs_buff[974 + i] = IXGBE_GET_STAT(adapter, qprc[i]); + for (i = 0; i < 16; i++) + regs_buff[990 + i] = IXGBE_GET_STAT(adapter, qptc[i]); + for (i = 0; i < 16; i++) + regs_buff[1006 + i] = IXGBE_GET_STAT(adapter, qbrc[i]); + for (i = 0; i < 16; i++) + regs_buff[1022 + i] = IXGBE_GET_STAT(adapter, qbtc[i]); + + /* MAC */ + regs_buff[1038] = IXGBE_R32_Q(hw, IXGBE_PCS1GCFIG); + regs_buff[1039] = IXGBE_R32_Q(hw, IXGBE_PCS1GLCTL); + regs_buff[1040] = IXGBE_R32_Q(hw, IXGBE_PCS1GLSTA); + regs_buff[1041] = IXGBE_R32_Q(hw, IXGBE_PCS1GDBG0); + regs_buff[1042] = IXGBE_R32_Q(hw, IXGBE_PCS1GDBG1); + regs_buff[1043] = IXGBE_R32_Q(hw, IXGBE_PCS1GANA); + regs_buff[1044] = IXGBE_R32_Q(hw, IXGBE_PCS1GANLP); + regs_buff[1045] = IXGBE_R32_Q(hw, IXGBE_PCS1GANNP); + regs_buff[1046] = IXGBE_R32_Q(hw, IXGBE_PCS1GANLPNP); + regs_buff[1047] = IXGBE_R32_Q(hw, IXGBE_HLREG0); + regs_buff[1048] = IXGBE_R32_Q(hw, IXGBE_HLREG1); + regs_buff[1049] = IXGBE_R32_Q(hw, IXGBE_PAP); + regs_buff[1050] = IXGBE_R32_Q(hw, IXGBE_MACA); + regs_buff[1051] = IXGBE_R32_Q(hw, IXGBE_APAE); + regs_buff[1052] = IXGBE_R32_Q(hw, IXGBE_ARD); + regs_buff[1053] = IXGBE_R32_Q(hw, IXGBE_AIS); + regs_buff[1054] = IXGBE_R32_Q(hw, IXGBE_MSCA); + regs_buff[1055] = IXGBE_R32_Q(hw, IXGBE_MSRWD); + regs_buff[1056] = IXGBE_R32_Q(hw, IXGBE_MLADD); + regs_buff[1057] = IXGBE_R32_Q(hw, IXGBE_MHADD); + regs_buff[1058] = IXGBE_R32_Q(hw, IXGBE_TREG); + regs_buff[1059] = IXGBE_R32_Q(hw, IXGBE_PCSS1); + regs_buff[1060] = IXGBE_R32_Q(hw, IXGBE_PCSS2); + regs_buff[1061] = IXGBE_R32_Q(hw, IXGBE_XPCSS); + regs_buff[1062] = IXGBE_R32_Q(hw, IXGBE_SERDESC); + regs_buff[1063] = IXGBE_R32_Q(hw, IXGBE_MACS); + regs_buff[1064] = IXGBE_R32_Q(hw, IXGBE_AUTOC); + regs_buff[1065] = IXGBE_R32_Q(hw, IXGBE_LINKS); + regs_buff[1066] = IXGBE_R32_Q(hw, IXGBE_AUTOC2); + regs_buff[1067] = IXGBE_R32_Q(hw, IXGBE_AUTOC3); + regs_buff[1068] = IXGBE_R32_Q(hw, IXGBE_ANLP1); + regs_buff[1069] = IXGBE_R32_Q(hw, IXGBE_ANLP2); + regs_buff[1070] = IXGBE_R32_Q(hw, IXGBE_ATLASCTL); + + /* Diagnostic */ + regs_buff[1071] = IXGBE_R32_Q(hw, IXGBE_RDSTATCTL); + for (i = 0; i < 8; i++) + regs_buff[1072 + i] = IXGBE_R32_Q(hw, IXGBE_RDSTAT(i)); + regs_buff[1080] = IXGBE_R32_Q(hw, IXGBE_RDHMPN); + for (i = 0; i < 4; i++) + regs_buff[1081 + i] = IXGBE_R32_Q(hw, IXGBE_RIC_DW(i)); + regs_buff[1085] = IXGBE_R32_Q(hw, IXGBE_RDPROBE); + regs_buff[1095] = IXGBE_R32_Q(hw, IXGBE_TDHMPN); + for (i = 0; i < 4; i++) + regs_buff[1096 + i] = IXGBE_R32_Q(hw, IXGBE_TIC_DW(i)); + regs_buff[1100] = IXGBE_R32_Q(hw, IXGBE_TDPROBE); + regs_buff[1101] = IXGBE_R32_Q(hw, IXGBE_TXBUFCTRL); + regs_buff[1102] = IXGBE_R32_Q(hw, IXGBE_TXBUFDATA0); + regs_buff[1103] = IXGBE_R32_Q(hw, IXGBE_TXBUFDATA1); + regs_buff[1104] = IXGBE_R32_Q(hw, IXGBE_TXBUFDATA2); + regs_buff[1105] = IXGBE_R32_Q(hw, IXGBE_TXBUFDATA3); + regs_buff[1106] = IXGBE_R32_Q(hw, IXGBE_RXBUFCTRL); + regs_buff[1107] = IXGBE_R32_Q(hw, IXGBE_RXBUFDATA0); + regs_buff[1108] = IXGBE_R32_Q(hw, IXGBE_RXBUFDATA1); + regs_buff[1109] = IXGBE_R32_Q(hw, IXGBE_RXBUFDATA2); + regs_buff[1110] = IXGBE_R32_Q(hw, IXGBE_RXBUFDATA3); + for (i = 0; i < 8; i++) + regs_buff[1111 + i] = IXGBE_R32_Q(hw, IXGBE_PCIE_DIAG(i)); + regs_buff[1119] = IXGBE_R32_Q(hw, IXGBE_RFVAL); + regs_buff[1120] = IXGBE_R32_Q(hw, IXGBE_MDFTC1); + regs_buff[1121] = IXGBE_R32_Q(hw, IXGBE_MDFTC2); + regs_buff[1122] = IXGBE_R32_Q(hw, IXGBE_MDFTFIFO1); + regs_buff[1123] = IXGBE_R32_Q(hw, IXGBE_MDFTFIFO2); + regs_buff[1124] = IXGBE_R32_Q(hw, IXGBE_MDFTS); + regs_buff[1125] = IXGBE_R32_Q(hw, IXGBE_PCIEECCCTL); + regs_buff[1126] = IXGBE_R32_Q(hw, IXGBE_PBTXECC); + regs_buff[1127] = IXGBE_R32_Q(hw, IXGBE_PBRXECC); + + /* 82599 X540 specific registers */ + regs_buff[1128] = IXGBE_R32_Q(hw, IXGBE_MFLCN); + + /* 82599 X540 specific DCB registers */ + regs_buff[1129] = IXGBE_R32_Q(hw, IXGBE_RTRUP2TC); + regs_buff[1130] = IXGBE_R32_Q(hw, IXGBE_RTTUP2TC); + for (i = 0; i < 4; i++) + regs_buff[1131 + i] = IXGBE_R32_Q(hw, IXGBE_TXLLQ(i)); + regs_buff[1135] = IXGBE_R32_Q(hw, IXGBE_RTTBCNRM); + /* same as RTTQCNRM */ + regs_buff[1136] = IXGBE_R32_Q(hw, IXGBE_RTTBCNRD); + /* same as RTTQCNRR */ + + /* X540 specific DCB registers */ + regs_buff[1137] = IXGBE_R32_Q(hw, IXGBE_RTTQCNCR); + regs_buff[1138] = IXGBE_R32_Q(hw, IXGBE_RTTQCNTG); + + /* Security config registers */ + regs_buff[1139] = IXGBE_R32_Q(hw, IXGBE_SECTXCTRL); + regs_buff[1140] = IXGBE_R32_Q(hw, IXGBE_SECTXSTAT); + regs_buff[1141] = IXGBE_R32_Q(hw, IXGBE_SECTXBUFFAF); + regs_buff[1142] = IXGBE_R32_Q(hw, IXGBE_SECTXMINIFG); + regs_buff[1143] = IXGBE_R32_Q(hw, IXGBE_SECRXCTRL); + regs_buff[1144] = IXGBE_R32_Q(hw, IXGBE_SECRXSTAT); + +} + +/** + * ixgbe_get_eeprom_len_E610 - Get EEPROM length for E610 hardware + * @netdev: Network device structure + * + * This function returns the length of the EEPROM for E610 hardware by + * calculating the total size in bytes based on the word size. + * + * Return: The EEPROM length in bytes. + */ +static int ixgbe_get_eeprom_len_E610(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + + return adapter->hw.eeprom.word_size * 2; +} + +/** + * ixgbe_get_eeprom_len - Get EEPROM length for the network device + * @netdev: Network device structure + * + * This function returns the length of the EEPROM for the specified network + * device. If `IXGBE_NVMUPD_SUPPORT` is defined, it returns the length of the + * PCI resource. Otherwise, it calculates the EEPROM size in bytes based on + * the word size. + * + * Return: The EEPROM length in bytes. + */ +static int ixgbe_get_eeprom_len(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + return pci_resource_len(adapter->pdev, 0); +} + +static u8 ixgbe_nvmupd_get_module(u32 val) +{ + return (u8)(val & IXGBE_NVMUPD_MOD_PNT_MASK); +} + +static int ixgbe_nvmupd_validate_offset(struct ixgbe_adapter *adapter, + u32 offset) +{ + struct net_device *netdev = adapter->netdev; + + switch (offset) { + case IXGBE_STATUS: + case IXGBE_ESDP: + case IXGBE_MSCA: + case IXGBE_MSRWD: + case IXGBE_EEC: + case IXGBE_FLA: + case IXGBE_FLOP: + case IXGBE_SWSM: + case IXGBE_FWSM: + case IXGBE_FACTPS: + case IXGBE_GSSR: + case IXGBE_HICR: + case IXGBE_FWSTS: + return 0; + default: + if ((offset >= IXGBE_MAVTV(0) && offset <= IXGBE_MAVTV(7)) || + (offset >= IXGBE_RAL(0) && offset <= IXGBE_RAH(15))) + return 0; + } + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + switch (offset) { + case IXGBE_AUTOC: + case IXGBE_EERD: + case IXGBE_BARCTRL: + return 0; + default: + if (offset >= 0x00020000 && + offset <= ixgbe_get_eeprom_len(netdev)) + return 0; + } + break; + case ixgbe_mac_X540: + switch (offset) { + case IXGBE_EERD: + case IXGBE_EEWR: + case IXGBE_SRAMREL: + case IXGBE_BARCTRL: + return 0; + default: + if ((offset >= 0x00020000 && + offset <= ixgbe_get_eeprom_len(netdev))) + return 0; + } + break; + case ixgbe_mac_X550: + fallthrough; + case ixgbe_mac_E610: + switch (offset) { + case IXGBE_EEWR: + case IXGBE_SRAMREL: + case IXGBE_PHYCTL_82599: + case IXGBE_FWRESETCNT: + return 0; + default: + if (offset >= IXGBE_FLEX_MNG_PTR(0) && + offset <= IXGBE_FLEX_MNG_PTR(447)) + return 0; + } + break; + case ixgbe_mac_X550EM_x: + switch (offset) { + case IXGBE_PHYCTL_82599: + case IXGBE_NW_MNG_IF_SEL: + case IXGBE_FWRESETCNT: + case IXGBE_I2CCTL_X550: + return 0; + default: + if ((offset >= IXGBE_FLEX_MNG_PTR(0) && + offset <= IXGBE_FLEX_MNG_PTR(447)) || + (offset >= IXGBE_FUSES0_GROUP(0) && + offset <= IXGBE_FUSES0_GROUP(7))) + return 0; + } + break; + case ixgbe_mac_X550EM_a: + switch (offset) { + case IXGBE_PHYCTL_82599: + case IXGBE_NW_MNG_IF_SEL: + case IXGBE_FWRESETCNT: + case IXGBE_I2CCTL_X550: + case IXGBE_FLA_X550EM_a: + case IXGBE_SWSM_X550EM_a: + case IXGBE_FWSM_X550EM_a: + case IXGBE_SWFW_SYNC_X550EM_a: + case IXGBE_FACTPS_X550EM_a: + case IXGBE_EEC_X550EM_a: + return 0; + default: + if (offset >= IXGBE_FLEX_MNG_PTR(0) && + offset <= IXGBE_FLEX_MNG_PTR(447)) + return 0; + } + default: + break; + } + + return -ENOTTY; +} + +static int ixgbe_nvmupd_command(struct ixgbe_hw *hw, + struct ixgbe_nvm_access *nvm, + u8 *bytes) +{ + u32 command; + int ret_val = 0; + u8 module; + + command = nvm->command; + module = ixgbe_nvmupd_get_module(nvm->config); + + switch (command) { + case IXGBE_NVMUPD_CMD_REG_READ: + switch (module) { + case IXGBE_NVMUPD_EXEC_FEATURES: + if (nvm->data_size == hw->nvmupd_features.size) + memcpy(bytes, &hw->nvmupd_features, + hw->nvmupd_features.size); + else + ret_val = -ENOMEM; + break; + default: + if (ixgbe_nvmupd_validate_offset(hw->back, nvm->offset)) + return -ENOTTY; + + if (nvm->data_size == 1) + *((u8 *)bytes) = IXGBE_R8_Q(hw, nvm->offset); + else + *((u32 *)bytes) = IXGBE_R32_Q(hw, nvm->offset); + break; + } + break; + case IXGBE_NVMUPD_CMD_REG_WRITE: + if (ixgbe_nvmupd_validate_offset(hw->back, nvm->offset)) + return -ENOTTY; + + IXGBE_WRITE_REG(hw, nvm->offset, *((u32 *)bytes)); + break; + } + + return ret_val; +} + +/** + * ixgbe_get_eeprom - Retrieve EEPROM data for the network device + * @netdev: Network device structure + * @eeprom: Pointer to ethtool_eeprom structure specifying the EEPROM section + * @bytes: Buffer to store the retrieved EEPROM data + * + * This function retrieves a specified section of the EEPROM data for the + * network device. It calculates the range of EEPROM words to read based on + * the offset and length provided in the `eeprom` structure. The function + * supports both standard EEPROM access and, if enabled, NVM update commands. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_get_eeprom(struct net_device *netdev, + struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u16 *eeprom_buff; + int first_word, last_word, eeprom_len; + struct ixgbe_nvm_access *nvm; + u32 magic; + int ret_val = 0; + u16 i; + + if (eeprom->len == 0) + return -EINVAL; + + magic = hw->vendor_id | (hw->device_id << 16); + if (eeprom->magic && eeprom->magic != magic) { + nvm = (struct ixgbe_nvm_access *)eeprom; + ret_val = ixgbe_nvmupd_command(hw, nvm, bytes); + return ret_val; + } + + /* normal ethtool get_eeprom support */ + eeprom->magic = hw->vendor_id | (hw->device_id << 16); + + first_word = eeprom->offset >> 1; + last_word = (eeprom->offset + eeprom->len - 1) >> 1; + eeprom_len = last_word - first_word + 1; + + eeprom_buff = kzalloc(sizeof(u16) * eeprom_len, GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + ret_val = hw->eeprom.ops.read_buffer(hw, first_word, eeprom_len, + eeprom_buff); + + /* Device's eeprom is always little-endian, word addressable */ + for (i = 0; i < eeprom_len; i++) + eeprom_buff[i] = le16_to_cpu(eeprom_buff[i]); + + memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); + kfree(eeprom_buff); + + return ret_val; +} + +/** + * ixgbe_set_eeprom - Write data to the EEPROM of the network device + * @netdev: Network device structure + * @eeprom: Pointer to ethtool_eeprom structure specifying the EEPROM section + * @bytes: Buffer containing the data to be written to the EEPROM + * + * This function writes the specified data to the EEPROM of the network device. + * It handles read-modify-write operations for unaligned offsets and updates + * the EEPROM checksum after writing. The function supports both standard + * EEPROM access and, if enabled, NVM update commands. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_eeprom(struct net_device *netdev, + struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + int max_len, first_word, last_word, ret_val = 0; + struct ixgbe_nvm_access *nvm; + u32 magic; + u16 *eeprom_buff, i; + u8 *ptr; + + if (eeprom->len == 0) + return -EINVAL; + + magic = hw->vendor_id | (hw->device_id << 16); + if (eeprom->magic && eeprom->magic != magic) { + nvm = (struct ixgbe_nvm_access *)eeprom; + ret_val = ixgbe_nvmupd_command(hw, nvm, bytes); + return ret_val; + } + + /* normal ethtool set_eeprom support */ + + if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) + return -EINVAL; + + max_len = hw->eeprom.word_size * 2; + + first_word = eeprom->offset >> 1; + last_word = (eeprom->offset + eeprom->len - 1) >> 1; + eeprom_buff = kzalloc(max_len, GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + ptr = (u8 *)eeprom_buff; + + if (eeprom->offset & 1) { + /* + * need read/modify/write of first changed EEPROM word + * only the second byte of the word is being modified + */ + ret_val = hw->eeprom.ops.read(hw, first_word, &eeprom_buff[0]); + if (ret_val) + goto err; + + ptr++; + } + if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) { + /* + * need read/modify/write of last changed EEPROM word + * only the first byte of the word is being modified + */ + ret_val = hw->eeprom.ops.read(hw, last_word, + &eeprom_buff[last_word - first_word]); + if (ret_val) + goto err; + } + + /* Device's eeprom is always little-endian, word addressable */ + for (i = 0; i < last_word - first_word + 1; i++) + eeprom_buff[i] = le16_to_cpu(eeprom_buff[i]); + + memcpy(ptr, bytes, eeprom->len); + + for (i = 0; i < last_word - first_word + 1; i++) + eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); + + ret_val = hw->eeprom.ops.write_buffer(hw, first_word, + last_word - first_word + 1, + eeprom_buff); + + /* Update the checksum */ + if (ret_val == 0) + hw->eeprom.ops.update_checksum(hw); + +err: + kfree(eeprom_buff); + return ret_val; +} + +/** + * ixgbe_get_drvinfo - Provide driver information for the network device + * @netdev: Network device structure + * @drvinfo: Pointer to ethtool_drvinfo to be filled with driver info + * + * This function fills the `ethtool_drvinfo` structure with the driver name, + * version, firmware version, and bus information for the specified network + * device. It uses `strscpy` for safe string copying. + */ +static void ixgbe_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + strscpy(drvinfo->driver, ixgbe_driver_name, + sizeof(drvinfo->driver)); + strscpy(drvinfo->version, ixgbe_driver_version, + sizeof(drvinfo->version)); + + strscpy(drvinfo->fw_version, adapter->eeprom_id, + sizeof(drvinfo->fw_version)); + strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + +#ifdef HAVE_ETHTOOL_GET_SSET_COUNT + drvinfo->n_priv_flags = IXGBE_PRIV_FLAGS_STR_LEN; +#endif +} + +#ifdef HAVE_ETHTOOL_EXTENDED_RINGPARAMS +/** + * ixgbe_get_ringparam - Retrieve ring parameters for the network device + * @netdev: Network device structure + * @ring: Pointer to ethtool_ringparam structure to be filled with ring parameters + * @ker: (Optional) Kernel-specific ring parameters (unused) + * @extack: (Optional) Netlink extended acknowledgment structure (unused) + * + * This function populates the `ethtool_ringparam` structure with the current + * and maximum ring parameters for the specified network device, including + * receive and transmit ring sizes. + */ +static void +ixgbe_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam __always_unused *ker, + struct netlink_ext_ack __always_unused *extack) +#else +static void ixgbe_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +#endif /* HAVE_ETHTOOL_EXTENDED_RINGPARAMS */ +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + ring->rx_max_pending = IXGBE_MAX_NUM_DESCRIPTORS; + ring->tx_max_pending = IXGBE_MAX_NUM_DESCRIPTORS; + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->rx_pending = adapter->rx_ring_count; + ring->tx_pending = adapter->tx_ring_count; + ring->rx_mini_pending = 0; + ring->rx_jumbo_pending = 0; +} + +#ifdef HAVE_ETHTOOL_EXTENDED_RINGPARAMS +/** + * ixgbe_set_ringparam - Set ring parameters for the network device + * @netdev: Network device structure + * @ring: Pointer to ethtool_ringparam structure with desired ring settings + * @ker: (Optional) Kernel-specific ring parameters (unused) + * @extack: (Optional) Netlink extended acknowledgment structure (unused) + * + * This function configures the ring parameters for the specified network device + * based on the provided `ethtool_ringparam` structure. It validates the settings, + * updates the ring sizes, and reallocates resources if necessary. The function + * handles both transmit and receive rings, and supports XDP if enabled. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int +ixgbe_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam __always_unused *ker, + struct netlink_ext_ack __always_unused *extack) +#else +static int ixgbe_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +#endif /* HAVE_ETHTOOL_EXTENDED_RINGPARAMS */ +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_ring *temp_ring; + int i, j, err = 0; + u32 new_rx_count, new_tx_count; + + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + + if (ring->tx_pending > IXGBE_MAX_NUM_DESCRIPTORS || + ring->tx_pending < IXGBE_MIN_NUM_DESCRIPTORS || + ring->rx_pending > IXGBE_MAX_NUM_DESCRIPTORS || + ring->rx_pending < IXGBE_MIN_NUM_DESCRIPTORS) { + netdev_info(netdev, + "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n", + ring->tx_pending, ring->rx_pending, + IXGBE_MIN_NUM_DESCRIPTORS, + IXGBE_MAX_NUM_DESCRIPTORS); + return -EINVAL; + } + + new_tx_count = ALIGN(ring->tx_pending, + IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); + new_rx_count = ALIGN(ring->rx_pending, + IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); + + if ((new_tx_count == adapter->tx_ring_count) && + (new_rx_count == adapter->rx_ring_count)) { + /* nothing to do */ + return 0; + } + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + /* If there is a AF_XDP UMEM attached to any of Rx rings, + * disallow changing the number of descriptors -- regardless + * if the netdev is running or not. + */ + if (ixgbe_xsk_any_rx_ring_enabled(adapter)) + return -EBUSY; +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ + + while (test_and_set_bit(__IXGBE_RESETTING, adapter->state)) + usleep_range(1000, 2000); + + if (!netif_running(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i]->count = new_tx_count; + for (i = 0; i < adapter->num_xdp_queues; i++) + adapter->xdp_ring[i]->count = new_tx_count; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i]->count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->xdp_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; + } + + /* allocate temporary buffer to store rings in */ + i = max_t(int, adapter->num_tx_queues + adapter->num_xdp_queues, + adapter->num_rx_queues); + temp_ring = vmalloc(i * sizeof(struct ixgbe_ring)); + + if (!temp_ring) { + err = -ENOMEM; + goto clear_reset; + } + + ixgbe_down(adapter); + + /* + * Setup new Tx resources and free the old Tx resources in that order. + * We can then assign the new resources to the rings via a memcpy. + * The advantage to this approach is that we are guaranteed to still + * have resources even in the case of an allocation failure. + */ + if (new_tx_count != adapter->tx_ring_count) { + for (i = 0; i < adapter->num_tx_queues; i++) { + memcpy(&temp_ring[i], adapter->tx_ring[i], + sizeof(struct ixgbe_ring)); + + temp_ring[i].count = new_tx_count; + err = ixgbe_setup_tx_resources(&temp_ring[i]); + if (err) { + while (i) { + i--; + ixgbe_free_tx_resources(&temp_ring[i]); + } + goto err_setup; + } + } + + for (j = 0; j < adapter->num_xdp_queues; j++, i++) { + memcpy(&temp_ring[i], adapter->xdp_ring[j], + sizeof(struct ixgbe_ring)); + + temp_ring[i].count = new_tx_count; + err = ixgbe_setup_tx_resources(&temp_ring[i]); + if (err) { + while (i) { + i--; + ixgbe_free_tx_resources(&temp_ring[i]); + } + goto err_setup; + } + } + + for (i = 0; i < adapter->num_tx_queues; i++) { + ixgbe_free_tx_resources(adapter->tx_ring[i]); + + memcpy(adapter->tx_ring[i], &temp_ring[i], + sizeof(struct ixgbe_ring)); + } + for (j = 0; j < adapter->num_xdp_queues; j++, i++) { + ixgbe_free_tx_resources(adapter->xdp_ring[j]); + + memcpy(adapter->xdp_ring[j], &temp_ring[i], + sizeof(struct ixgbe_ring)); + } + + adapter->tx_ring_count = new_tx_count; + } + + /* Repeat the process for the Rx rings if needed */ + if (new_rx_count != adapter->rx_ring_count) { + for (i = 0; i < adapter->num_rx_queues; i++) { + memcpy(&temp_ring[i], adapter->rx_ring[i], + sizeof(struct ixgbe_ring)); +#ifdef HAVE_XDP_BUFF_RXQ + + /* Clear copied XDP RX-queue info */ + memset(&temp_ring[i].xdp_rxq, 0, + sizeof(temp_ring[i].xdp_rxq)); +#endif + + temp_ring[i].count = new_rx_count; + err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]); + if (err) { + while (i) { + i--; + ixgbe_free_rx_resources(&temp_ring[i]); + } + goto err_setup; + } + } + + + for (i = 0; i < adapter->num_rx_queues; i++) { + ixgbe_free_rx_resources(adapter->rx_ring[i]); + + memcpy(adapter->rx_ring[i], &temp_ring[i], + sizeof(struct ixgbe_ring)); + } + + adapter->rx_ring_count = new_rx_count; + } + +err_setup: + ixgbe_up(adapter); + vfree(temp_ring); +clear_reset: + clear_bit(__IXGBE_RESETTING, adapter->state); + return err; +} + +#ifndef HAVE_ETHTOOL_GET_SSET_COUNT +/** + * ixgbe_get_stats_count - Get the number of statistics available + * @netdev: Network device structure + * + * This function returns the total number of statistics available for the + * specified network device. The count is defined by the constant + * `IXGBE_STATS_LEN`. + * + * Return: The number of available statistics. + */ +static int ixgbe_get_stats_count(struct net_device *netdev) +{ + return IXGBE_STATS_LEN; +} + +#else /* HAVE_ETHTOOL_GET_SSET_COUNT */ +/** + * ixgbe_get_sset_count - Get the number of strings in a specified set + * @netdev: Network device structure + * @sset: String set identifier + * + * This function returns the number of strings in the specified string set for + * the network device. It supports test, statistics, and private flags string + * sets. If the string set is not supported, it returns an error. + * + * Return: The number of strings in the specified set, or -EOPNOTSUPP if the set + * is not supported. + */ +static int ixgbe_get_sset_count(struct net_device *netdev, int sset) +{ +#ifdef HAVE_TX_MQ +#ifndef HAVE_NETDEV_SELECT_QUEUE + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#endif +#endif + + switch (sset) { + case ETH_SS_TEST: + return IXGBE_TEST_LEN; + case ETH_SS_STATS: + return IXGBE_STATS_LEN; + case ETH_SS_PRIV_FLAGS: + return IXGBE_PRIV_FLAGS_STR_LEN; + default: + return -EOPNOTSUPP; + } +} +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + +/** + * ixgbe_get_ethtool_stats - Retrieve ethtool statistics for the network device + * @netdev: Network device structure + * @stats: Unused ethtool_stats structure + * @data: Buffer to store the retrieved statistics + * + * This function populates the provided `data` buffer with various statistics + * for the network device, including network, global, and per-queue statistics. + * It updates the adapter's statistics and iterates over transmit and receive + * queues to gather packet and byte counts, among other metrics. + */ +static void ixgbe_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats __always_unused *stats, u64 *data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +#ifdef HAVE_NDO_GET_STATS64 + const struct rtnl_link_stats64 *net_stats; + struct rtnl_link_stats64 temp; + unsigned int start; +#else +#ifdef HAVE_NETDEV_STATS_IN_NETDEV + struct net_device_stats *net_stats = &netdev->stats; +#else + struct net_device_stats *net_stats = &adapter->net_stats; +#endif +#endif + u64 *queue_stat; + int stat_count, k; + struct ixgbe_ring *ring; + int i, data_index = 0; + char *p; + + ixgbe_update_stats(adapter); +#ifdef HAVE_NDO_GET_STATS64 + net_stats = dev_get_stats(netdev, &temp); +#endif + + for (i = 0; i < IXGBE_NETDEV_STATS_LEN; i++) { + p = (char *)net_stats + ixgbe_gstrings_net_stats[i].stat_offset; + data[data_index++] = (ixgbe_gstrings_net_stats[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } + for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { + p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset; + data[data_index++] = (ixgbe_gstrings_stats[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } + for (i = 0; i < IXGBE_NUM_TX_QUEUES; i++) { + ring = adapter->tx_ring[i]; + if (!ring) { + data[data_index++] = 0; + data[data_index++] = 0; +#ifdef BP_EXTENDED_STATS + data[data_index++] = 0; + data[data_index++] = 0; + data[data_index++] = 0; +#endif + continue; + } + +#ifdef HAVE_NDO_GET_STATS64 + do { + start = u64_stats_fetch_begin(&ring->syncp); +#endif + data[data_index] = ring->stats.packets; + data[data_index+1] = ring->stats.bytes; +#ifdef HAVE_NDO_GET_STATS64 + } while (u64_stats_fetch_retry(&ring->syncp, start)); +#endif + data_index += 2; +#ifdef BP_EXTENDED_STATS + data[data_index] = ring->stats.yields; + data[data_index+1] = ring->stats.misses; + data[data_index+2] = ring->stats.cleaned; + data_index += 3; +#endif + } + for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) { + ring = adapter->rx_ring[i]; + if (!ring) { + data[data_index++] = 0; + data[data_index++] = 0; +#ifdef BP_EXTENDED_STATS + data[data_index++] = 0; + data[data_index++] = 0; + data[data_index++] = 0; +#endif + continue; + } + +#ifdef HAVE_NDO_GET_STATS64 + do { + start = u64_stats_fetch_begin(&ring->syncp); +#endif + data[data_index] = ring->stats.packets; + data[data_index+1] = ring->stats.bytes; +#ifdef HAVE_NDO_GET_STATS64 + } while (u64_stats_fetch_retry(&ring->syncp, start)); +#endif + data_index += 2; +#ifdef BP_EXTENDED_STATS + data[data_index] = ring->stats.yields; + data[data_index+1] = ring->stats.misses; + data[data_index+2] = ring->stats.cleaned; + data_index += 3; +#endif + } + for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { + data[data_index++] = adapter->stats.pxontxc[i]; + data[data_index++] = adapter->stats.pxofftxc[i]; + } + for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { + data[data_index++] = adapter->stats.pxonrxc[i]; + data[data_index++] = adapter->stats.pxoffrxc[i]; + } + stat_count = sizeof(struct vf_stats) / sizeof(u64); + for (i = 0; i < adapter->num_vfs; i++) { + queue_stat = (u64 *)&adapter->vfinfo[i].vfstats; + for (k = 0; k < stat_count; k++) + data[data_index + k] = queue_stat[k]; + queue_stat = (u64 *)&adapter->vfinfo[i].saved_rst_vfstats; + for (k = 0; k < stat_count; k++) + data[data_index + k] += queue_stat[k]; + data_index += k; + } +} + +/** + * ixgbe_get_strings - Retrieve string set for the network device + * @netdev: Network device structure + * @stringset: Identifier for the string set to retrieve + * @data: Buffer to store the retrieved strings + * + * This function populates the provided buffer with strings corresponding to + * the specified string set for the network device. It supports test strings, + * statistics strings, and private flags strings, depending on the string set + * identifier. + */ +static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, + u8 *data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + char *p = (char *)data; + unsigned int i; + + switch (stringset) { + case ETH_SS_TEST: + memcpy(data, *ixgbe_gstrings_test, + IXGBE_TEST_LEN * ETH_GSTRING_LEN); + break; + case ETH_SS_STATS: + for (i = 0; i < IXGBE_NETDEV_STATS_LEN; i++) { + memcpy(p, ixgbe_gstrings_net_stats[i].stat_string, + ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { + memcpy(p, ixgbe_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < IXGBE_NUM_TX_QUEUES; i++) { + snprintf(p, ETH_GSTRING_LEN, + "tx_queue_%u_packets", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "tx_queue_%u_bytes", i); + p += ETH_GSTRING_LEN; +#ifdef BP_EXTENDED_STATS + snprintf(p, ETH_GSTRING_LEN, + "tx_queue_%u_bp_napi_yield", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "tx_queue_%u_bp_misses", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "tx_queue_%u_bp_cleaned", i); + p += ETH_GSTRING_LEN; +#endif /* BP_EXTENDED_STATS */ + } + for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) { + snprintf(p, ETH_GSTRING_LEN, + "rx_queue_%u_packets", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "rx_queue_%u_bytes", i); + p += ETH_GSTRING_LEN; +#ifdef BP_EXTENDED_STATS + snprintf(p, ETH_GSTRING_LEN, + "rx_queue_%u_bp_poll_yield", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "rx_queue_%u_bp_misses", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "rx_queue_%u_bp_cleaned", i); + p += ETH_GSTRING_LEN; +#endif /* BP_EXTENDED_STATS */ + } + for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { + snprintf(p, ETH_GSTRING_LEN, "tx_pb_%u_pxon", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, "tx_pb_%u_pxoff", i); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { + snprintf(p, ETH_GSTRING_LEN, "rx_pb_%u_pxon", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, "rx_pb_%u_pxoff", i); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < adapter->num_vfs; i++) { + snprintf(p, ETH_GSTRING_LEN, "VF %u Rx Packets", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, "VF %u Rx Bytes", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, "VF %u Tx Packets", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, "VF %u Tx Bytes", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, "VF %u MC Packets", i); + p += ETH_GSTRING_LEN; + } + /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */ + break; +#ifdef HAVE_ETHTOOL_GET_SSET_COUNT + case ETH_SS_PRIV_FLAGS: + memcpy(data, ixgbe_priv_flags_strings, + IXGBE_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN); + break; +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + } +} + +static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data) +{ + struct ixgbe_hw *hw = &adapter->hw; + bool link_up; + u32 link_speed = 0; + + if (IXGBE_REMOVED(hw->hw_addr)) { + *data = 1; + return 1; + } + *data = 0; + hw->mac.ops.check_link(hw, &link_speed, &link_up, true); + if (link_up) + return *data; + else + *data = 1; + return *data; +} + +/* ethtool register test data */ +struct ixgbe_reg_test { + u16 reg; + u8 array_len; + u8 test_type; + u32 mask; + u32 write; +}; + +/* In the hardware, registers are laid out either singly, in arrays + * spaced 0x40 bytes apart, or in contiguous tables. We assume + * most tests take place on arrays or single registers (handled + * as a single-element array) and special-case the tables. + * Table tests are always pattern tests. + * + * We also make provision for some required setup steps by specifying + * registers to be written without any read-back testing. + */ + +#define PATTERN_TEST 1 +#define SET_READ_TEST 2 +#define WRITE_NO_TEST 3 +#define TABLE32_TEST 4 +#define TABLE64_TEST_LO 5 +#define TABLE64_TEST_HI 6 + +/* default 82599 register test */ +static struct ixgbe_reg_test reg_test_82599[] = { + { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, + { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, + { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 }, + { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, + { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, + { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, + { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, + { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, + { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFF80 }, + { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000001, 0x00000001 }, + { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x8001FFFF, 0x800CFFFF }, + { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { .reg = 0 } +}; + +/* default 82598 register test */ +static struct ixgbe_reg_test reg_test_82598[] = { + { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, + { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, + { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 }, + { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, + /* Enable all four RX queues before testing. */ + { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, + /* RDH is read-only for 82598, only test RDT. */ + { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, + { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, + { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, + { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_TIPG, 1, PATTERN_TEST, 0x000000FF, 0x000000FF }, + { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, + { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, + { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000003, 0x00000003 }, + { IXGBE_DTXCTL, 1, SET_READ_TEST, 0x00000005, 0x00000005 }, + { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, + { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x800CFFFF, 0x800CFFFF }, + { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { .reg = 0 } +}; + + +static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg, + u32 mask, u32 write) +{ + u32 pat, val, before; + static const u32 test_pattern[] = { + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF + }; + + if (IXGBE_REMOVED(adapter->hw.hw_addr)) { + *data = 1; + return true; + } + for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) { + before = IXGBE_READ_REG(&adapter->hw, reg); + IXGBE_WRITE_REG(&adapter->hw, reg, test_pattern[pat] & write); + val = IXGBE_READ_REG(&adapter->hw, reg); + if (val != (test_pattern[pat] & write & mask)) { + e_err(drv, + "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", + reg, val, test_pattern[pat] & write & mask); + *data = reg; + IXGBE_WRITE_REG(&adapter->hw, reg, before); + return true; + } + IXGBE_WRITE_REG(&adapter->hw, reg, before); + } + return false; +} + +static bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg, + u32 mask, u32 write) +{ + u32 val, before; + + if (IXGBE_REMOVED(adapter->hw.hw_addr)) { + *data = 1; + return true; + } + before = IXGBE_READ_REG(&adapter->hw, reg); + IXGBE_WRITE_REG(&adapter->hw, reg, write & mask); + val = IXGBE_READ_REG(&adapter->hw, reg); + if ((write & mask) != (val & mask)) { + e_err(drv, + "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", + reg, (val & mask), (write & mask)); + *data = reg; + IXGBE_WRITE_REG(&adapter->hw, reg, before); + return true; + } + IXGBE_WRITE_REG(&adapter->hw, reg, before); + return false; +} + +static bool ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) +{ + struct ixgbe_reg_test *test; + struct ixgbe_hw *hw = &adapter->hw; + u32 value, before, after; + u32 i, toggle; + + if (IXGBE_REMOVED(hw->hw_addr)) { + e_err(drv, "Adapter removed - register test blocked\n"); + *data = 1; + return true; + } + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + toggle = 0x7FFFF3FF; + test = reg_test_82598; + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + toggle = 0x7FFFF30F; + test = reg_test_82599; + break; + default: + *data = 1; + return true; + } + + /* + * Because the status register is such a special case, + * we handle it separately from the rest of the register + * tests. Some bits are read-only, some toggle, and some + * are writeable on newer MACs. + */ + before = IXGBE_READ_REG(hw, IXGBE_STATUS); + value = IXGBE_READ_REG(hw, IXGBE_STATUS) & toggle; + IXGBE_WRITE_REG(hw, IXGBE_STATUS, toggle); + after = IXGBE_READ_REG(hw, IXGBE_STATUS) & toggle; + if (value != after) { + e_err(drv, + "failed STATUS register test got: 0x%08X expected: 0x%08X\n", + after, value); + *data = 1; + return true; + } + /* restore previous status */ + IXGBE_WRITE_REG(hw, IXGBE_STATUS, before); + + /* + * Perform the remainder of the register test, looping through + * the test table until we either fail or reach the null entry. + */ + while (test->reg) { + for (i = 0; i < test->array_len; i++) { + bool b = false; + + switch (test->test_type) { + case PATTERN_TEST: + b = reg_pattern_test(adapter, data, + test->reg + (i * 0x40), + test->mask, + test->write); + break; + case SET_READ_TEST: + b = reg_set_and_check(adapter, data, + test->reg + (i * 0x40), + test->mask, + test->write); + break; + case WRITE_NO_TEST: + IXGBE_WRITE_REG(hw, test->reg + (i * 0x40), + test->write); + break; + case TABLE32_TEST: + b = reg_pattern_test(adapter, data, + test->reg + (i * 4), + test->mask, + test->write); + break; + case TABLE64_TEST_LO: + b = reg_pattern_test(adapter, data, + test->reg + (i * 8), + test->mask, + test->write); + break; + case TABLE64_TEST_HI: + b = reg_pattern_test(adapter, data, + (test->reg + 4) + (i * 8), + test->mask, + test->write); + break; + } + if (b) + return true; + } + test++; + } + + *data = 0; + return false; +} + +static bool ixgbe_eeprom_test(struct ixgbe_adapter *adapter, u64 *data) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (hw->eeprom.ops.validate_checksum(hw, NULL)) { + *data = 1; + return true; + } else { + *data = 0; + return false; + } +} + +static irqreturn_t ixgbe_test_intr(int __always_unused irq, void *data) +{ + struct net_device *netdev = (struct net_device *) data; + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + adapter->test_icr |= IXGBE_READ_REG(&adapter->hw, IXGBE_EICR); + + return IRQ_HANDLED; +} + +static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) +{ + struct net_device *netdev = adapter->netdev; + u32 mask, i = 0, shared_int = true; + u32 irq = adapter->pdev->irq; + + if (IXGBE_REMOVED(adapter->hw.hw_addr)) { + *data = 1; + return -1; + } + *data = 0; + + /* Hook up test interrupt handler just for this test */ + if (adapter->msix_entries) { + /* NOTE: we don't test MSI-X interrupts here, yet */ + return 0; + } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { + shared_int = false; + if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name, + netdev)) { + *data = 1; + return -1; + } + } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED, + netdev->name, netdev)) { + shared_int = false; + } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED, + netdev->name, netdev)) { + *data = 1; + return -1; + } + e_info(hw, "testing %s interrupt\n", + (shared_int ? "shared" : "unshared")); + + /* Disable all the interrupts */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); + IXGBE_WRITE_FLUSH(&adapter->hw); + usleep_range(10000, 20000); + + /* Test each interrupt */ + for (; i < 10; i++) { + /* Interrupt to test */ + mask = 1 << i; + + if (!shared_int) { + /* + * Disable the interrupts to be reported in + * the cause register and then force the same + * interrupt and see if one gets posted. If + * an interrupt was posted to the bus, the + * test failed. + */ + adapter->test_icr = 0; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, + ~mask & 0x00007FFF); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, + ~mask & 0x00007FFF); + IXGBE_WRITE_FLUSH(&adapter->hw); + usleep_range(10000, 20000); + + if (adapter->test_icr & mask) { + *data = 3; + break; + } + } + + /* + * Enable the interrupt to be reported in the cause + * register and then force the same interrupt and see + * if one gets posted. If an interrupt was not posted + * to the bus, the test failed. + */ + adapter->test_icr = 0; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); + IXGBE_WRITE_FLUSH(&adapter->hw); + usleep_range(10000, 20000); + + if (!(adapter->test_icr & mask)) { + *data = 4; + break; + } + + if (!shared_int) { + /* + * Disable the other interrupts to be reported in + * the cause register and then force the other + * interrupts and see if any get posted. If + * an interrupt was posted to the bus, the + * test failed. + */ + adapter->test_icr = 0; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, + ~mask & 0x00007FFF); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, + ~mask & 0x00007FFF); + IXGBE_WRITE_FLUSH(&adapter->hw); + usleep_range(10000, 20000); + + if (adapter->test_icr) { + *data = 5; + break; + } + } + } + + /* Disable all the interrupts */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); + IXGBE_WRITE_FLUSH(&adapter->hw); + usleep_range(10000, 20000); + + /* Unhook test interrupt handler */ + free_irq(irq, netdev); + + return *data; +} + +static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) +{ + /* Shut down the DMA engines now so they can be reinitialized later, + * since the test rings and normally used rings should overlap on + * queue 0 we can just use the standard disable Rx/Tx calls and they + * will take care of disabling the test rings for us. + */ + + /* first Rx */ + ixgbe_disable_rx_queue(adapter); + + /* now Tx */ + ixgbe_disable_tx_queue(adapter); + + ixgbe_reset(adapter); + + ixgbe_free_tx_resources(&adapter->test_tx_ring); + ixgbe_free_rx_resources(&adapter->test_rx_ring); +} + +static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) +{ + struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; + struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; + u32 rctl, reg_data; + int ret_val; + int err; + + /* Setup Tx descriptor ring and Tx buffers */ + tx_ring->count = IXGBE_DEFAULT_TXD; + tx_ring->queue_index = 0; + tx_ring->dev = ixgbe_pf_to_dev(adapter); + tx_ring->netdev = adapter->netdev; + tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx; + + err = ixgbe_setup_tx_resources(tx_ring); + if (err) + return 1; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); + reg_data |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); + break; + default: + break; + } + + ixgbe_configure_tx_ring(adapter, tx_ring); + + /* Setup Rx Descriptor ring and Rx buffers */ + rx_ring->count = IXGBE_DEFAULT_RXD; + rx_ring->queue_index = 0; + rx_ring->dev = ixgbe_pf_to_dev(adapter); + rx_ring->netdev = adapter->netdev; + rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + rx_ring->rx_buf_len = IXGBE_RXBUFFER_2K; +#endif + + err = ixgbe_setup_rx_resources(adapter, rx_ring); + if (err) { + ret_val = 4; + goto err_nomem; + } + + ixgbe_disable_rx(&adapter->hw); + + ixgbe_configure_rx_ring(adapter, rx_ring); + + rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); + rctl |= IXGBE_RXCTRL_DMBYPS; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl); + ixgbe_enable_rx(&adapter->hw); + + return 0; + +err_nomem: + ixgbe_free_desc_rings(adapter); + return ret_val; +} + +static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reg_data; + + + /* Setup MAC loopback */ + reg_data = IXGBE_READ_REG(hw, IXGBE_HLREG0); + reg_data |= IXGBE_HLREG0_LPBK; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg_data); + + reg_data = IXGBE_READ_REG(hw, IXGBE_FCTRL); + reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg_data); + + /* X540 needs to set the MACC.FLU bit to force link up */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + case ixgbe_mac_X540: + reg_data = IXGBE_READ_REG(hw, IXGBE_MACC); + reg_data |= IXGBE_MACC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data); + break; + default: + if (hw->mac.orig_autoc) { + reg_data = hw->mac.orig_autoc | IXGBE_AUTOC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_data); + } else { + return 10; + } + } + IXGBE_WRITE_FLUSH(hw); + usleep_range(10000, 20000); + + /* Disable Atlas Tx lanes; re-enabled in reset path */ + if (hw->mac.type == ixgbe_mac_82598EB) { + u8 atlas; + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &atlas); + atlas |= IXGBE_ATLAS_PDN_TX_REG_EN; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, atlas); + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &atlas); + atlas |= IXGBE_ATLAS_PDN_TX_10G_QL_ALL; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, atlas); + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &atlas); + atlas |= IXGBE_ATLAS_PDN_TX_1G_QL_ALL; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, atlas); + + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &atlas); + atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL; + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, atlas); + } + + return 0; +} + +static void ixgbe_loopback_cleanup(struct ixgbe_adapter *adapter) +{ + u32 reg_data; + + reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); + reg_data &= ~IXGBE_HLREG0_LPBK; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); +} + +static void ixgbe_create_lbtest_frame(struct sk_buff *skb, + unsigned int frame_size) +{ + memset(skb->data, 0xFF, frame_size); + frame_size >>= 1; + memset(&skb->data[frame_size], 0xAA, frame_size / 2 - 1); + memset(&skb->data[frame_size + 10], 0xBE, 1); + memset(&skb->data[frame_size + 12], 0xAF, 1); +} + +static bool ixgbe_check_lbtest_frame(struct ixgbe_rx_buffer *rx_buffer, + unsigned int frame_size) +{ + unsigned char *data; + bool match = true; + + frame_size >>= 1; + +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + data = rx_buffer->skb->data; +#else + data = kmap(rx_buffer->page) + rx_buffer->page_offset; +#endif + + if (data[3] != 0xFF || + data[frame_size + 10] != 0xBE || + data[frame_size + 12] != 0xAF) + match = false; + +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + kunmap(rx_buffer->page); + +#endif + return match; +} + +static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, + struct ixgbe_ring *tx_ring, + unsigned int size) +{ + union ixgbe_adv_rx_desc *rx_desc; +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + const int bufsz = rx_ring->rx_buf_len; +#else + const int bufsz = ixgbe_rx_bufsz(rx_ring); +#endif + u16 rx_ntc, tx_ntc, count = 0; + + /* initialize next to clean and descriptor values */ + rx_ntc = rx_ring->next_to_clean; + tx_ntc = tx_ring->next_to_clean; + rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc); + + while (tx_ntc != tx_ring->next_to_use) { + union ixgbe_adv_tx_desc *tx_desc; + struct ixgbe_tx_buffer *tx_buffer; + + tx_desc = IXGBE_TX_DESC(tx_ring, tx_ntc); + + /* if DD is not set transmit has not completed */ + if (!(tx_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD))) + return count; + + /* unmap buffer on Tx side */ + tx_buffer = &tx_ring->tx_buffer_info[tx_ntc]; + + /* Free all the Tx ring sk_buffs */ + dev_kfree_skb_any(tx_buffer->skb); + + /* unmap skb header data */ + dma_unmap_single(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + dma_unmap_len_set(tx_buffer, len, 0); + + /* increment Tx next to clean counter */ + tx_ntc++; + if (tx_ntc == tx_ring->count) + tx_ntc = 0; + } + + while (rx_desc->wb.upper.length) { + struct ixgbe_rx_buffer *rx_buffer; + + /* check Rx buffer */ + rx_buffer = &rx_ring->rx_buffer_info[rx_ntc]; + + /* sync Rx buffer for CPU read */ + dma_sync_single_for_cpu(rx_ring->dev, + rx_buffer->dma, + bufsz, + DMA_FROM_DEVICE); + + /* verify contents of skb */ + if (ixgbe_check_lbtest_frame(rx_buffer, size)) + count++; + else + break; + + /* sync Rx buffer for device write */ + dma_sync_single_for_device(rx_ring->dev, + rx_buffer->dma, + bufsz, + DMA_FROM_DEVICE); + + /* increment Rx next to clean counter */ + rx_ntc++; + if (rx_ntc == rx_ring->count) + rx_ntc = 0; + + /* fetch next descriptor */ + rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc); + } + + /* re-map buffers to ring, store next to clean values */ + ixgbe_alloc_rx_buffers(rx_ring, count); + rx_ring->next_to_clean = rx_ntc; + tx_ring->next_to_clean = tx_ntc; + + return count; +} + +static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) +{ + struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; + struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; + int i, j, lc, ret_val = 0; + unsigned int size = 1024; + netdev_tx_t tx_ret_val; + struct sk_buff *skb; + u32 flags_orig = adapter->flags; + + /* DCB can modify the frames on Tx */ + adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; + + /* allocate test skb */ + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return 11; + + /* place data into test skb */ + ixgbe_create_lbtest_frame(skb, size); + skb_put(skb, size); + + /* + * Calculate the loop count based on the largest descriptor ring + * The idea is to wrap the largest ring a number of times using 64 + * send/receive pairs during each loop + */ + + if (rx_ring->count <= tx_ring->count) + lc = ((tx_ring->count / 64) * 2) + 1; + else + lc = ((rx_ring->count / 64) * 2) + 1; + + for (j = 0; j <= lc; j++) { + unsigned int good_cnt; + + /* reset count of good packets */ + good_cnt = 0; + + /* place 64 packets on the transmit queue*/ + for (i = 0; i < 64; i++) { + skb_get(skb); + tx_ret_val = ixgbe_xmit_frame_ring(skb, + adapter, + tx_ring); + if (tx_ret_val == NETDEV_TX_OK) + good_cnt++; + } + + if (good_cnt != 64) { + ret_val = 12; + break; + } + + /* allow 200 milliseconds for packets to go from Tx to Rx */ + msleep(200); + + good_cnt = ixgbe_clean_test_rings(rx_ring, tx_ring, size); + if (good_cnt != 64) { + ret_val = 13; + break; + } + } + + /* free the original skb */ + kfree_skb(skb); + adapter->flags = flags_orig; + + return ret_val; +} + +static int ixgbe_loopback_test(struct ixgbe_adapter *adapter, u64 *data) +{ + *data = ixgbe_setup_desc_rings(adapter); + if (*data) + goto out; + *data = ixgbe_setup_loopback_test(adapter); + if (*data) + goto err_loopback; + *data = ixgbe_run_loopback_test(adapter); + ixgbe_loopback_cleanup(adapter); + +err_loopback: + ixgbe_free_desc_rings(adapter); +out: + return *data; +} + +#ifndef HAVE_ETHTOOL_GET_SSET_COUNT +/** + * ixgbe_diag_test_count - Get the number of diagnostic tests available + * @netdev: Network device structure (unused) + * + * This function returns the number of diagnostic tests available for the + * network device. The `netdev` parameter is marked as unused, indicating that + * it is not utilized within the function. The function simply returns a + * constant value, `IXGBE_TEST_LEN`, which represents the number of diagnostic + * tests that can be performed on the device. + * + * Return: The number of diagnostic tests available, as defined by + * `IXGBE_TEST_LEN`. + */ +static int ixgbe_diag_test_count(struct net_device __always_unused *netdev) +{ + return IXGBE_TEST_LEN; +} +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + +/** + * ixgbe_diag_test - Perform diagnostic tests on the network device + * @netdev: Network device structure + * @eth_test: Ethtool test structure containing test flags + * @data: Array to store the results of the diagnostic tests + * + * This function performs a series of diagnostic tests on the specified network + * device. It supports both offline and online tests, depending on the flags set + * in the `eth_test` structure. The function checks if the device is in a + * removable state and blocks the test if the adapter is removed. + * + * For offline tests, the function performs the following diagnostics: + * - Link test + * - Register test + * - EEPROM test + * - Interrupt test + * - MAC loopback test (skipped if SR-IOV or VMDq is enabled) + * + * The function handles the device state appropriately, closing and resetting + * the device as needed during offline tests. It also ensures that the device + * returns to its previous state after testing. + * + * For online tests, only the link test is performed, and other tests are + * skipped with default pass results. + * + * The results of each test are stored in the `data` array, and the function + * sets the `ETH_TEST_FL_FAILED` flag in `eth_test` if any test fails. + */ +static void ixgbe_diag_test(struct net_device *netdev, + struct ethtool_test *eth_test, u64 *data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool if_running = netif_running(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (IXGBE_REMOVED(hw->hw_addr)) { + e_err(hw, "Adapter removed - test blocked\n"); + data[0] = 1; + data[1] = 1; + data[2] = 1; + data[3] = 1; + data[4] = 1; + eth_test->flags |= ETH_TEST_FL_FAILED; + return; + } + set_bit(__IXGBE_TESTING, adapter->state); + if (eth_test->flags == ETH_TEST_FL_OFFLINE) { + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + int i; + for (i = 0; i < adapter->num_vfs; i++) { + if (adapter->vfinfo[i].clear_to_send) { + e_warn(drv, "Please take active VFS " + "offline and restart the " + "adapter before running NIC " + "diagnostics\n"); + data[0] = 1; + data[1] = 1; + data[2] = 1; + data[3] = 1; + data[4] = 1; + eth_test->flags |= ETH_TEST_FL_FAILED; + clear_bit(__IXGBE_TESTING, + adapter->state); + goto skip_ol_tests; + } + } + } + + /* Offline tests */ + e_info(hw, "offline testing starting\n"); + + /* Link test performed before hardware reset so autoneg doesn't + * interfere with test result */ + if (ixgbe_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + if (if_running) + /* indicate we're in test mode */ + ixgbe_close(netdev); + else + ixgbe_reset(adapter); + + e_info(hw, "register testing starting\n"); + if (ixgbe_reg_test(adapter, &data[0])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + ixgbe_reset(adapter); + e_info(hw, "eeprom testing starting\n"); + if (ixgbe_eeprom_test(adapter, &data[1])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + ixgbe_reset(adapter); + e_info(hw, "interrupt testing starting\n"); + if (ixgbe_intr_test(adapter, &data[2])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + /* If SRIOV or VMDq is enabled then skip MAC + * loopback diagnostic. */ + if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED | + IXGBE_FLAG_VMDQ_ENABLED)) { + e_info(hw, "skip MAC loopback diagnostic in VT mode\n"); + data[3] = 0; + goto skip_loopback; + } + + ixgbe_reset(adapter); + e_info(hw, "loopback testing starting\n"); + if (ixgbe_loopback_test(adapter, &data[3])) + eth_test->flags |= ETH_TEST_FL_FAILED; + +skip_loopback: + ixgbe_reset(adapter); + + /* clear testing bit and return adapter to previous state */ + clear_bit(__IXGBE_TESTING, adapter->state); + if (if_running) + ixgbe_open(netdev); + else if (hw->mac.ops.disable_tx_laser) + hw->mac.ops.disable_tx_laser(hw); + } else { + e_info(hw, "online testing starting\n"); + + /* Online tests */ + if (ixgbe_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; + + /* Offline tests aren't run; pass by default */ + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + + clear_bit(__IXGBE_TESTING, adapter->state); + } + +skip_ol_tests: + msleep_interruptible(4 * 1000); +} + +static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, + struct ethtool_wolinfo *wol) +{ + struct ixgbe_hw *hw = &adapter->hw; + int retval = 0; + + /* WOL not supported for all devices */ + if (!ixgbe_wol_supported(adapter, hw->device_id, + hw->subsystem_device_id)) { + retval = 1; + wol->supported = 0; + } + + return retval; +} + +/** + * ixgbe_get_wol - Retrieve Wake-on-LAN settings for the network device + * @netdev: Network device structure + * @wol: Pointer to ethtool_wolinfo structure to be filled with WoL settings + * + * This function populates the `ethtool_wolinfo` structure with the supported + * and enabled Wake-on-LAN (WoL) options for the specified network device. It + * checks for WoL exclusions and device wakeup capability before setting the + * enabled options. + */ +static void ixgbe_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + wol->supported = WAKE_UCAST | WAKE_MCAST | + WAKE_BCAST | WAKE_MAGIC; + wol->wolopts = 0; + + if (ixgbe_wol_exclusion(adapter, wol) || + !device_can_wakeup(ixgbe_pf_to_dev(adapter))) + return; + + if (adapter->wol & IXGBE_WUFC_EX) + wol->wolopts |= WAKE_UCAST; + if (adapter->wol & IXGBE_WUFC_MC) + wol->wolopts |= WAKE_MCAST; + if (adapter->wol & IXGBE_WUFC_BC) + wol->wolopts |= WAKE_BCAST; + if (adapter->wol & IXGBE_WUFC_MAG) + wol->wolopts |= WAKE_MAGIC; +} + +/** + * ixgbe_set_wol - Set Wake-on-LAN settings for the network device + * @netdev: Network device structure + * @wol: Pointer to ethtool_wolinfo structure containing desired WoL settings + * + * This function sets the Wake-on-LAN (WoL) options for the specified network + * device based on the provided `ethtool_wolinfo` structure. It checks for + * unsupported WoL options and exclusions before updating the device's WoL + * configuration and enabling or disabling device wakeup. + * + * Return: 0 on success, or -EOPNOTSUPP if unsupported options are specified. + */ +static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE | + WAKE_FILTER)) + return -EOPNOTSUPP; + + if (ixgbe_wol_exclusion(adapter, wol)) + return wol->wolopts ? -EOPNOTSUPP : 0; + + adapter->wol = 0; + + if (wol->wolopts & WAKE_UCAST) + adapter->wol |= IXGBE_WUFC_EX; + if (wol->wolopts & WAKE_MCAST) + adapter->wol |= IXGBE_WUFC_MC; + if (wol->wolopts & WAKE_BCAST) + adapter->wol |= IXGBE_WUFC_BC; + if (wol->wolopts & WAKE_MAGIC) + adapter->wol |= IXGBE_WUFC_MAG; + + hw->wol_enabled = !!(adapter->wol); + + device_set_wakeup_enable(ixgbe_pf_to_dev(adapter), adapter->wol); + + return 0; +} + +/** + * ixgbe_set_wol_acpi - Set ACPI Wake-on-LAN settings for the network device + * @netdev: Network device structure + * @wol: Pointer to ethtool_wolinfo structure containing desired WoL settings + * + * This function configures the ACPI Wake-on-LAN (WoL) options for the specified + * network device based on the provided `ethtool_wolinfo` structure. It disables + * APM wakeup, updates the device's WoL configuration, and enables or disables + * device wakeup. Unsupported WoL options and exclusions are checked before + * applying the settings. + * + * Return: 0 on success, or -EOPNOTSUPP if unsupported options are specified. + */ +static int ixgbe_set_wol_acpi(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u32 grc; + + if (ixgbe_wol_exclusion(adapter, wol)) + return wol->wolopts ? -EOPNOTSUPP : 0; + + /* disable APM wakeup */ + grc = IXGBE_READ_REG(hw, IXGBE_GRC_X550EM_a); + grc &= ~IXGBE_GRC_APME; + IXGBE_WRITE_REG(hw, IXGBE_GRC_X550EM_a, grc); + + IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); + + adapter->wol = 0; + if (wol->wolopts & WAKE_UCAST) + adapter->wol |= IXGBE_WUFC_EX; + if (wol->wolopts & WAKE_MCAST) + adapter->wol |= IXGBE_WUFC_MC; + if (wol->wolopts & WAKE_BCAST) + adapter->wol |= IXGBE_WUFC_BC; + + IXGBE_WRITE_REG(hw, IXGBE_WUC, IXGBE_WUC_PME_EN); + IXGBE_WRITE_REG(hw, IXGBE_WUFC, adapter->wol); + + hw->wol_enabled = !!(adapter->wol); + + device_set_wakeup_enable(ixgbe_pf_to_dev(adapter), adapter->wol); + + return 0; +} + +/** + * ixgbe_set_wol_E610 - Set Wake-on-LAN settings for E610 hardware + * @netdev: Network device structure + * @wol: Pointer to ethtool_wolinfo structure containing desired WoL settings + * + * This function sets the Wake-on-LAN (WoL) options for E610 hardware. It + * delegates to `ixgbe_set_wol_acpi` if unicast, multicast, or broadcast WoL + * options are specified, otherwise it uses `ixgbe_set_wol`. + * + * Return: 0 on success, or a negative error code if unsupported options are specified. + */ +static int ixgbe_set_wol_E610(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + if (wol->wolopts & (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)) + return ixgbe_set_wol_acpi(netdev, wol); + else + return ixgbe_set_wol(netdev, wol); +} + +/** + * ixgbe_nway_reset - Perform a N-Way reset on the network device + * @netdev: Network device structure + * + * This function performs a N-Way reset on the specified network device. If the + * network interface is running, it reinitializes the adapter to apply the reset. + * + * Return: 0 on success. + */ +static int ixgbe_nway_reset(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + + return 0; +} + +#ifdef HAVE_ETHTOOL_SET_PHYS_ID +/** + * ixgbe_set_phys_id_E610 - Control the physical identification LED for E610 hardware + * @netdev: Network device structure + * @state: Desired state for the LED (active or inactive) + * + * This function controls the physical identification LED for E610 hardware + * based on the specified state. It turns the LED on or off to help identify + * the physical location of the network device. + * + * Return: 0 on success, -EIO if an error occurs, or -EOPNOTSUPP if the state is unsupported. + */ +static int ixgbe_set_phys_id_E610(struct net_device *netdev, + enum ethtool_phys_id_state state) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + bool led_active; + int err; + + switch (state) { + case ETHTOOL_ID_ACTIVE: + led_active = true; + break; + case ETHTOOL_ID_INACTIVE: + led_active = false; + break; + default: + return -EOPNOTSUPP; + } + + err = ixgbe_aci_set_port_id_led(&adapter->hw, !led_active); + if (err) + err = -EIO; + + return err; +} + +/** + * ixgbe_set_phys_id - Control the physical identification LED for the network device + * @netdev: Network device structure + * @state: Desired state for the LED (active, on, off, or inactive) + * + * This function controls the physical identification LED for the network device + * based on the specified state. It can turn the LED on or off, activate it for + * identification, or restore its previous settings. + * + * Return: 0 on success, 2 if the LED is activated for identification, -EINVAL if + * an error occurs, or -EOPNOTSUPP if LED operations are not supported. + */ +static int ixgbe_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (!hw->mac.ops.led_on || !hw->mac.ops.led_off) + return -EOPNOTSUPP; + + switch (state) { + case ETHTOOL_ID_ACTIVE: + adapter->led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + return 2; + + case ETHTOOL_ID_ON: + if (hw->mac.ops.led_on(hw, hw->mac.led_link_act)) + return -EINVAL; + break; + + case ETHTOOL_ID_OFF: + if (hw->mac.ops.led_off(hw, hw->mac.led_link_act)) + return -EINVAL; + break; + + case ETHTOOL_ID_INACTIVE: + /* Restore LED settings */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, adapter->led_reg); + break; + } + + return 0; +} +#else +/** + * ixgbe_phys_id - Identify the physical location of the network device + * @netdev: Network device structure + * @data: Duration in seconds to blink the LED for identification + * + * This function blinks the LED on the network device to help identify its + * physical location. It uses the device's LED on and off operations to blink + * the LED for the specified duration. If the duration is not specified or + * exceeds 300 seconds, it defaults to 300 seconds. The function restores the + * original LED settings after blinking. + * + * Return: 0 on success, or a negative error code if LED operations are not supported. + */ +static int ixgbe_phys_id(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + u32 i; + + if (!hw->mac.ops.led_on || !hw->mac.ops.led_off) + return -EOPNOTSUPP; + + if (!data || data > 300) + data = 300; + + for (i = 0; i < (data * 1000); i += 400) { + if (hw->mac.ops.led_on(hw, hw->mac.led_link_act)) + return -EINVAL; + msleep_interruptible(200); + if (hw->mac.ops.led_off(hw, hw->mac.led_link_act)) + return -EINVAL; + msleep_interruptible(200); + } + + /* Restore LED settings */ + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + + return IXGBE_SUCCESS; +} +#endif /* HAVE_ETHTOOL_SET_PHYS_ID */ + +/** + * ixgbe_get_coalesce - Retrieve interrupt coalescing settings for the network device + * @netdev: Network device structure + * @ec: Pointer to the ethtool_coalesce structure to be filled with coalescing info + * @kernel_coal: (Optional) Pointer to kernel-specific coalescing settings (unused) + * @extack: (Optional) Pointer to netlink extended acknowledgment structure (unused) + * + * This function retrieves the interrupt coalescing settings for the specified + * network device and populates the provided `ethtool_coalesce` structure with + * the relevant information. It reports the maximum number of coalesced frames + * for transmit interrupts and the coalescing time for receive and transmit + * interrupts based on the device's configuration. + * + * Return: 0 on success. + */ +static int ixgbe_get_coalesce(struct net_device *netdev, +#ifdef HAVE_ETHTOOL_COALESCE_EXTACK + struct ethtool_coalesce *ec, + struct kernel_ethtool_coalesce *kernel_coal, + struct netlink_ext_ack *extack) +#else + struct ethtool_coalesce *ec) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + ec->tx_max_coalesced_frames_irq = adapter->tx_work_limit; + /* only valid if in constant ITR mode */ + if (adapter->rx_itr_setting <= 1) + ec->rx_coalesce_usecs = adapter->rx_itr_setting; + else + ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; + + /* if in mixed tx/rx queues per vector mode, report only rx settings */ + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) + return 0; + + /* only valid if in constant ITR mode */ + if (adapter->tx_itr_setting <= 1) + ec->tx_coalesce_usecs = adapter->tx_itr_setting; + else + ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; + + return 0; +} + +/* + * this function must be called before setting the new value of + * rx_itr_setting + */ +static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + /* nothing to do if LRO or RSC are not enabled */ + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) || + !(netdev->features & NETIF_F_LRO)) + return false; + + /* check the feature flag value and enable RSC if necessary */ + if (adapter->rx_itr_setting == 1 || + adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR) { + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + e_info(probe, "rx-usecs value high enough " + "to re-enable RSC\n"); + return true; + } + /* if interrupt rate is too high then disable RSC */ + } else if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + e_info(probe, "rx-usecs set too low, disabling RSC\n"); + return true; + } + return false; +} + +/** + * ixgbe_set_coalesce - Configure interrupt coalescing settings + * @netdev: Network device structure + * @ec: Pointer to ethtool_coalesce structure with desired coalescing settings + * @kernel_coal: (Optional) Kernel-specific coalescing settings (unused) + * @extack: (Optional) Netlink extended acknowledgment structure (unused) + * + * This function sets the interrupt coalescing parameters for the specified + * network device based on the provided `ethtool_coalesce` structure. It + * validates the settings, updates the adapter's configuration, and applies + * changes to the interrupt throttle rate (ITR) settings. If necessary, it + * triggers a device reset to apply the changes. + * + * Return: 0 on success, or -EINVAL if the configuration is invalid. + */ +static int ixgbe_set_coalesce(struct net_device *netdev, +#ifdef HAVE_ETHTOOL_COALESCE_EXTACK + struct ethtool_coalesce *ec, + struct kernel_ethtool_coalesce *kernel_coal, + struct netlink_ext_ack *extack) +#else + struct ethtool_coalesce *ec) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i; + u16 tx_itr_param, rx_itr_param; + u16 tx_itr_prev; + bool need_reset = false; + + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) { + /* reject Tx specific changes in case of mixed RxTx vectors */ + if (ec->tx_coalesce_usecs) + return -EINVAL; + tx_itr_prev = adapter->rx_itr_setting; + } else { + tx_itr_prev = adapter->tx_itr_setting; + } + + if (ec->tx_max_coalesced_frames_irq) + adapter->tx_work_limit = ec->tx_max_coalesced_frames_irq; + + if ((ec->rx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)) || + (ec->tx_coalesce_usecs > (IXGBE_MAX_EITR >> 2))) + return -EINVAL; + + if (ec->rx_coalesce_usecs > 1) + adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2; + else + adapter->rx_itr_setting = ec->rx_coalesce_usecs; + + if (adapter->rx_itr_setting == 1) + rx_itr_param = IXGBE_20K_ITR; + else + rx_itr_param = adapter->rx_itr_setting; + + if (ec->tx_coalesce_usecs > 1) + adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2; + else + adapter->tx_itr_setting = ec->tx_coalesce_usecs; + + if (adapter->tx_itr_setting == 1) + tx_itr_param = IXGBE_12K_ITR; + else + tx_itr_param = adapter->tx_itr_setting; + + /* mixed Rx/Tx */ + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) + adapter->tx_itr_setting = adapter->rx_itr_setting; + + /* detect ITR changes that require update of TXDCTL.WTHRESH */ + if ((adapter->tx_itr_setting != 1) && + (adapter->tx_itr_setting < IXGBE_100K_ITR)) { + if ((tx_itr_prev == 1) || + (tx_itr_prev >= IXGBE_100K_ITR)) + need_reset = true; + } else { + if ((tx_itr_prev != 1) && + (tx_itr_prev < IXGBE_100K_ITR)) + need_reset = true; + } + + /* check the old value and enable RSC if necessary */ + need_reset |= ixgbe_update_rsc(adapter); + + if (adapter->hw.mac.dmac_config.watchdog_timer && + (!adapter->rx_itr_setting && !adapter->tx_itr_setting)) { + e_info(probe, + "Disabling DMA coalescing because interrupt throttling is disabled\n"); + adapter->hw.mac.dmac_config.watchdog_timer = 0; + ixgbe_dmac_config(&adapter->hw); + } + + for (i = 0; i < adapter->num_q_vectors; i++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; + + q_vector->tx.work_limit = adapter->tx_work_limit; + if (q_vector->tx.count && !q_vector->rx.count) + /* tx only */ + q_vector->itr = tx_itr_param; + else + /* rx only or mixed */ + q_vector->itr = rx_itr_param; + ixgbe_write_eitr(q_vector); + } + + /* + * do reset here at the end to make sure EITR==0 case is handled + * correctly w.r.t stopping tx, and changing TXDCTL.WTHRESH settings + * also locks in RSC enable/disable which requires reset + */ + if (need_reset) + ixgbe_do_reset(netdev); + + return 0; +} + +#ifndef HAVE_NDO_SET_FEATURES +/** + * ixgbe_get_rx_csum - Check if RX checksum offload is enabled + * @netdev: Network device structure + * + * This function returns a boolean value indicating whether receive checksum + * offload is enabled for the specified network device. + * + * Return: 1 if RX checksum offload is enabled, 0 otherwise. + */ +static u32 ixgbe_get_rx_csum(struct net_device *netdev) +{ + return !!(netdev->features & NETIF_F_RXCSUM); +} + +/** + * ixgbe_set_rx_csum - Enable or disable RX checksum offload + * @netdev: Network device structure + * @data: Boolean value to enable (non-zero) or disable (zero) RX checksum offload + * + * This function sets the receive checksum offload feature for the specified + * network device. It also adjusts related features such as LRO (Large Receive + * Offload) and RSC (Receive Side Coalescing) based on the RX checksum setting. + * If necessary, it triggers a device reset to apply changes. + * + * Return: 0 on success. + */ +static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool need_reset = false; + + if (data) + netdev->features |= NETIF_F_RXCSUM; + else + netdev->features &= ~NETIF_F_RXCSUM; + + /* LRO and RSC both depend on RX checksum to function */ + if (!data && (netdev->features & NETIF_F_LRO)) { + netdev->features &= ~NETIF_F_LRO; + + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + need_reset = true; + } + } + +#ifdef HAVE_VXLAN_RX_OFFLOAD + if (adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE && data) { + netdev->hw_enc_features |= NETIF_F_RXCSUM | + NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM; + if (!need_reset) + adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED; + } else { + netdev->hw_enc_features &= ~(NETIF_F_RXCSUM | + NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM); + ixgbe_clear_udp_tunnel_port(adapter, + IXGBE_VXLANCTRL_ALL_UDPPORT_MASK); + } +#endif /* HAVE_VXLAN_RX_OFFLOAD */ + + if (need_reset) + ixgbe_do_reset(netdev); + + return 0; +} + +/** + * ixgbe_set_tx_csum - Enable or disable TX checksum offload + * @netdev: Network device structure + * @data: Boolean value to enable (non-zero) or disable (zero) TX checksum offload + * + * This function sets the transmit checksum offload feature for the specified + * network device. It updates the device's features to enable or disable checksum + * offload for IP, IPv6, SCTP, and UDP tunnels, depending on the hardware type + * and capabilities. + * + * Return: 0 on success. + */ +static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#ifdef NETIF_F_IPV6_CSUM + u32 feature_list = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; +#else + u32 feature_list = NETIF_F_IP_CSUM; +#endif + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: +#ifdef HAVE_ENCAP_TSO_OFFLOAD + if (data) + netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL; + else + netdev->hw_enc_features &= ~NETIF_F_GSO_UDP_TUNNEL; + feature_list |= NETIF_F_GSO_UDP_TUNNEL; +#endif /* HAVE_ENCAP_TSO_OFFLOAD */ + feature_list |= NETIF_F_SCTP_CSUM; + break; + default: + break; + } + + if (data) + netdev->features |= feature_list; + else + netdev->features &= ~feature_list; + + return 0; +} + +#ifdef NETIF_F_TSO +/** + * ixgbe_set_tso - Enable or disable TCP Segmentation Offload (TSO) + * @netdev: Network device structure + * @data: Boolean value to enable (non-zero) or disable (zero) TSO + * + * This function sets the TCP Segmentation Offload (TSO) feature for the + * specified network device. It updates the device's features to enable or + * disable TSO, and if VLANs are present and TSO is being disabled, it also + * disables TSO on all associated VLAN devices. + * + * Return: 0 on success. + */ +static int ixgbe_set_tso(struct net_device *netdev, u32 data) +{ +#ifdef NETIF_F_TSO6 + u32 feature_list = NETIF_F_TSO | NETIF_F_TSO6; +#else + u32 feature_list = NETIF_F_TSO; +#endif + + if (data) + netdev->features |= feature_list; + else + netdev->features &= ~feature_list; + +#ifndef HAVE_NETDEV_VLAN_FEATURES + if (!data) { + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct net_device *v_netdev; + int i; + + /* disable TSO on all VLANs if they're present */ + if (!adapter->vlgrp) + goto tso_out; + + for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + v_netdev = vlan_group_get_device(adapter->vlgrp, i); + if (!v_netdev) + continue; + + v_netdev->features &= ~feature_list; + vlan_group_set_device(adapter->vlgrp, i, v_netdev); + } + } + +tso_out: + +#endif /* HAVE_NETDEV_VLAN_FEATURES */ + return 0; +} +#endif /* NETIF_F_TSO */ + +#ifdef ETHTOOL_GFLAGS +/** + * ixgbe_set_flags - Set device flags for the network device + * @netdev: Network device structure + * @data: New flags to be set + * + * This function sets various device flags for the specified network device + * based on the provided `data`. It validates the flags against supported + * options and updates the device's configuration accordingly. If necessary, + * it triggers a device reset to apply changes. + * + * Return: 0 on success, or a negative error code if the configuration is invalid. + */ +static int ixgbe_set_flags(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u32 supported_flags = ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN; + u32 changed = netdev->features ^ data; + bool need_reset = false; + int rc; + +#ifndef HAVE_VLAN_RX_REGISTER + if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && + !(data & ETH_FLAG_RXVLAN)) + return -EINVAL; + +#endif + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + supported_flags |= ETH_FLAG_LRO; + +#ifdef ETHTOOL_GRXRINGS + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + supported_flags |= ETH_FLAG_NTUPLE; + default: + break; + } + +#endif +#ifdef NETIF_F_RXHASH + supported_flags |= ETH_FLAG_RXHASH; + +#endif + rc = ethtool_op_set_flags(netdev, data, supported_flags); + if (rc) + return rc; + +#ifndef HAVE_VLAN_RX_REGISTER + if (changed & ETH_FLAG_RXVLAN) + ixgbe_vlan_mode(netdev, netdev->features); +#endif + +#ifdef HAVE_VXLAN_RX_OFFLOAD + if (adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE && + netdev->features & NETIF_F_RXCSUM) { + vxlan_get_rx_port(netdev); + else + ixgbe_clear_udp_tunnel_port(adapter, + IXGBE_VXLANCTRL_ALL_UDPPORT_MASK); + } +#endif /* HAVE_VXLAN_RX_OFFLOAD */ + + /* if state changes we need to update adapter->flags and reset */ + if (!(netdev->features & NETIF_F_LRO)) { + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + need_reset = true; + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + } else if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && + !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { + if (adapter->rx_itr_setting == 1 || + adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR) { + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + need_reset = true; + } else if (changed & ETH_FLAG_LRO) { + e_info(probe, "rx-usecs set too low, " + "disabling RSC\n"); + } + } + +#ifdef ETHTOOL_GRXRINGS + /* + * Check if Flow Director n-tuple support was enabled or disabled. If + * the state changed, we need to reset. + */ + switch (netdev->features & NETIF_F_NTUPLE) { + case NETIF_F_NTUPLE: + /* turn off ATR, enable perfect filters and reset */ + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + need_reset = true; + + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + break; + default: + /* turn off perfect filters, enable ATR and reset */ + if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) + need_reset = true; + + adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + + /* We cannot enable ATR if VMDq is enabled */ + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) + break; + + /* We cannot enable ATR if we have 2 or more traffic classes */ + if (netdev_get_num_tc(netdev) > 1) + break; + + /* We cannot enable ATR if RSS is disabled */ + if (adapter->ring_feature[RING_F_RSS].limit <= 1) + break; + + /* A sample rate of 0 indicates ATR disabled */ + if (!adapter->atr_sample_rate) + break; + + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + break; + } + +#endif /* ETHTOOL_GRXRINGS */ + if (need_reset) + ixgbe_do_reset(netdev); + + return 0; +} + +#endif /* ETHTOOL_GFLAGS */ +#endif /* HAVE_NDO_SET_FEATURES */ +#ifdef ETHTOOL_GRXRINGS +static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fsp = + (struct ethtool_rx_flow_spec *)&cmd->fs; + struct ixgbe_fdir_filter *rule = NULL; + union ixgbe_atr_input *mask; + struct hlist_node *node2; + int ret; + + /* report total rule count */ + cmd->data = (1024 << adapter->fdir_pballoc) - 2; + + spin_lock(&adapter->fdir_perfect_lock); + + hlist_for_each_entry_safe(rule, node2, + &adapter->fdir_filter_list, fdir_node) { + if (fsp->location <= rule->sw_idx) + break; + } + + if (!rule || fsp->location != rule->sw_idx) { + ret = -EINVAL; + goto err_out; + } + + /* fill out the flow spec entry */ + + /* set flow type field */ + switch (rule->filter.formatted.flow_type) { + case IXGBE_ATR_FLOW_TYPE_TCPV4: + fsp->flow_type = TCP_V4_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_UDPV4: + fsp->flow_type = UDP_V4_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_TCPV6: + fsp->flow_type = TCP_V6_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_UDPV6: + fsp->flow_type = UDP_V6_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_SCTPV4: + fsp->flow_type = SCTP_V4_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_IPV4: + fsp->flow_type = IP_USER_FLOW; + fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4; + fsp->h_u.usr_ip4_spec.proto = 0; + fsp->m_u.usr_ip4_spec.proto = 0; + break; + default: + ret = -EINVAL; + goto err_out; + } + + mask = &adapter->fdir_mask; +#ifdef HAVE_ETHTOOL_FLOW_UNION_IP6_SPEC + if (rule->filter.formatted.flow_type & IXGBE_ATR_L4TYPE_IPV6_MASK) { + fsp->h_u.tcp_ip6_spec.psrc = rule->filter.formatted.src_port; + fsp->m_u.tcp_ip6_spec.psrc = mask->formatted.src_port; + fsp->h_u.tcp_ip6_spec.pdst = rule->filter.formatted.dst_port; + fsp->m_u.tcp_ip6_spec.pdst = mask->formatted.dst_port; + } else { +#endif + fsp->h_u.tcp_ip4_spec.psrc = rule->filter.formatted.src_port; + fsp->m_u.tcp_ip4_spec.psrc = mask->formatted.src_port; + fsp->h_u.tcp_ip4_spec.pdst = rule->filter.formatted.dst_port; + fsp->m_u.tcp_ip4_spec.pdst = mask->formatted.dst_port; + fsp->h_u.tcp_ip4_spec.ip4src = rule->filter.formatted.src_ip[0]; + fsp->m_u.tcp_ip4_spec.ip4src = mask->formatted.src_ip[0]; + fsp->h_u.tcp_ip4_spec.ip4dst = rule->filter.formatted.dst_ip[0]; + fsp->m_u.tcp_ip4_spec.ip4dst = mask->formatted.dst_ip[0]; +#ifdef HAVE_ETHTOOL_FLOW_UNION_IP6_SPEC + } +#endif + + fsp->h_ext.vlan_tci = rule->filter.formatted.vlan_id; + fsp->m_ext.vlan_tci = mask->formatted.vlan_id; + fsp->h_ext.vlan_etype = rule->filter.formatted.flex_bytes; + fsp->m_ext.vlan_etype = mask->formatted.flex_bytes; + fsp->h_ext.data[1] = htonl(rule->filter.formatted.vm_pool); + fsp->m_ext.data[1] = htonl(mask->formatted.vm_pool); + fsp->flow_type |= FLOW_EXT; + + /* record action */ + if (rule->action == IXGBE_FDIR_DROP_QUEUE) + fsp->ring_cookie = RX_CLS_FLOW_DISC; + else + fsp->ring_cookie = rule->action; + + spin_unlock(&adapter->fdir_perfect_lock); + return 0; + +err_out: + spin_unlock(&adapter->fdir_perfect_lock); + return ret; +} + +static int ixgbe_get_ethtool_fdir_all(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + struct hlist_node *node2; + struct ixgbe_fdir_filter *rule; + int cnt = 0; + + /* report total rule count */ + cmd->data = (1024 << adapter->fdir_pballoc) - 2; + + hlist_for_each_entry_safe(rule, node2, + &adapter->fdir_filter_list, fdir_node) { + if (cnt == cmd->rule_cnt) + return -EMSGSIZE; + rule_locs[cnt] = rule->sw_idx; + cnt++; + } + + cmd->rule_cnt = cnt; + + return 0; +} + +static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + cmd->data = 0; + + /* Report default options for RSS on ixgbe */ + switch (cmd->flow_type) { + case TCP_V4_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case UDP_V4_FLOW: + if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case IPV4_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case UDP_V6_FLOW: + if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IPV6_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * ixgbe_get_rxnfc - Retrieve RX network flow classification settings + * @dev: Network device structure + * @cmd: Pointer to ethtool_rxnfc structure specifying the command and data + * @rule_locs: Buffer to store rule locations (optional, type depends on kernel) + * + * This function handles various ethtool commands related to RX network flow + * classification for the specified network device. It supports commands to + * get the number of RX rings, flow director rule count, specific flow director + * rules, all flow director rules, and RSS hash options. + * + * Return: 0 on success, or a negative error code if the command is not supported. + */ +static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, +#ifdef HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS + void *rule_locs) +#else + u32 *rule_locs) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = adapter->num_rx_queues; + ret = 0; + break; + case ETHTOOL_GRXCLSRLCNT: + cmd->rule_cnt = adapter->fdir_filter_count; + ret = 0; + break; + case ETHTOOL_GRXCLSRULE: + ret = ixgbe_get_ethtool_fdir_entry(adapter, cmd); + break; + case ETHTOOL_GRXCLSRLALL: + ret = ixgbe_get_ethtool_fdir_all(adapter, cmd, + (u32 *)rule_locs); + break; + case ETHTOOL_GRXFH: + ret = ixgbe_get_rss_hash_opts(adapter, cmd); + break; + default: + break; + } + + return ret; +} + +int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ixgbe_fdir_filter *input, + u16 sw_idx) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct hlist_node *node2; + struct ixgbe_fdir_filter *rule, *parent; + bool deleted = false; + s32 err; + + parent = NULL; + rule = NULL; + + hlist_for_each_entry_safe(rule, node2, + &adapter->fdir_filter_list, fdir_node) { + /* hash found, or no matching entry */ + if (rule->sw_idx >= sw_idx) + break; + parent = rule; + } + + /* if there is an old rule occupying our place remove it */ + if (rule && (rule->sw_idx == sw_idx)) { + /* hardware filters are only configured when interface is up, + * and we should not issue filter commands while the interface + * is down + */ + if (netif_running(adapter->netdev) && + (!input || (rule->filter.formatted.bkt_hash != + input->filter.formatted.bkt_hash))) { + err = ixgbe_fdir_erase_perfect_filter_82599(hw, + &rule->filter, + sw_idx); + if (err) + return -EINVAL; + } + + hlist_del(&rule->fdir_node); + kfree(rule); + adapter->fdir_filter_count--; + deleted = true; + } + + /* If we weren't given an input, then this was a request to delete a + * filter. We should return -EINVAL if the filter wasn't found, but + * return 0 if the rule was successfully deleted. + */ + if (!input) + return deleted ? 0 : -EINVAL; + + /* initialize node and set software index */ + INIT_HLIST_NODE(&input->fdir_node); + + /* add filter to the list */ + if (parent) + hlist_add_behind(&input->fdir_node, &parent->fdir_node); + else + hlist_add_head(&input->fdir_node, + &adapter->fdir_filter_list); + + /* update counts */ + adapter->fdir_filter_count++; + + return 0; +} + +static int ixgbe_flowspec_to_flow_type(struct ethtool_rx_flow_spec *fsp, + u8 *flow_type) +{ + switch (fsp->flow_type & ~FLOW_EXT) { + case TCP_V4_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4; + break; + case UDP_V4_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4; + break; + case TCP_V6_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV6; + break; + case UDP_V6_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV6; + break; + case SCTP_V4_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4; + break; + case IP_USER_FLOW: + switch (fsp->h_u.usr_ip4_spec.proto) { + case IPPROTO_TCP: + *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4; + break; + case IPPROTO_UDP: + *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4; + break; + case IPPROTO_SCTP: + *flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4; + break; + case 0: + if (!fsp->m_u.usr_ip4_spec.proto) { + *flow_type = IXGBE_ATR_FLOW_TYPE_IPV4; + break; + } + fallthrough; + default: + return 0; + } + break; + default: + return 0; + } + + return 1; +} + +static bool ixgbe_match_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ixgbe_fdir_filter *input) +{ + struct hlist_node *node2; + struct ixgbe_fdir_filter *rule = NULL; + + hlist_for_each_entry_safe(rule, node2, + &adapter->fdir_filter_list, fdir_node) { + if (rule->filter.formatted.bkt_hash == + input->filter.formatted.bkt_hash && + rule->action == input->action) { + e_info(drv, "FDIR entry already exist\n"); + return true; + } + } + return false; +} + +static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fsp = + (struct ethtool_rx_flow_spec *)&cmd->fs; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_fdir_filter *input; + union ixgbe_atr_input mask; + u8 queue; + int err; + + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + return -EOPNOTSUPP; + + /* ring_cookie is a masked into a set of queues and ixgbe pools or + * we use drop index + */ + if (fsp->ring_cookie == RX_CLS_FLOW_DISC) { + queue = IXGBE_FDIR_DROP_QUEUE; + } else { + u32 ring = ethtool_get_flow_spec_ring(fsp->ring_cookie); + u8 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie); + + if (!vf && ring >= adapter->num_rx_queues) + return -EINVAL; + else if (vf && + ((vf > adapter->num_vfs) || + ring >= adapter->num_rx_queues_per_pool)) + return -EINVAL; + + /* Map the ring onto the absolute queue index */ + if (!vf) + queue = adapter->rx_ring[ring]->reg_idx; + else + queue = ((vf - 1) * + adapter->num_rx_queues_per_pool) + ring; + } + + /* Don't allow indexes to exist outside of available space */ + if (fsp->location >= ((1024 << adapter->fdir_pballoc) - 2)) { + e_err(drv, "Location out of range\n"); + return -EINVAL; + } + + input = kzalloc(sizeof(*input), GFP_ATOMIC); + if (!input) + return -ENOMEM; + + memset(&mask, 0, sizeof(union ixgbe_atr_input)); + + /* set SW index */ + input->sw_idx = fsp->location; + + spin_lock(&adapter->fdir_perfect_lock); + /* record flow type */ + if (!ixgbe_flowspec_to_flow_type(fsp, + &input->filter.formatted.flow_type)) { + e_err(drv, "Unrecognized flow type\n"); + goto err_out_w_lock; + } + + mask.formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK | + IXGBE_ATR_L4TYPE_MASK; + + if (input->filter.formatted.flow_type == IXGBE_ATR_FLOW_TYPE_IPV4) + mask.formatted.flow_type &= IXGBE_ATR_L4TYPE_IPV6_MASK; + +#ifdef HAVE_ETHTOOL_FLOW_UNION_IP6_SPEC + /* not support full IPV6 address filtering */ + if (input->filter.formatted.flow_type & IXGBE_ATR_L4TYPE_IPV6_MASK) { + if (fsp->m_u.tcp_ip6_spec.ip6src[0] || + fsp->m_u.tcp_ip6_spec.ip6src[1] || + fsp->m_u.tcp_ip6_spec.ip6src[2] || + fsp->m_u.tcp_ip6_spec.ip6src[3] || + fsp->m_u.tcp_ip6_spec.ip6dst[0] || + fsp->m_u.tcp_ip6_spec.ip6dst[1] || + fsp->m_u.tcp_ip6_spec.ip6dst[2] || + fsp->m_u.tcp_ip6_spec.ip6dst[3]) { + e_err(drv, "Error not support IPv6 address fitlers\n"); + goto err_out_w_lock; + } + input->filter.formatted.src_port = fsp->h_u.tcp_ip6_spec.psrc; + mask.formatted.src_port = fsp->m_u.tcp_ip6_spec.psrc; + input->filter.formatted.dst_port = fsp->h_u.tcp_ip6_spec.pdst; + mask.formatted.dst_port = fsp->m_u.tcp_ip6_spec.pdst; + } else { +#endif + /* Copy input into formatted structures */ + input->filter.formatted.src_ip[0] = + fsp->h_u.tcp_ip4_spec.ip4src; + mask.formatted.src_ip[0] = + fsp->m_u.tcp_ip4_spec.ip4src; + input->filter.formatted.dst_ip[0] = + fsp->h_u.tcp_ip4_spec.ip4dst; + mask.formatted.dst_ip[0] = + fsp->m_u.tcp_ip4_spec.ip4dst; + input->filter.formatted.src_port = + fsp->h_u.tcp_ip4_spec.psrc; + mask.formatted.src_port = + fsp->m_u.tcp_ip4_spec.psrc; + input->filter.formatted.dst_port = + fsp->h_u.tcp_ip4_spec.pdst; + mask.formatted.dst_port = + fsp->m_u.tcp_ip4_spec.pdst; +#ifdef HAVE_ETHTOOL_FLOW_UNION_IP6_SPEC + } +#endif + + if (fsp->flow_type & FLOW_EXT) { + input->filter.formatted.vm_pool = + (unsigned char)ntohl(fsp->h_ext.data[1]); + mask.formatted.vm_pool = + (unsigned char)ntohl(fsp->m_ext.data[1]); + input->filter.formatted.vlan_id = fsp->h_ext.vlan_tci; + mask.formatted.vlan_id = fsp->m_ext.vlan_tci; + input->filter.formatted.flex_bytes = + fsp->h_ext.vlan_etype; + mask.formatted.flex_bytes = fsp->m_ext.vlan_etype; + } + + /* determine if we need to drop or route the packet */ + if (fsp->ring_cookie == RX_CLS_FLOW_DISC) + input->action = IXGBE_FDIR_DROP_QUEUE; + else + input->action = fsp->ring_cookie; + + if (hlist_empty(&adapter->fdir_filter_list)) { + /* save mask and program input mask into HW */ + memcpy(&adapter->fdir_mask, &mask, sizeof(mask)); + err = ixgbe_fdir_set_input_mask_82599(hw, &mask, adapter->cloud_mode); + if (err) { + e_err(drv, "Error writing mask\n"); + goto err_out_w_lock; + } + } else if (memcmp(&adapter->fdir_mask, &mask, sizeof(mask))) { + e_err(drv, "Hardware only supports one mask per port. To change the mask you must first delete all the rules.\n"); + goto err_out_w_lock; + } + + /* apply mask and compute/store hash */ + ixgbe_atr_compute_perfect_hash_82599(&input->filter, &mask); + + /* check if new entry does not exist on filter list */ + if (ixgbe_match_ethtool_fdir_entry(adapter, input)) + goto err_out_w_lock; + + /* only program filters to hardware if the net device is running, as + * we store the filters in the Rx buffer which is not allocated when + * the device is down + */ + if (netif_running(adapter->netdev)) { + err = ixgbe_fdir_write_perfect_filter_82599(hw, + &input->filter, input->sw_idx, queue, + adapter->cloud_mode); + if (err) + goto err_out_w_lock; + } + + ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); + + spin_unlock(&adapter->fdir_perfect_lock); + + return 0; +err_out_w_lock: + spin_unlock(&adapter->fdir_perfect_lock); + kfree(input); + return -EINVAL; +} + +static int ixgbe_del_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fsp = + (struct ethtool_rx_flow_spec *)&cmd->fs; + int err; + + spin_lock(&adapter->fdir_perfect_lock); + err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, fsp->location); + spin_unlock(&adapter->fdir_perfect_lock); + + return err; +} + +#ifdef ETHTOOL_SRXNTUPLE +/** + * ixgbe_set_rx_ntuple - Stub function for setting RX n-tuple filters + * @dev: Network device structure (unused) + * @cmd: RX n-tuple command structure (unused) + * + * This function is a stub for setting RX n-tuple filters and always returns + * -EOPNOTSUPP. It is retained for compatibility with older kernel versions + * (2.6.33 - 2.6.39) to prevent null pointer dereferences when the + * NETIF_F_NTUPLE flag is defined. + * + * Return: -EOPNOTSUPP, indicating the operation is not supported. + */ +static int ixgbe_set_rx_ntuple(struct net_device __always_unused *dev, + struct ethtool_rx_ntuple __always_unused *cmd) +{ + return -EOPNOTSUPP; +} + +#endif +#define UDP_RSS_FLAGS (IXGBE_FLAG2_RSS_FIELD_IPV4_UDP | \ + IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) +static int ixgbe_set_rss_hash_opt(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *nfc) +{ + u32 flags2 = adapter->flags2; + + /* + * RSS does not support anything other than hashing + * to queues on src and dst IPs and ports + */ + if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3)) + return -EINVAL; + + switch (nfc->flow_type) { + case TCP_V4_FLOW: + case TCP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST) || + !(nfc->data & RXH_L4_B_0_1) || + !(nfc->data & RXH_L4_B_2_3)) + return -EINVAL; + break; + case UDP_V4_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + flags2 &= ~IXGBE_FLAG2_RSS_FIELD_IPV4_UDP; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + flags2 |= IXGBE_FLAG2_RSS_FIELD_IPV4_UDP; + break; + default: + return -EINVAL; + } + break; + case UDP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + flags2 &= ~IXGBE_FLAG2_RSS_FIELD_IPV6_UDP; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + flags2 |= IXGBE_FLAG2_RSS_FIELD_IPV6_UDP; + break; + default: + return -EINVAL; + } + break; + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case SCTP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST) || + (nfc->data & RXH_L4_B_0_1) || + (nfc->data & RXH_L4_B_2_3)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + /* if we changed something we need to update flags */ + if (flags2 != adapter->flags2) { + struct ixgbe_hw *hw = &adapter->hw; + u32 mrqc; + unsigned int pf_pool = adapter->num_vfs; + + if ((hw->mac.type >= ixgbe_mac_X550) && + (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + mrqc = IXGBE_READ_REG(hw, IXGBE_PFVFMRQC(pf_pool)); + else + mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC); + + if ((flags2 & UDP_RSS_FLAGS) && + !(adapter->flags2 & UDP_RSS_FLAGS)) + e_warn(drv, "enabling UDP RSS: fragmented packets" + " may arrive out of order to the stack above\n"); + + adapter->flags2 = flags2; + + /* Perform hash on these packet types */ + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4 + | IXGBE_MRQC_RSS_FIELD_IPV4_TCP + | IXGBE_MRQC_RSS_FIELD_IPV6 + | IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + + mrqc &= ~(IXGBE_MRQC_RSS_FIELD_IPV4_UDP | + IXGBE_MRQC_RSS_FIELD_IPV6_UDP); + + if (flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; + + if (flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; + + if ((hw->mac.type >= ixgbe_mac_X550) && + (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + IXGBE_WRITE_REG(hw, IXGBE_PFVFMRQC(pf_pool), mrqc); + else + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + } + + return 0; +} + +/** + * ixgbe_set_rxnfc - Configure RX network flow classification + * @dev: Network device structure + * @cmd: Pointer to ethtool_rxnfc structure specifying the command and data + * + * This function handles various ethtool commands related to RX network flow + * classification for the specified network device. It supports adding and + * deleting flow director entries and setting RSS hash options. + * + * Return: 0 on success, or -EOPNOTSUPP if the command is not supported. + */ +static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { + case ETHTOOL_SRXCLSRLINS: + ret = ixgbe_add_ethtool_fdir_entry(adapter, cmd); + break; + case ETHTOOL_SRXCLSRLDEL: + ret = ixgbe_del_ethtool_fdir_entry(adapter, cmd); + break; + case ETHTOOL_SRXFH: + ret = ixgbe_set_rss_hash_opt(adapter, cmd); + break; + default: + break; + } + + return ret; +} + +#if defined(ETHTOOL_GRSSH) && defined(ETHTOOL_SRSSH) +/** + * ixgbe_rss_indir_tbl_max - Get the maximum size of the RSS indirection table + * @adapter: Pointer to the ixgbe adapter structure + * + * This function returns the maximum size of the Receive Side Scaling (RSS) + * indirection table for the specified adapter. The size depends on the + * hardware type, with older models supporting up to 16 entries and newer + * models (X550 and above) supporting up to 64 entries. + * + * Return: The maximum number of entries in the RSS indirection table. + */ +static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.mac.type < ixgbe_mac_X550) + return 16; + else + return 64; +} + +/** + * ixgbe_get_rxfh_key_size - Get the size of the RX flow hash key + * @netdev: Network device structure + * + * This function returns the size of the receive flow hash key for the specified + * network device. The key size is defined by the constant `IXGBE_RSS_KEY_SIZE`. + * + * Return: The size of the RX flow hash key. + */ +static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev) +{ + return IXGBE_RSS_KEY_SIZE; +} + +/** + * ixgbe_rss_indir_size - Get the size of the RSS indirection table + * @netdev: Network device structure + * + * This function returns the size of the Receive Side Scaling (RSS) indirection + * table for the specified network device. The size is determined by the number + * of entries in the indirection table. + * + * Return: The size of the RSS indirection table. + */ +static u32 ixgbe_rss_indir_size(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + return ixgbe_rss_indir_tbl_entries(adapter); +} + +/** + * ixgbe_get_reta - Retrieve the RSS indirection table + * @adapter: Pointer to the ixgbe adapter structure + * @indir: Buffer to store the retrieved indirection table entries + * + * This function populates the provided buffer with the current entries of the + * Receive Side Scaling (RSS) indirection table for the specified adapter. It + * considers the RSS mask and adjusts for SR-IOV if enabled. + */ +static void ixgbe_get_reta(struct ixgbe_adapter *adapter, u32 *indir) +{ + int i, reta_size = ixgbe_rss_indir_tbl_entries(adapter); + u16 rss_m = adapter->ring_feature[RING_F_RSS].mask; + + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + rss_m = adapter->ring_feature[RING_F_RSS].indices - 1; + + for (i = 0; i < reta_size; i++) + indir[i] = adapter->rss_indir_tbl[i] & rss_m; +} + +/** + * ixgbe_get_rxfh - Retrieve RX flow hash configuration + * @netdev: Network device structure + * @rxfh: (Optional) Pointer to ethtool_rxfh_param structure for RX flow hash + * @indir: (Optional) Buffer to store the indirection table + * @key: (Optional) Buffer to store the RSS key + * @hfunc: (Optional) Buffer to store the hash function + * + * This function retrieves the RX flow hash configuration for the specified + * network device. It populates the indirection table, RSS key, and hash + * function based on the device's current settings. The function supports + * different parameter configurations based on kernel capabilities. + * + * Return: 0 on success. + */ +#ifdef HAVE_RXFH_HASHFUNC +#ifdef HAVE_ETHTOOL_RXFH_PARAM +static int ixgbe_get_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh) +#else +static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 *hfunc) +#endif /* HAVE_ETHTOOL_RXFH_PARAM */ +#else +static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#ifdef HAVE_ETHTOOL_RXFH_PARAM + u32 *indir = rxfh->indir; + u8 *key = rxfh->key; +#endif /* HAVE_ETHTOOL_RXFH_PARAM */ + +#ifdef HAVE_RXFH_HASHFUNC +#ifdef HAVE_ETHTOOL_RXFH_PARAM + rxfh->hfunc = ETH_RSS_HASH_TOP; +#else + if (hfunc) + *hfunc = ETH_RSS_HASH_TOP; +#endif /* HAVE_ETHTOOL_RXFH_PARAM */ +#endif + + if (indir) + ixgbe_get_reta(adapter, indir); + + if (key) + memcpy(key, adapter->rss_key, ixgbe_get_rxfh_key_size(netdev)); + + return 0; +} + +#ifdef HAVE_RXFH_HASHFUNC +#ifdef HAVE_ETHTOOL_RXFH_PARAM +/** + * ixgbe_set_rxfh - Set RX flow hash configuration + * @netdev: Network device structure + * @rxfh: (Optional) Pointer to ethtool_rxfh_param structure for RX flow hash + * @extack: (Optional) Netlink extended acknowledgment structure (unused) + * @indir: (Optional) Indirection table + * @key: (Optional) RSS key + * @hfunc: (Optional) Hash function (unused) + * + * This function sets the RX flow hash configuration for the specified network + * device. It updates the indirection table and RSS key based on the provided + * parameters. The function supports different parameter configurations based + * on kernel capabilities. + * + * Return: 0 on success, or -EINVAL if the configuration is invalid. + */ +static int ixgbe_set_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +#else +static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *key, const u8 hfunc) +#endif /* HAVE_ETHTOOL_RXFH_PARAM */ +#else +#ifdef HAVE_RXFH_NONCONST +static int ixgbe_set_rxfh(struct net_device *netdev, u32 *indir, u8 *key) +#else +static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *key) +#endif /* HAVE_RXFH_NONCONST */ +#endif /* HAVE_RXFH_HASHFUNC */ +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#ifdef HAVE_ETHTOOL_RXFH_PARAM + u32 *indir = rxfh->indir; + u8 *key = rxfh->key; +#endif /* HAVE_ETHTOOL_RXFH_PARAM */ + int i; + u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter); + +#ifdef HAVE_RXFH_HASHFUNC +#ifndef HAVE_ETHTOOL_RXFH_PARAM + if (hfunc) + return -EINVAL; +#endif /* !HAVE_ETHTOOL_RXFH_PARAM */ +#endif + + /* Fill out the redirection table */ + if (indir) { + int max_queues = min_t(int, adapter->num_rx_queues, + ixgbe_rss_indir_tbl_max(adapter)); + + /*Allow at least 2 queues w/ SR-IOV.*/ + if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && + (max_queues < 2)) + max_queues = 2; + + /* Verify user input. */ + for (i = 0; i < reta_entries; i++) + if (indir[i] >= max_queues) + return -EINVAL; + + for (i = 0; i < reta_entries; i++) + adapter->rss_indir_tbl[i] = indir[i]; + + ixgbe_store_reta(adapter); + } + + /* Fill out the rss hash key */ + if (key) { + memcpy(adapter->rss_key, key, ixgbe_get_rxfh_key_size(netdev)); + ixgbe_store_key(adapter); + } + + return 0; +} +#endif /* ETHTOOL_GRSSH && ETHTOOL_SRSSH */ + +/** + * ixgbe_get_ts_info - Retrieve timestamping capabilities for the network device + * @dev: Network device structure + * @info: Pointer to ethtool_ts_info or kernel_ethtool_ts_info structure + * + * This function populates the provided structure with the timestamping + * capabilities of the network device. It sets the supported receive filters, + * timestamping modes, and PTP hardware clock index based on the device's + * hardware type and capabilities. + * + * Return: 0 on success, or a negative error code if the operation is not supported. + */ +#ifdef HAVE_ETHTOOL_GET_TS_INFO +#ifdef HAVE_ETHTOOL_KERNEL_TS_INFO +static int ixgbe_get_ts_info(struct net_device *dev, + struct kernel_ethtool_ts_info *info) +#else +static int ixgbe_get_ts_info(struct net_device *dev, + struct ethtool_ts_info *info) +#endif /* HAVE_ETHTOOL_KERNEL_TS_INFO */ +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + /* we always support timestamping disabled */ + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); + + switch (adapter->hw.mac.type) { +#ifdef HAVE_PTP_1588_CLOCK + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + info->rx_filters |= BIT(HWTSTAMP_FILTER_ALL); + break; + case ixgbe_mac_E610: + info->rx_filters |= BIT(HWTSTAMP_FILTER_ALL); + break; + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + info->rx_filters |= + BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | + BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | + BIT(HWTSTAMP_FILTER_PTP_V2_EVENT); + break; +#endif /* HAVE_PTP_1588_CLOCK */ + default: + return ethtool_op_get_ts_info(dev, info); + } +#ifdef HAVE_PTP_1588_CLOCK + + info->so_timestamping = + SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + if (adapter->ptp_clock) + info->phc_index = ptp_clock_index(adapter->ptp_clock); + else + info->phc_index = -1; + + info->tx_types = + BIT(HWTSTAMP_TX_OFF) | + BIT(HWTSTAMP_TX_ON); + + return 0; +#endif /* HAVE_PTP_1588_CLOCK */ +} +#endif /* HAVE_ETHTOOL_GET_TS_INFO */ + +#endif /* ETHTOOL_GRXRINGS */ +#ifdef ETHTOOL_SCHANNELS +static unsigned int ixgbe_max_channels(struct ixgbe_adapter *adapter) +{ + unsigned int max_combined; + u8 tcs = netdev_get_num_tc(adapter->netdev); + + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { + /* We only support one q_vector without MSI-X */ + max_combined = 1; + } else if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + /* Limit value based on the queue mask */ + max_combined = adapter->ring_feature[RING_F_RSS].mask + 1; + } else if (tcs > 1) { + /* For DCB report channels per traffic class */ + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + /* 8 TC w/ 4 queues per TC */ + max_combined = 4; + } else if (tcs > 4) { + /* 8 TC w/ 8 queues per TC */ + max_combined = 8; + } else { + /* 4 TC w/ 16 queues per TC */ + max_combined = 16; + } + } else if (adapter->atr_sample_rate) { + /* support up to MAX FDIR or num proc queues with ATR */ + u8 numcpus = num_possible_cpus(); + + if (numcpus > IXGBE_MAX_FDIR_INDICES) { + max_combined = IXGBE_MAX_FDIR_INDICES; + } else { + max_combined = numcpus; + } + } else { + /* support up to max allowed queues with RSS */ + max_combined = ixgbe_max_rss_indices(adapter); + } + + return max_combined; +} + +/** + * ixgbe_get_channels - Retrieve channel configuration for the network device + * @dev: Network device structure + * @ch: Pointer to the ethtool_channels structure to be filled with channel info + * + * This function retrieves the channel configuration for the specified network + * device and populates the provided `ethtool_channels` structure with the + * relevant information. It reports the maximum number of combined channels, + * the number of other channels, and the current count of combined channels + * based on the device's configuration. + * + * The function is used to provide information about the device's channel + * capabilities and current configuration, which can be useful for network + * management and optimization. + */ +static void ixgbe_get_channels(struct net_device *dev, + struct ethtool_channels *ch) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + /* report maximum channels */ + ch->max_combined = ixgbe_max_channels(adapter); + + /* report info for other vector */ + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + ch->max_other = NON_Q_VECTORS; + ch->other_count = NON_Q_VECTORS; + } + + /* record RSS queues */ + ch->combined_count = adapter->ring_feature[RING_F_RSS].indices; + + /* nothing else to report if RSS is disabled */ + if (ch->combined_count == 1) + return; + + /* we do not support ATR queueing if SR-IOV is enabled */ + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + return; + + /* same thing goes for being DCB enabled */ + if (netdev_get_num_tc(dev) > 1) + return; + + /* if ATR is disabled we can exit */ + if (!adapter->atr_sample_rate) + return; + + /* report flow director queues as maximum channels */ + ch->combined_count = adapter->ring_feature[RING_F_FDIR].indices; +} + +/** + * ixgbe_set_channels - Configure the number of channels for the network device + * @dev: Network device structure + * @ch: Pointer to ethtool_channels structure containing desired channel configuration + * + * This function sets the number of combined channels for the specified network + * device based on the provided `ethtool_channels` structure. It verifies that + * the requested configuration does not exceed hardware limits and that separate + * RX and TX vectors are not requested. The function updates the adapter's + * feature limits and adjusts RSS and FCoE limits as necessary. + * + * Return: 0 on success, or -EINVAL if the configuration is invalid. + */ +static int ixgbe_set_channels(struct net_device *dev, + struct ethtool_channels *ch) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + unsigned int count = ch->combined_count; + u8 max_rss_indices = ixgbe_max_rss_indices(adapter); + + /* verify they are not requesting separate vectors */ + if (!count || ch->rx_count || ch->tx_count) + return -EINVAL; + + /* verify other_count has not changed */ + if (ch->other_count != NON_Q_VECTORS) + return -EINVAL; + + /* verify the number of channels does not exceed hardware limits */ + if (count > ixgbe_max_channels(adapter)) + return -EINVAL; + + /* update feature limits from largest to smallest supported values */ + adapter->ring_feature[RING_F_FDIR].limit = count; + + /* cap RSS limit */ + if (count > max_rss_indices) + count = max_rss_indices; + adapter->ring_feature[RING_F_RSS].limit = count; + +#if IS_ENABLED(CONFIG_FCOE) + /* cap FCoE limit at 8 */ + if (count > IXGBE_FCRETA_SIZE) + count = IXGBE_FCRETA_SIZE; + adapter->ring_feature[RING_F_FCOE].limit = count; +#endif /* CONFIG_FCOE */ + + /* use setup TC to update any traffic class queue mapping */ + return ixgbe_setup_tc(dev, netdev_get_num_tc(dev)); +} +#endif /* ETHTOOL_SCHANNELS */ + +#ifdef ETHTOOL_GMODULEINFO +/** + * ixgbe_get_module_info - Retrieve module information + * @dev: Network device structure + * @modinfo: Pointer to ethtool_modinfo structure to be filled with module info + * + * This function retrieves information about the network module (e.g., SFP) for + * the specified network device. It checks if the module supports SFF-8472 and + * determines the EEPROM length and type. If the module requires an unsupported + * addressing mode, it logs an error and defaults to SFF-8079. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + u32 status; + u8 sff8472_rev, addr_mode; + bool page_swap = false; + + /* Check whether we support SFF-8472 or not */ + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_SFF_8472_COMP, + &sff8472_rev); + if (status != 0) + return -EIO; + + /* addressing mode is not supported */ + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_SFF_8472_SWAP, + &addr_mode); + if (status != 0) + return -EIO; + + if (addr_mode & IXGBE_SFF_ADDRESSING_MODE) { + e_err(drv, "Address change required to access page 0xA2, but not supported. Please report the module type to the driver maintainers.\n"); + page_swap = true; + } + + if (sff8472_rev == IXGBE_SFF_SFF_8472_UNSUP || page_swap) { + /* We have a SFP, but it does not support SFF-8472 */ + modinfo->type = ETH_MODULE_SFF_8079; + modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; + } else { + /* We have a SFP which supports a revision of SFF-8472. */ + modinfo->type = ETH_MODULE_SFF_8472; + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + } + + return 0; +} + +/** + * ixgbe_get_module_eeprom - Retrieve module EEPROM data + * @dev: Network device structure + * @ee: Pointer to ethtool_eeprom structure specifying the EEPROM section + * @data: Buffer to store the retrieved EEPROM data + * + * This function reads EEPROM data from a network module (e.g., SFP) for the + * specified network device. It supports reading both standard and extended + * EEPROM data, depending on the offset. The function checks if the device is + * busy with SFP initialization and returns an error if so. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_get_module_eeprom(struct net_device *dev, + struct ethtool_eeprom *ee, + u8 *data) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + u32 status = IXGBE_ERR_PHY_ADDR_INVALID; + u8 databyte = 0xFF; + int i = 0; + + if (ee->len == 0) + return -EINVAL; + + for (i = ee->offset; i < ee->offset + ee->len; i++) { + /* I2C reads can take long time */ + if (test_bit(__IXGBE_IN_SFP_INIT, adapter->state)) + return -EBUSY; + + if (i < ETH_MODULE_SFF_8079_LEN) + status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte); + else + status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte); + + if (status != 0) + return -EIO; + + data[i - ee->offset] = databyte; + } + + return 0; +} +#endif /* ETHTOOL_GMODULEINFO */ + +#ifdef ETHTOOL_GEEE + +static const struct { + ixgbe_link_speed mac_speed; + u32 link_mode; +} ixgbe_ls_map[] = { + { IXGBE_LINK_SPEED_10_FULL, ETHTOOL_LINK_MODE_10baseT_Full_BIT }, + { IXGBE_LINK_SPEED_100_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT }, + { IXGBE_LINK_SPEED_1GB_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT }, + { IXGBE_LINK_SPEED_2_5GB_FULL, ETHTOOL_LINK_MODE_2500baseT_Full_BIT }, + { IXGBE_LINK_SPEED_10GB_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT }, +}; + +static const struct { + u32 lp_advertised; + u32 link_mode; +} ixgbe_lp_map[] = { + { FW_PHY_ACT_UD_2_100M_TX_EEE, ETHTOOL_LINK_MODE_100baseT_Full_BIT }, + { FW_PHY_ACT_UD_2_1G_T_EEE, ETHTOOL_LINK_MODE_1000baseT_Full_BIT }, + { FW_PHY_ACT_UD_2_10G_T_EEE, ETHTOOL_LINK_MODE_10000baseT_Full_BIT }, + { FW_PHY_ACT_UD_2_1G_KX_EEE, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT }, + { FW_PHY_ACT_UD_2_10G_KX4_EEE, ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT }, + { FW_PHY_ACT_UD_2_10G_KR_EEE, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT}, +}; + +static int +ixgbe_get_keee_fw(struct ixgbe_adapter *adapter, struct ethtool_keee *kedata) +{ + __ETHTOOL_DECLARE_LINK_MODE_MASK(common); + u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; + struct ixgbe_hw *hw = &adapter->hw; + s32 rc; + u16 i; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_UD_2, &info); + if (rc) + return rc; + + linkmode_zero(kedata->lp_advertised); + for (i = 0; i < ARRAY_SIZE(ixgbe_lp_map); ++i) { + if (info[0] & ixgbe_lp_map[i].lp_advertised) + linkmode_set_bit(ixgbe_lp_map[i].link_mode, + kedata->lp_advertised); + } + + linkmode_zero(kedata->supported); + for (i = 0; i < ARRAY_SIZE(ixgbe_ls_map); ++i) { + if (hw->phy.eee_speeds_supported & ixgbe_ls_map[i].mac_speed) + linkmode_set_bit(ixgbe_lp_map[i].link_mode, + kedata->supported); + } + + linkmode_zero(kedata->advertised); + for (i = 0; i < ARRAY_SIZE(ixgbe_ls_map); ++i) { + if (hw->phy.eee_speeds_advertised & ixgbe_ls_map[i].mac_speed) + linkmode_set_bit(ixgbe_lp_map[i].link_mode, + kedata->advertised); + } + + kedata->eee_enabled = !linkmode_empty(kedata->advertised); + kedata->tx_lpi_enabled = kedata->eee_enabled; + linkmode_and(common, kedata->advertised, kedata->lp_advertised); + kedata->eee_active = !linkmode_empty(common); + + return 0; +} +#ifdef HAVE_ETHTOOL_KEEE +static const struct { + __le16 eee_cap_bit; + u32 mac_speed; +} ixgbe_eee_cap_map[] = { + { IXGBE_ACI_PHY_EEE_EN_100BASE_TX, ETHTOOL_LINK_MODE_100baseT_Full_BIT }, + { IXGBE_ACI_PHY_EEE_EN_1000BASE_T, ETHTOOL_LINK_MODE_1000baseT_Full_BIT }, + { IXGBE_ACI_PHY_EEE_EN_10GBASE_T, ETHTOOL_LINK_MODE_10000baseT_Full_BIT }, + { IXGBE_ACI_PHY_EEE_EN_5GBASE_T, ETHTOOL_LINK_MODE_5000baseT_Full_BIT }, + { IXGBE_ACI_PHY_EEE_EN_2_5GBASE_T, ETHTOOL_LINK_MODE_2500baseX_Full_BIT }, +}; + +static const struct { + ixgbe_link_speed shared_speed; + u32 kernel_speed; +} ixgbe_kernel_map[] = { + { IXGBE_LINK_SPEED_100_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT }, + { IXGBE_LINK_SPEED_1GB_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT }, + { IXGBE_LINK_SPEED_2_5GB_FULL, ETHTOOL_LINK_MODE_2500baseX_Full_BIT }, + { IXGBE_LINK_SPEED_5GB_FULL, ETHTOOL_LINK_MODE_5000baseT_Full_BIT }, + { IXGBE_LINK_SPEED_10GB_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT }, +}; + +/** + * ixgbe_get_keee_E610 - Retrieve EEE settings for E610 hardware + * @netdev: Network device structure + * @kedata: Pointer to ethtool_keee structure to be filled with EEE settings + * + * This function retrieves Energy Efficient Ethernet (EEE) settings for E610 + * hardware. It populates the `kedata` structure with supported, advertised, + * and link partner advertised EEE capabilities. It also checks if EEE is + * active and enabled, and sets the LPI (Low Power Idle) timer if applicable. + * + * Return: 0 on success, or a negative error code on failure. + */ +static s32 +ixgbe_get_keee_E610(struct net_device *netdev, struct ethtool_keee *kedata) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + struct ixgbe_aci_cmd_get_phy_caps_data pcaps; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_link_status link; + u16 eee_cap; + s32 status; + int i; + + if (!(adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE)) + return -EOPNOTSUPP; + + linkmode_zero(kedata->lp_advertised); + linkmode_zero(kedata->supported); + linkmode_zero(kedata->advertised); + + status = ixgbe_aci_get_link_info(hw, true, &link); + if (status) + return status; + + kedata->eee_active = link.eee_status & IXGBE_ACI_LINK_EEE_ACTIVE; + kedata->eee_enabled = link.eee_status & IXGBE_ACI_LINK_EEE_ENABLED; + + /* for E610 devices EEE enablement implies TX LPI enablement */ + kedata->tx_lpi_enabled = kedata->eee_enabled; + + status = ixgbe_aci_get_phy_caps(hw, false, + IXGBE_ACI_REPORT_ACTIVE_CFG, &pcaps); + if (status) + return status; + + if (kedata->eee_enabled) + kedata->tx_lpi_timer = IXGBE_LE16_TO_CPU(pcaps.eee_entry_delay); + + eee_cap = IXGBE_LE16_TO_CPU(pcaps.eee_cap); + + for (i = 0; i < ARRAY_SIZE(ixgbe_eee_cap_map); i++) { + if (eee_cap & ixgbe_eee_cap_map[i].eee_cap_bit) + linkmode_set_bit(ixgbe_eee_cap_map[i].mac_speed, + kedata->lp_advertised); + } + + for (i = 0; i < ARRAY_SIZE(ixgbe_kernel_map); i++) { + if (hw->phy.eee_speeds_supported & + ixgbe_kernel_map[i].shared_speed) + linkmode_set_bit(ixgbe_kernel_map[i].kernel_speed, + kedata->supported); + + if (hw->phy.eee_speeds_advertised & + ixgbe_kernel_map[i].shared_speed) + linkmode_set_bit(ixgbe_kernel_map[i].kernel_speed, + kedata->advertised); + } + + return 0; +} +#endif /* HAVE_ETHTOOL_KEEE */ + +/** + * ixgbe_get_keee - Retrieve EEE settings for the network device + * @netdev: Network device structure + * @kedata: Pointer to ethtool_keee structure to be filled with EEE settings + * + * This function retrieves Energy Efficient Ethernet (EEE) settings for the + * specified network device. It checks if EEE is supported and, if so, populates + * the `kedata` structure with supported, advertised, and active EEE capabilities. + * If the device uses firmware-based EEE, it delegates to `ixgbe_get_keee_fw`. + * + * Return: 0 on success, or -EOPNOTSUPP if EEE is not supported. + */ +static int ixgbe_get_keee(struct net_device *netdev, struct ethtool_keee *kedata) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (!hw->mac.ops.setup_eee) + return -EOPNOTSUPP; + + if (!(adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE)) + return -EOPNOTSUPP; + + if (hw->phy.eee_speeds_supported && hw->phy.type == ixgbe_phy_fw) { + return ixgbe_get_keee_fw(adapter, kedata); + } + + return -EOPNOTSUPP; +} + +#ifndef HAVE_ETHTOOL_KEEE + +#define IXGBE_LINK_MODE_MASK 0xFFFFFFFF + +/** + * ixgbe_get_eee - Retrieve Energy Efficient Ethernet (EEE) settings + * @netdev: Network device structure + * @edata: Pointer to ethtool_eee structure to be filled with EEE settings + * + * This function retrieves the Energy Efficient Ethernet (EEE) settings for the + * specified network device. It converts the EEE settings to a kernel-specific + * format, calls `ixgbe_get_keee` to get the settings, and then converts them + * back. It also applies a workaround for kernels with limited link mode support. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_get_eee(struct net_device *netdev, struct ethtool_eee *edata) +{ + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; + struct ethtool_keee kedata; + int ret; + + eee_to_keee(&kedata, edata); + ret = ixgbe_get_keee(netdev, &kedata); + + /* workaround for kernels limiting linkmode up to 32 bits */ + ethtool_convert_legacy_u32_to_link_mode(mask, IXGBE_LINK_MODE_MASK); + linkmode_and(kedata.supported, kedata.supported, mask); + + keee_to_eee(edata, &kedata); + + return ret; +} +#endif /* !HAVE_ETHTOOL_KEEE */ +#endif /* ETHTOOL_GEEE */ + +#ifdef ETHTOOL_SEEE +static int ixgbe_validate_keee(struct net_device *netdev, + struct ethtool_keee *keee_requested) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + struct ethtool_keee keee_stored = {}; + struct ixgbe_hw *hw = &adapter->hw; +#ifndef HAVE_ETHTOOL_KEEE + struct ethtool_eee eee_stored = {}; +#endif + int ret_val; + + if (!(hw->mac.ops.setup_eee && + (adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE))) + return -EOPNOTSUPP; + +#ifndef HAVE_ETHTOOL_KEEE + ret_val = netdev->ethtool_ops->get_eee(netdev, &eee_stored); +#else + ret_val = netdev->ethtool_ops->get_eee(netdev, &keee_stored); +#endif + if (ret_val) + return ret_val; + +#ifndef HAVE_ETHTOOL_KEEE + eee_to_keee(&keee_stored, &eee_stored); +#endif + if (keee_stored.tx_lpi_enabled != keee_requested->tx_lpi_enabled) { + e_dev_err("Setting EEE Tx LPI is not supported\n"); + return -EINVAL; + } + + if (keee_stored.tx_lpi_timer != keee_requested->tx_lpi_timer) { + e_dev_err("Setting EEE Tx LPI timer is not supported\n"); + return -EINVAL; + } + + if (*keee_stored.advertised != *keee_requested->advertised) { + e_dev_err("Setting EEE advertised speeds is not supported\n"); + return -EINVAL; + } + + if (keee_stored.eee_enabled == keee_requested->eee_enabled) + return -EALREADY; + + return 0; +} + +/** + * ixgbe_check_link_for_eee_e610 - Check if EEE can be enabled + * @adapter - pointer to the adapter struct + * @print_msg - indicate whether to print info msg when EEE cannot be supported + * + * Check whether current link configuration is capable of enabling EEE feature. + * + * E610 specific function - for other adapters supporting EEE there might be + * no such limitation. + * + * Return: true if EEE can be enabled, false otherwise. + */ +bool ixgbe_check_link_for_eee_e610(struct ixgbe_adapter *adapter, + bool print_msg) +{ + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + case IXGBE_LINK_SPEED_2_5GB_FULL: + case IXGBE_LINK_SPEED_5GB_FULL: + return true; + case IXGBE_LINK_SPEED_10_FULL: + case IXGBE_LINK_SPEED_100_FULL: + case IXGBE_LINK_SPEED_1GB_FULL: + if (print_msg) + e_dev_info("Energy Efficient Ethernet (EEE) feature is not supported on link speeds equal to or below 1Gbps. EEE is supported on speeds above 1Gbps.\n"); + fallthrough; + default: + return false; + } +} + +#ifdef HAVE_ETHTOOL_KEEE +/** + * ixgbe_set_keee_E610 - Configure EEE settings for E610 hardware + * @netdev: Network device structure + * @kedata: Pointer to ethtool_keee structure with desired EEE settings + * + * This function sets the Energy Efficient Ethernet (EEE) parameters for E610 + * hardware based on the provided `ethtool_keee` structure. It validates the + * settings, updates the adapter's configuration, and applies the changes. If + * necessary, it reinitializes or resets the device to apply the new settings. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_keee_E610(struct net_device *netdev, + struct ethtool_keee *kedata) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + s32 ret_val; + + ret_val = ixgbe_validate_keee(netdev, kedata); + if (ret_val == -EALREADY) + return 0; + else if (ret_val) + return ret_val; + + if (!ixgbe_check_link_for_eee_e610(adapter, true) && + kedata->eee_enabled) + return -EOPNOTSUPP; + + hw->phy.eee_speeds_advertised = kedata->eee_enabled ? + hw->phy.eee_speeds_supported : 0; + + ret_val = hw->mac.ops.setup_eee(hw, kedata->eee_enabled); + if (ret_val) { + e_dev_err("Setting EEE %s failed.\n", + (kedata->eee_enabled ? "on" : "off")); + return ret_val; + } + + if (kedata->eee_enabled) + adapter->eee_state = IXGBE_EEE_ENABLED; + else + adapter->eee_state = IXGBE_EEE_DISABLED; + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + + return 0; +} +#endif /* HAVE_ETHTOOL_KEEE */ + +/** + * ixgbe_set_keee - Configure EEE settings for the network device + * @netdev: Network device structure + * @kedata: Pointer to ethtool_keee structure with desired EEE settings + * + * This function sets the Energy Efficient Ethernet (EEE) parameters for the + * specified network device based on the provided `ethtool_keee` structure. It + * validates the settings, updates the adapter's configuration, and applies the + * changes. If necessary, it reinitializes or resets the device to apply the new + * settings. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_keee(struct net_device *netdev, struct ethtool_keee *kedata) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + s32 ret_val; + + ret_val = ixgbe_validate_keee(netdev, kedata); + if (ret_val == -EALREADY) + return 0; + else if (ret_val) + return ret_val; + + hw->phy.eee_speeds_advertised = kedata->eee_enabled ? + hw->phy.eee_speeds_supported : 0; + + if (kedata->eee_enabled) + adapter->eee_state = IXGBE_EEE_ENABLED; + else + adapter->eee_state = IXGBE_EEE_DISABLED; + + /* reset link */ + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + + return 0; +} + +#ifndef HAVE_ETHTOOL_KEEE +/** + * ixgbe_set_eee - Configure Energy Efficient Ethernet (EEE) settings + * @netdev: Network device structure + * @edata: Pointer to ethtool_eee structure with desired EEE settings + * + * This function sets the Energy Efficient Ethernet (EEE) parameters for the + * specified network device based on the provided `ethtool_eee` structure. It + * converts the EEE settings to a kernel-specific format, applies the settings, + * and then converts them back. It includes a workaround for kernels with + * limited link mode support. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_eee(struct net_device *netdev, struct ethtool_eee *edata) +{ + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; + struct ethtool_keee kedata; + int ret; + + eee_to_keee(&kedata, edata); + ret = ixgbe_set_keee(netdev, &kedata); + + /* workaround for kernels limiting linkmode up to 32 bits */ + ethtool_convert_legacy_u32_to_link_mode(mask, IXGBE_LINK_MODE_MASK); + linkmode_and(kedata.supported, kedata.supported, mask); + + keee_to_eee(edata, &kedata); + + return ret; +} +#endif /* !HAVE_ETHTOOL_KEEE */ +#endif /* ETHTOOL_SEEE */ + +#ifdef HAVE_ETHTOOL_GET_SSET_COUNT +/** + * ixgbe_get_priv_flags - Report device private flags + * @netdev: Network interface device structure + * + * This function retrieves the private flags for the ixgbe network adapter. + * It checks the adapter's configuration and sets the corresponding flags in + * a bitmap. The function ensures that the flags returned match the string + * set count and the string set in the `ixgbe_priv_flags_strings` array. + * + * Return: A u32 bitmap of private flags. + */ +static u32 ixgbe_get_priv_flags(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u32 priv_flags = 0; + + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) + priv_flags |= IXGBE_PRIV_FLAGS_FD_ATR; +#ifdef HAVE_SWIOTLB_SKIP_CPU_SYNC + + if (adapter->flags2 & IXGBE_FLAG2_RX_LEGACY) + priv_flags |= IXGBE_PRIV_FLAGS_LEGACY_RX; +#endif + if (adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) + priv_flags |= IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF; + + return priv_flags; +} + +/** + * ixgbe_set_priv_flags - Set private flags for the network device + * @netdev: Network interface device structure + * @priv_flags: Bit flags to be set + * + * This function sets the private flags for the ixgbe network adapter based + * on the provided bit flags. It allows control over features such as Flow + * Director ATR (Application Targeted Routing) and legacy receive mode. The + * function checks for compatibility and constraints before setting the + * flags, and performs necessary resets or reinitializations if the flags + * change. It returns an error if the requested flags are not supported or + * cannot be enabled due to current configuration. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + unsigned int flags2 = adapter->flags2; + unsigned int flags = adapter->flags; + unsigned int i; + + /* allow the user to control the state of the Flow + * Director ATR (Application Targeted Routing) feature + * of the driver + */ + flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + if (priv_flags & IXGBE_PRIV_FLAGS_FD_ATR) { + /* We cannot enable ATR if VMDq is enabled */ + if (flags & IXGBE_FLAG_VMDQ_ENABLED) + return -EINVAL; + /* We cannot enable ATR if we have 2 or more traffic classes */ + if (netdev_get_num_tc(netdev) > 1) + return -EINVAL; + /* We cannot enable ATR if RSS is disabled */ + if (adapter->ring_feature[RING_F_RSS].limit <= 1) + return -EINVAL; + /* A sample rate of 0 indicates ATR disabled */ + if (!adapter->atr_sample_rate) + return -EINVAL; + flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + } +#ifdef HAVE_SWIOTLB_SKIP_CPU_SYNC + + flags2 &= ~IXGBE_FLAG2_RX_LEGACY; + if (priv_flags & IXGBE_PRIV_FLAGS_LEGACY_RX) + flags2 |= IXGBE_FLAG2_RX_LEGACY; +#endif + + flags2 &= ~IXGBE_FLAG2_AUTO_DISABLE_VF; + if (priv_flags & IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF) { + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + /* Reset primary abort counter */ + for (i = 0; i < adapter->num_vfs; i++) + adapter->vfinfo[i].primary_abort_count = 0; + + flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF; + } else { + e_info(probe, + "Cannot set private flags: Operation not supported\n"); + return -EOPNOTSUPP; + } + } + + if (flags != adapter->flags) { + adapter->flags = flags; + + /* ATR state change requires a reset */ + ixgbe_do_reset(netdev); + } else if (flags2 != adapter->flags2) { + adapter->flags2 = flags2; + + /* reset interface to repopulate queues */ + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + } + + return 0; +} + +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ +static struct ethtool_ops ixgbe_ethtool_ops = { +#ifdef ETHTOOL_GLINKSETTINGS + .get_link_ksettings = ixgbe_get_link_ksettings, + .set_link_ksettings = ixgbe_set_link_ksettings, +#else + .get_settings = ixgbe_get_settings, + .set_settings = ixgbe_set_settings, +#endif + .get_drvinfo = ixgbe_get_drvinfo, + .get_regs_len = ixgbe_get_regs_len, + .get_regs = ixgbe_get_regs, + .get_wol = ixgbe_get_wol, + .set_wol = ixgbe_set_wol, + .nway_reset = ixgbe_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = ixgbe_get_eeprom_len, + .get_eeprom = ixgbe_get_eeprom, + .set_eeprom = ixgbe_set_eeprom, + .get_ringparam = ixgbe_get_ringparam, + .set_ringparam = ixgbe_set_ringparam, + .get_pauseparam = ixgbe_get_pauseparam, + .set_pauseparam = ixgbe_set_pauseparam, + .get_msglevel = ixgbe_get_msglevel, + .set_msglevel = ixgbe_set_msglevel, +#ifndef HAVE_ETHTOOL_GET_SSET_COUNT + .self_test_count = ixgbe_diag_test_count, +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + .self_test = ixgbe_diag_test, + .get_strings = ixgbe_get_strings, +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +#ifdef HAVE_ETHTOOL_SET_PHYS_ID + .set_phys_id = ixgbe_set_phys_id, +#else + .phys_id = ixgbe_phys_id, +#endif /* HAVE_ETHTOOL_SET_PHYS_ID */ +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +#ifndef HAVE_ETHTOOL_GET_SSET_COUNT + .get_stats_count = ixgbe_get_stats_count, +#else /* HAVE_ETHTOOL_GET_SSET_COUNT */ + .get_sset_count = ixgbe_get_sset_count, + .get_priv_flags = ixgbe_get_priv_flags, + .set_priv_flags = ixgbe_set_priv_flags, +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + .get_ethtool_stats = ixgbe_get_ethtool_stats, +#ifdef HAVE_ETHTOOL_GET_PERM_ADDR + .get_perm_addr = ethtool_op_get_perm_addr, +#endif + .get_coalesce = ixgbe_get_coalesce, + .set_coalesce = ixgbe_set_coalesce, +#ifdef ETHTOOL_COALESCE_USECS + .supported_coalesce_params = ETHTOOL_COALESCE_USECS, +#endif +#ifndef HAVE_NDO_SET_FEATURES + .get_rx_csum = ixgbe_get_rx_csum, + .set_rx_csum = ixgbe_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ixgbe_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, + .set_tso = ixgbe_set_tso, +#endif +#ifdef ETHTOOL_GFLAGS + .get_flags = ethtool_op_get_flags, + .set_flags = ixgbe_set_flags, +#endif +#endif /* HAVE_NDO_SET_FEATURES */ +#ifdef ETHTOOL_GRXRINGS + .get_rxnfc = ixgbe_get_rxnfc, + .set_rxnfc = ixgbe_set_rxnfc, +#ifdef ETHTOOL_SRXNTUPLE + .set_rx_ntuple = ixgbe_set_rx_ntuple, +#endif +#endif /* ETHTOOL_GRXRINGS */ +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +#ifdef ETHTOOL_GEEE +#ifdef HAVE_ETHTOOL_KEEE + .get_eee = ixgbe_get_keee, +#else + .get_eee = ixgbe_get_eee, +#endif /* HAVE_ETHTOOL_KEEE */ +#endif /* ETHTOOL_GEEE */ +#ifdef ETHTOOL_SEEE +#ifdef HAVE_ETHTOOL_KEEE + .set_eee = ixgbe_set_keee, +#else + .set_eee = ixgbe_set_eee, +#endif /* HAVE_ETHTOOL_KEEE */ +#endif /* ETHTOOL_SEEE */ +#ifdef ETHTOOL_SCHANNELS + .get_channels = ixgbe_get_channels, + .set_channels = ixgbe_set_channels, +#endif +#ifdef ETHTOOL_GMODULEINFO + .get_module_info = ixgbe_get_module_info, + .get_module_eeprom = ixgbe_get_module_eeprom, +#endif +#ifdef HAVE_ETHTOOL_GET_TS_INFO + .get_ts_info = ixgbe_get_ts_info, +#endif +#if defined(ETHTOOL_GRSSH) && defined(ETHTOOL_SRSSH) + .get_rxfh_indir_size = ixgbe_rss_indir_size, + .get_rxfh_key_size = ixgbe_get_rxfh_key_size, + .get_rxfh = ixgbe_get_rxfh, + .set_rxfh = ixgbe_set_rxfh, +#endif /* ETHTOOL_GRSSH && ETHTOOL_SRSSH */ +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +}; + +static struct ethtool_ops ixgbe_ethtool_ops_E610 = { +#ifdef ETHTOOL_GLINKSETTINGS + .get_link_ksettings = ixgbe_get_link_ksettings, + .set_link_ksettings = ixgbe_set_link_ksettings, +#else + .get_settings = ixgbe_get_settings, + .set_settings = ixgbe_set_settings, +#endif + .get_drvinfo = ixgbe_get_drvinfo, + .get_regs_len = ixgbe_get_regs_len, + .get_regs = ixgbe_get_regs, + .get_wol = ixgbe_get_wol, + .set_wol = ixgbe_set_wol_E610, + .nway_reset = ixgbe_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = ixgbe_get_eeprom_len_E610, + .get_eeprom = ixgbe_get_eeprom, + .set_eeprom = ixgbe_set_eeprom, + .get_ringparam = ixgbe_get_ringparam, + .set_ringparam = ixgbe_set_ringparam, + .get_pauseparam = ixgbe_get_pauseparam, + .set_pauseparam = ixgbe_set_pauseparam_E610, + .get_msglevel = ixgbe_get_msglevel, + .set_msglevel = ixgbe_set_msglevel, +#ifndef HAVE_ETHTOOL_GET_SSET_COUNT + .self_test_count = ixgbe_diag_test_count, +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + .self_test = ixgbe_diag_test, + .get_strings = ixgbe_get_strings, +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +#ifdef HAVE_ETHTOOL_SET_PHYS_ID + .set_phys_id = ixgbe_set_phys_id_E610, +#else + .phys_id = ixgbe_phys_id, +#endif /* HAVE_ETHTOOL_SET_PHYS_ID */ +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +#ifndef HAVE_ETHTOOL_GET_SSET_COUNT + .get_stats_count = ixgbe_get_stats_count, +#else /* HAVE_ETHTOOL_GET_SSET_COUNT */ + .get_sset_count = ixgbe_get_sset_count, + .get_priv_flags = ixgbe_get_priv_flags, + .set_priv_flags = ixgbe_set_priv_flags, +#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */ + .get_ethtool_stats = ixgbe_get_ethtool_stats, +#ifdef HAVE_ETHTOOL_GET_PERM_ADDR + .get_perm_addr = ethtool_op_get_perm_addr, +#endif + .get_coalesce = ixgbe_get_coalesce, + .set_coalesce = ixgbe_set_coalesce, +#ifdef ETHTOOL_COALESCE_USECS + .supported_coalesce_params = ETHTOOL_COALESCE_USECS, +#endif +#ifndef HAVE_NDO_SET_FEATURES + .get_rx_csum = ixgbe_get_rx_csum, + .set_rx_csum = ixgbe_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ixgbe_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, + .set_tso = ixgbe_set_tso, +#endif +#ifdef ETHTOOL_GFLAGS + .get_flags = ethtool_op_get_flags, + .set_flags = ixgbe_set_flags, +#endif +#endif /* HAVE_NDO_SET_FEATURES */ +#ifdef ETHTOOL_GRXRINGS + .get_rxnfc = ixgbe_get_rxnfc, + .set_rxnfc = ixgbe_set_rxnfc, +#ifdef ETHTOOL_SRXNTUPLE + .set_rx_ntuple = ixgbe_set_rx_ntuple, +#endif +#endif /* ETHTOOL_GRXRINGS */ +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +#ifdef HAVE_ETHTOOL_KEEE +#ifdef ETHTOOL_GEEE + .get_eee = ixgbe_get_keee_E610, +#endif /* ETHTOOL_GEEE */ +#ifdef ETHTOOL_SEEE + .set_eee = ixgbe_set_keee_E610, +#endif /* ETHTOOL_SEEE */ +#endif /* HAVE_ETHTOOL_KEEE */ +#ifdef ETHTOOL_SCHANNELS + .get_channels = ixgbe_get_channels, + .set_channels = ixgbe_set_channels, +#endif +#ifdef ETHTOOL_GMODULEINFO + .get_module_info = ixgbe_get_module_info, + .get_module_eeprom = ixgbe_get_module_eeprom, +#endif +#ifdef HAVE_ETHTOOL_GET_TS_INFO + .get_ts_info = ixgbe_get_ts_info, +#endif +#if defined(ETHTOOL_GRSSH) && defined(ETHTOOL_SRSSH) + .get_rxfh_indir_size = ixgbe_rss_indir_size, + .get_rxfh_key_size = ixgbe_get_rxfh_key_size, + .get_rxfh = ixgbe_get_rxfh, + .set_rxfh = ixgbe_set_rxfh, +#endif /* ETHTOOL_GRSSH && ETHTOOL_SRSSH */ +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +}; + +#ifdef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +static const struct ethtool_ops_ext ixgbe_ethtool_ops_ext = { + .size = sizeof(struct ethtool_ops_ext), + .get_ts_info = ixgbe_get_ts_info, + .set_phys_id = ixgbe_set_phys_id, + .get_channels = ixgbe_get_channels, + .set_channels = ixgbe_set_channels, +#ifdef ETHTOOL_GMODULEINFO + .get_module_info = ixgbe_get_module_info, + .get_module_eeprom = ixgbe_get_module_eeprom, +#endif +#if defined(ETHTOOL_GRSSH) && defined(ETHTOOL_SRSSH) + .get_rxfh_indir_size = ixgbe_rss_indir_size, + .get_rxfh_key_size = ixgbe_get_rxfh_key_size, + .get_rxfh = ixgbe_get_rxfh, + .set_rxfh = ixgbe_set_rxfh, +#endif /* ETHTOOL_GRSSH && ETHTOOL_SRSSH */ +#ifdef ETHTOOL_GEEE + .get_eee = ixgbe_get_eee, +#endif /* ETHTOOL_GEEE */ +#ifdef ETHTOOL_SEEE + .set_eee = ixgbe_set_eee, +#endif /* ETHTOOL_SEEE */ +}; + +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +void ixgbe_set_ethtool_ops(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = + netdev_priv(netdev); +#ifndef ETHTOOL_OPS_COMPAT + switch (adapter->hw.mac.type) { + case ixgbe_mac_E610: + netdev->ethtool_ops = &ixgbe_ethtool_ops_E610; + break; + default: + netdev->ethtool_ops = &ixgbe_ethtool_ops; + break; + } +#else + switch (adapter->hw.mac.type) { + case ixgbe_mac_E610: + SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops_E610); + break; + default: + SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops); + break; + } +#endif + +#ifdef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT + set_ethtool_ops_ext(netdev, &ixgbe_ethtool_ops_ext); +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +} +#endif /* SIOCETHTOOL */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.c new file mode 100644 index 0000000000..379cd67156 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.c @@ -0,0 +1,1059 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + + +#if IS_ENABLED(CONFIG_FCOE) +#if IS_ENABLED(CONFIG_DCB) +#include "ixgbe_dcb_82599.h" +#endif /* CONFIG_DCB */ +#include +#include +#include +#include +#include +#include +#include + +/** + * ixgbe_fcoe_clear_ddp - clear the given ddp context + * @ddp: ptr to the ixgbe_fcoe_ddp + * + * Returns : none + * + */ +static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp) +{ + ddp->len = 0; + ddp->err = 1; + ddp->udl = NULL; + ddp->udp = 0UL; + ddp->sgl = NULL; + ddp->sgc = 0; +} + +/** + * ixgbe_fcoe_ddp_put - free the ddp context for a given xid + * @netdev: the corresponding net_device + * @xid: the xid that corresponding ddp will be freed + * + * This is the implementation of net_device_ops.ndo_fcoe_ddp_done + * and it is expected to be called by ULD, i.e., FCP layer of libfc + * to release the corresponding ddp context when the I/O is done. + * + * Returns : data length already ddp-ed in bytes + */ +int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) +{ + int len = 0; + struct ixgbe_fcoe *fcoe; + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct ixgbe_fcoe_ddp *ddp; + u32 fcbuff; + + if (!netdev) + goto out_ddp_put; + + if (xid > netdev->fcoe_ddp_xid) + goto out_ddp_put; + + adapter = netdev_priv(netdev); + hw = &adapter->hw; + fcoe = &adapter->fcoe; + ddp = &fcoe->ddp[xid]; + if (!ddp->udl) + goto out_ddp_put; + + len = ddp->len; + /* if there an error, force to invalidate ddp context */ + if (ddp->err) { + switch (hw->mac.type) { + case ixgbe_mac_X550: + /* X550 does not require DDP FCoE lock */ + + IXGBE_WRITE_REG(hw, IXGBE_FCDFC(0, xid), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCDFC(3, xid), + (xid | IXGBE_FCFLTRW_WE)); + + /* program FCBUFF */ + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(2, xid), 0); + + /* program FCDMARW */ + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(3, xid), + (xid | IXGBE_FCDMARW_WE)); + + /* read FCBUFF to check context invalidated */ + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(3, xid), + (xid | IXGBE_FCDMARW_RE)); + fcbuff = IXGBE_READ_REG(hw, + IXGBE_FCDDC(2, xid)); + break; + default: + /* other hardware requires DDP FCoE lock */ + spin_lock_bh(&fcoe->lock); + + IXGBE_WRITE_REG(hw, IXGBE_FCFLT, 0); + IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, + (xid | IXGBE_FCFLTRW_WE)); + IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, 0); + IXGBE_WRITE_REG(hw, IXGBE_FCDMARW, + (xid | IXGBE_FCDMARW_WE)); + + /* read FCBUFF to check context invalidated */ + IXGBE_WRITE_REG(hw, IXGBE_FCDMARW, + (xid | IXGBE_FCDMARW_RE)); + fcbuff = IXGBE_READ_REG(hw, IXGBE_FCBUFF); + + spin_unlock_bh(&fcoe->lock); + break; + } + + /* guaranteed to be invalidated after 100us */ + if (fcbuff & IXGBE_FCBUFF_VALID) + udelay(100); + } + if (ddp->sgl) + dma_unmap_sg(ixgbe_pf_to_dev(adapter), ddp->sgl, ddp->sgc, + DMA_FROM_DEVICE); + if (ddp->pool) { + dma_pool_free(ddp->pool, ddp->udl, ddp->udp); + ddp->pool = NULL; + } + + ixgbe_fcoe_clear_ddp(ddp); + +out_ddp_put: + return len; +} + +/** + * ixgbe_fcoe_ddp_setup - called to set up ddp context + * @netdev: the corresponding net_device + * @xid: the exchange id requesting ddp + * @sgl: the scatter-gather list for this request + * @sgc: the number of scatter-gather items + * @target_mode: 1 to setup target mode, 0 to setup initiator mode + * + * Returns : 1 for success and 0 for no ddp + */ +static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc, + int target_mode) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + struct ixgbe_fcoe *fcoe; + struct ixgbe_fcoe_ddp *ddp; + struct ixgbe_fcoe_ddp_pool *ddp_pool; + struct scatterlist *sg; + unsigned int i, j, dmacount; + unsigned int len; + static const unsigned int bufflen = IXGBE_FCBUFF_MIN; + unsigned int firstoff = 0; + unsigned int lastsize; + unsigned int thisoff = 0; + unsigned int thislen = 0; + u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; + dma_addr_t addr = 0; + + if (!netdev || !sgl || !sgc) + return 0; + + adapter = netdev_priv(netdev); + if (xid > netdev->fcoe_ddp_xid) { + e_warn(drv, "xid=0x%x out-of-range\n", xid); + return 0; + } + + /* no DDP if we are already down or resetting */ + if (test_bit(__IXGBE_DOWN, adapter->state) || + test_bit(__IXGBE_RESETTING, adapter->state)) + return 0; + + fcoe = &adapter->fcoe; + ddp = &fcoe->ddp[xid]; + if (ddp->sgl) { + e_err(drv, "xid 0x%x w/ non-null sgl=%p nents=%d\n", + xid, ddp->sgl, ddp->sgc); + return 0; + } + ixgbe_fcoe_clear_ddp(ddp); + + + if (!fcoe->ddp_pool) { + e_warn(drv, "No ddp_pool resources allocated\n"); + return 0; + } + + ddp_pool = per_cpu_ptr(fcoe->ddp_pool, get_cpu()); + if (!ddp_pool->pool) { + e_warn(drv, "xid=0x%x no ddp pool for fcoe\n", xid); + goto out_noddp; + } + + /* setup dma from scsi command sgl */ + dmacount = dma_map_sg(ixgbe_pf_to_dev(adapter), sgl, sgc, DMA_FROM_DEVICE); + if (dmacount == 0) { + e_err(drv, "xid 0x%x DMA map error\n", xid); + goto out_noddp; + } + + /* alloc the udl from per cpu ddp pool */ + ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_KERNEL, &ddp->udp); + if (!ddp->udl) { + e_err(drv, "failed allocated ddp context\n"); + goto out_noddp_unmap; + } + ddp->pool = ddp_pool->pool; + ddp->sgl = sgl; + ddp->sgc = sgc; + + j = 0; + for_each_sg(sgl, sg, dmacount, i) { + addr = sg_dma_address(sg); + len = sg_dma_len(sg); + while (len) { + /* max number of buffers allowed in one DDP context */ + if (j >= IXGBE_BUFFCNT_MAX) { + ddp_pool->noddp++; + goto out_noddp_free; + } + + /* get the offset of length of current buffer */ + thisoff = addr & ((dma_addr_t)bufflen - 1); + thislen = min((bufflen - thisoff), len); + /* + * all but the 1st buffer (j == 0) + * must be aligned on bufflen + */ + if ((j != 0) && (thisoff)) + goto out_noddp_free; + /* + * all but the last buffer + * ((i == (dmacount - 1)) && (thislen == len)) + * must end at bufflen + */ + if (((i != (dmacount - 1)) || (thislen != len)) + && ((thislen + thisoff) != bufflen)) + goto out_noddp_free; + + ddp->udl[j] = (u64)(addr - thisoff); + /* only the first buffer may have none-zero offset */ + if (j == 0) + firstoff = thisoff; + len -= thislen; + addr += thislen; + j++; + } + } + /* only the last buffer may have non-full bufflen */ + lastsize = thisoff + thislen; + + /* + * lastsize can not be bufflen. + * If it is then adding another buffer with lastsize = 1. + * Since lastsize is 1 there will be no HW access to this buffer. + */ + if (lastsize == bufflen) { + if (j >= IXGBE_BUFFCNT_MAX) { + ddp_pool->noddp_ext_buff++; + goto out_noddp_free; + } + + ddp->udl[j] = (u64)(fcoe->extra_ddp_buffer_dma); + j++; + lastsize = 1; + } + put_cpu(); + + fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); + fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); + fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); + /* Set WRCONTX bit to allow DDP for target */ + if (target_mode) + fcbuff |= (IXGBE_FCBUFF_WRCONTX); + fcbuff |= (IXGBE_FCBUFF_VALID); + + fcdmarw = xid; + fcdmarw |= IXGBE_FCDMARW_WE; + fcdmarw |= (lastsize << IXGBE_FCDMARW_LASTSIZE_SHIFT); + + fcfltrw = xid; + fcfltrw |= IXGBE_FCFLTRW_WE; + + /* program DMA context */ + hw = &adapter->hw; + + /* turn on last frame indication for target mode as FCP_RSPtarget is + * supposed to send FCP_RSP when it is done. */ + if (target_mode && !test_bit(__IXGBE_FCOE_TARGET, &fcoe->mode)) { + set_bit(__IXGBE_FCOE_TARGET, &fcoe->mode); + fcrxctl = IXGBE_READ_REG(hw, IXGBE_FCRXCTRL); + fcrxctl |= IXGBE_FCRXCTRL_LASTSEQH; + IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, fcrxctl); + } + + switch (hw->mac.type) { + case ixgbe_mac_X550: + /* X550 does not require DDP lock */ + + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(0, xid), + ddp->udp & DMA_BIT_MASK(32)); + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(1, xid), (u64)ddp->udp >> 32); + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(2, xid), fcbuff); + IXGBE_WRITE_REG(hw, IXGBE_FCDDC(3, xid), fcdmarw); + /* program filter context */ + IXGBE_WRITE_REG(hw, IXGBE_FCDFC(0, xid), IXGBE_FCFLT_VALID); + IXGBE_WRITE_REG(hw, IXGBE_FCDFC(1, xid), 0); + IXGBE_WRITE_REG(hw, IXGBE_FCDFC(3, xid), fcfltrw); + /* + * TBD: SMAC and FCID info not available with current + * netdev APIs, add code to pull that from skb later + * and then program that here before enabling DDP context. + */ + break; + default: + /* other devices require DDP lock with direct DDP context access */ + spin_lock_bh(&fcoe->lock); + + IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32)); + IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32); + IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff); + IXGBE_WRITE_REG(hw, IXGBE_FCDMARW, fcdmarw); + /* program filter context */ + IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0); + IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID); + IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw); + + spin_unlock_bh(&fcoe->lock); + break; + } + + return 1; + +out_noddp_free: + dma_pool_free(ddp->pool, ddp->udl, ddp->udp); + ixgbe_fcoe_clear_ddp(ddp); + +out_noddp_unmap: + dma_unmap_sg(ixgbe_pf_to_dev(adapter), sgl, sgc, DMA_FROM_DEVICE); +out_noddp: + put_cpu(); + return 0; +} + +/** + * ixgbe_fcoe_ddp_get - Set up DDP context in initiator mode + * @netdev: The corresponding network device + * @xid: The exchange ID requesting DDP + * @sgl: The scatter-gather list for this request + * @sgc: The number of scatter-gather items + * + * This function implements the `ndo_fcoe_ddp_setup` operation for the + * ixgbe network adapter. It is called from the Upper Layer Driver (ULD), + * such as the FCP layer of libfc, to set up Direct Data Placement (DDP) + * for the specified exchange ID (xid) using the provided scatter-gather + * list (sgl) for the corresponding I/O operation. + * + * Return: 1 for success, or 0 if DDP is not set up. + */ +int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc) +{ + return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0); +} + +#ifdef HAVE_NETDEV_OPS_FCOE_DDP_TARGET +/** + * ixgbe_fcoe_ddp_target - Set up DDP context in target mode + * @netdev: The corresponding network device + * @xid: The exchange ID requesting DDP + * @sgl: The scatter-gather list for this request + * @sgc: The number of scatter-gather items + * + * This function implements the `ndo_fcoe_ddp_target` operation for the + * ixgbe network adapter. It is called from the Upper Layer Driver (ULD), + * such as the FCP layer of libfc, to set up Direct Data Placement (DDP) + * for the specified exchange ID (xid) using the provided scatter-gather + * list (sgl) for the corresponding I/O operation. In target mode, DDP + * handles write I/O requests from the initiator. + * + * Return: 1 for success, or 0 if DDP is not set up. + */ +int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc) +{ + return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1); +} +#endif /* HAVE_NETDEV_OPS_FCOE_DDP_TARGET */ + +/** + * ixgbe_fcoe_ddp - Check DDP status and mark it done + * @adapter: ixgbe adapter structure + * @rx_desc: Advanced Rx descriptor + * @skb: The socket buffer holding the received data + * + * This function checks the Direct Data Placement (DDP) status for Fibre + * Channel over Ethernet (FCoE) frames and marks the DDP context as done. + * It verifies the DDP status, updates the length of DDPed data, and + * determines whether to pass the skb to the Upper Layer Driver (ULD). The + * function handles different FCoE statuses and errors, and returns the + * length of DDPed data if applicable. + * + * Return: < 0 indicates an error or not a FCoE DDP, 0 indicates not passing + * the skb to ULD, > 0 indicates the length of data being DDPed. + */ +int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + struct ixgbe_fcoe_ddp *ddp; + struct fc_frame_header *fh; + int rc = -EINVAL, ddp_max; + __le32 fcerr = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCERR); + __le32 ddp_err; + u32 fctl; + u16 xid; + + if (fcerr == cpu_to_le32(IXGBE_FCERR_BADCRC)) + skb->ip_summed = CHECKSUM_NONE; + else + skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* verify header contains at least the FCOE header */ + BUG_ON(skb_headlen(skb) < FCOE_HEADER_LEN); + + fh = (struct fc_frame_header *)(skb->data + sizeof(struct fcoe_hdr)); + + if (skb->protocol == htons(ETH_P_8021Q)) + fh = (struct fc_frame_header *)((char *)fh + VLAN_HLEN); + + fctl = ntoh24(fh->fh_f_ctl); + if (fctl & FC_FC_EX_CTX) + xid = ntohs(fh->fh_ox_id); + else + xid = ntohs(fh->fh_rx_id); + + ddp_max = IXGBE_FCOE_DDP_MAX; + /* X550 has different DDP Max limit */ + if (adapter->hw.mac.type == ixgbe_mac_X550) + ddp_max = IXGBE_FCOE_DDP_MAX_X550; + + if (xid >= ddp_max) + goto ddp_out; + + ddp = &fcoe->ddp[xid]; + if (!ddp->udl) + goto ddp_out; + + ddp_err = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCEOFE | + IXGBE_RXDADV_ERR_FCERR); + if (ddp_err) + goto ddp_out; + + switch (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_FCSTAT)) { + /* return 0 to bypass going to ULD for DDPed data */ + case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_DDP): + /* update length of DDPed data */ + ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); + rc = 0; + break; + /* unmap the sg list when FCPRSP is received */ + case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_FCPRSP): + dma_unmap_sg(ixgbe_pf_to_dev(adapter), ddp->sgl, + ddp->sgc, DMA_FROM_DEVICE); + ddp->err = ddp_err; + ddp->sgl = NULL; + ddp->sgc = 0; + fallthrough; + /* if DDP length is present pass it through to ULD */ + case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NODDP): + /* update length of DDPed data */ + ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); + if (ddp->len) + rc = ddp->len; + break; + /* no match will return as an error */ + case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NOMTCH): + default: + break; + } + + /* In target mode, check the last data frame of the sequence. + * For DDP in target mode, data is already DDPed but the header + * indication of the last data frame ould allow is to tell if we + * got all the data and the ULP can send FCP_RSP back, as this is + * not a full fcoe frame, we fill the trailer here so it won't be + * dropped by the ULP stack. + */ + if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && + (fctl & FC_FC_END_SEQ)) { + struct fcoe_crc_eof *crc; + skb_linearize(skb); + crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); + crc->fcoe_eof = FC_EOF_T; + } +ddp_out: + return rc; +} + +/** + * ixgbe_fso - ixgbe FCoE Sequence Offload (FSO) + * @tx_ring: tx desc ring + * @first: first tx_buffer structure containing skb, tx_flags, and protocol + * @hdr_len: hdr_len to be returned + * + * This sets up large send offload for FCoE + * + * Returns : 0 indicates success, < 0 for error + */ +int ixgbe_fso(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, + u8 *hdr_len) +{ + struct sk_buff *skb = first->skb; + struct fc_frame_header *fh; + u32 vlan_macip_lens; + u32 fcoe_sof_eof = 0; + u32 mss_l4len_idx; + u8 sof, eof; + u32 type_tucmd = IXGBE_ADVTXT_TUCMD_FCOE; + +#ifdef NETIF_F_FSO + if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type != SKB_GSO_FCOE) { + dev_err(tx_ring->dev, "Wrong gso type %d:expecting " + "SKB_GSO_FCOE\n", skb_shinfo(skb)->gso_type); + return -EINVAL; + } + +#endif + /* resets the header to point fcoe/fc */ + skb_set_network_header(skb, skb->mac_len); + skb_set_transport_header(skb, skb->mac_len + + sizeof(struct fcoe_hdr)); + + /* sets up SOF and ORIS */ + sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof; + switch (sof) { + case FC_SOF_I2: + fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_ORIS; + break; + case FC_SOF_I3: + fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF | + IXGBE_ADVTXD_FCOEF_ORIS; + break; + case FC_SOF_N2: + break; + case FC_SOF_N3: + fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF; + break; + default: + dev_warn(tx_ring->dev, "unknown sof = 0x%x\n", sof); + return -EINVAL; + } + + /* the first byte of the last dword is EOF */ + skb_copy_bits(skb, skb->len - 4, &eof, 1); + /* sets up EOF and ORIE */ + switch (eof) { + case FC_EOF_N: + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N; + break; + case FC_EOF_T: + /* lso needs ORIE */ + if (skb_is_gso(skb)) + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N | + IXGBE_ADVTXD_FCOEF_ORIE; + else + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T; + break; + case FC_EOF_NI: + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI; + break; + case FC_EOF_A: + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A; + break; + default: + dev_warn(tx_ring->dev, "unknown eof = 0x%x\n", eof); + return -EINVAL; + } + + /* sets up PARINC indicating data offset */ + fh = (struct fc_frame_header *)skb_transport_header(skb); + if (fh->fh_f_ctl[2] & FC_FC_REL_OFF) + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC; + + /* include trailer in headlen as it is replicated per frame */ + *hdr_len = sizeof(struct fcoe_crc_eof); + + /* hdr_len includes fc_hdr if FCoE LSO is enabled */ + if (skb_is_gso(skb)) { + *hdr_len += skb_transport_offset(skb) + + sizeof(struct fc_frame_header); + /* update gso_segs and bytecount */ + first->gso_segs = DIV_ROUND_UP(skb->len - *hdr_len, + skb_shinfo(skb)->gso_size); + first->bytecount += (first->gso_segs - 1) * *hdr_len; + first->tx_flags |= IXGBE_TX_FLAGS_TSO; + /* Hardware expects L4T to be RSV for FCoE TSO */ + type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_RSV; + } + + /* set flag indicating FCOE to ixgbe_tx_map call */ + first->tx_flags |= IXGBE_TX_FLAGS_FCOE | IXGBE_TX_FLAGS_CC; + + /* mss_l4len_id: use 0 for FSO as TSO, no need for L4LEN */ + mss_l4len_idx = skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT; + + /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */ + vlan_macip_lens = skb_transport_offset(skb) + + sizeof(struct fc_frame_header); + vlan_macip_lens |= (skb_transport_offset(skb) - 4) + << IXGBE_ADVTXD_MACLEN_SHIFT; + vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; + + /* write context desc */ + ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fcoe_sof_eof, + type_tucmd, mss_l4len_idx); + + return 0; +} + +static void ixgbe_fcoe_dma_pool_free(struct ixgbe_fcoe *fcoe, unsigned int cpu) +{ + struct ixgbe_fcoe_ddp_pool *ddp_pool; + + ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu); + dma_pool_destroy(ddp_pool->pool); + ddp_pool->pool = NULL; +} + +static int ixgbe_fcoe_dma_pool_alloc(struct ixgbe_fcoe *fcoe, + struct device *dev, + unsigned int cpu) +{ + struct ixgbe_fcoe_ddp_pool *ddp_pool; + struct dma_pool *pool; + char pool_name[32]; + + snprintf(pool_name, 32, "ixgbe_fcoe_ddp_%d", cpu); + + pool = dma_pool_create(pool_name, dev, IXGBE_FCPTR_MAX, + IXGBE_FCPTR_ALIGN, PAGE_SIZE); + if (!pool) + return -ENOMEM; + + ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu); + ddp_pool->pool = pool; + ddp_pool->noddp = 0; + ddp_pool->noddp_ext_buff = 0; + + return 0; +} + +/** + * ixgbe_configure_fcoe - configures registers for fcoe at start + * @adapter: ptr to ixgbe adapter + * + * This sets up FCoE related registers + * + * Returns : none + */ +void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) +{ + struct ixgbe_ring_feature *fcoe = &adapter->ring_feature[RING_F_FCOE]; + struct ixgbe_hw *hw = &adapter->hw; + int i, fcoe_i; + u32 fcoe_q, fcoe_q_h = 0; + u32 etqf; + int fcreta_size; + + /* Minimal funcionality for FCoE requires at least CRC offloads */ + if (!(adapter->netdev->features & NETIF_F_FCOE_CRC)) + return; + + /* Enable L2 EtherType filter for FCoE, needed for FCoE CRC and DDP */ + etqf = ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN; + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + etqf |= IXGBE_ETQF_POOL_ENABLE; + etqf |= VMDQ_P(0) << IXGBE_ETQF_POOL_SHIFT; + } + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), etqf); + IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0); + + /* leave remaining registers unconfigued if FCoE is disabled */ + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return; + + /* Use one or more Rx queues for FCoE by redirection table */ + fcreta_size = IXGBE_FCRETA_SIZE; + if (adapter->hw.mac.type == ixgbe_mac_X550) + fcreta_size = IXGBE_FCRETA_SIZE_X550; + + for (i = 0; i < fcreta_size; i++) { + if (adapter->hw.mac.type == ixgbe_mac_X550) { + int fcoe_i_h = fcoe->offset + ((i + fcreta_size) % + fcoe->indices); + fcoe_q_h = adapter->rx_ring[fcoe_i_h]->reg_idx; + fcoe_q_h = (fcoe_q_h << IXGBE_FCRETA_ENTRY_HIGH_SHIFT) & + IXGBE_FCRETA_ENTRY_HIGH_MASK; + } + fcoe_i = fcoe->offset + (i % fcoe->indices); + if (fcoe_i >= MAX_RX_QUEUES) + fcoe_i = MAX_RX_QUEUES - 1; + fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx; + fcoe_q |= fcoe_q_h; + IXGBE_WRITE_REG(hw, IXGBE_FCRETA(i), fcoe_q); + } + IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA); + + /* Enable L2 EtherType filter for FIP */ + etqf = ETH_P_FIP | IXGBE_ETQF_FILTER_EN; + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + etqf |= IXGBE_ETQF_POOL_ENABLE; + etqf |= VMDQ_P(0) << IXGBE_ETQF_POOL_SHIFT; + } + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP), etqf); + + /* Send FIP frames to the first FCoE queue */ + fcoe_q = adapter->rx_ring[fcoe->offset]->reg_idx; + IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP), + IXGBE_ETQS_QUEUE_EN | + (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); + + /* Configure FCoE Rx control */ + IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, + IXGBE_FCRXCTRL_FCCRCBO | + (FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT)); +} + +/** + * ixgbe_free_fcoe_ddp_resources - release all fcoe ddp context resources + * @adapter : ixgbe adapter + * + * Cleans up outstanding ddp context resources + * + * Returns : none + */ +void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter) +{ + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + int cpu, i, ddp_max; + + /* do nothing if no DDP pools were allocated */ + if (!fcoe->ddp_pool) + return; + + ddp_max = IXGBE_FCOE_DDP_MAX; + /* X550 has different DDP Max limit */ + if (adapter->hw.mac.type == ixgbe_mac_X550) + ddp_max = IXGBE_FCOE_DDP_MAX_X550; + + for (i = 0; i < ddp_max; i++) + ixgbe_fcoe_ddp_put(adapter->netdev, i); + + for_each_possible_cpu(cpu) + ixgbe_fcoe_dma_pool_free(fcoe, cpu); + + dma_unmap_single(ixgbe_pf_to_dev(adapter), + fcoe->extra_ddp_buffer_dma, + IXGBE_FCBUFF_MIN, + DMA_FROM_DEVICE); + kfree(fcoe->extra_ddp_buffer); + + fcoe->extra_ddp_buffer = NULL; + fcoe->extra_ddp_buffer_dma = 0; +} + +/** + * ixgbe_setup_fcoe_ddp_resources - setup all fcoe ddp context resources + * @adapter: ixgbe adapter + * + * Sets up ddp context resouces + * + * Returns : 0 indicates success or -EINVAL on failure + */ +int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter) +{ + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + struct device *dev = ixgbe_pf_to_dev(adapter); + void *buffer; + dma_addr_t dma; + unsigned int cpu; + + /* do nothing if no DDP pools were allocated */ + if (!fcoe->ddp_pool) + return 0; + + /* Extra buffer to be shared by all DDPs for HW work around */ + buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_KERNEL); + if (!buffer) { + e_err(drv, "failed to allocate extra DDP buffer\n"); + return -ENOMEM; + } + + dma = dma_map_single(dev, buffer, IXGBE_FCBUFF_MIN, DMA_FROM_DEVICE); + if (dma_mapping_error(dev, dma)) { + e_err(drv, "failed to map extra DDP buffer\n"); + kfree(buffer); + return -ENOMEM; + } + + fcoe->extra_ddp_buffer = buffer; + fcoe->extra_ddp_buffer_dma = dma; + + /* allocate pci pool for each cpu */ + for_each_possible_cpu(cpu) { + int err = ixgbe_fcoe_dma_pool_alloc(fcoe, dev, cpu); + if (!err) + continue; + + e_err(drv, "failed to alloc DDP pool on cpu:%d\n", cpu); + ixgbe_free_fcoe_ddp_resources(adapter); + return -ENOMEM; + } + + return 0; +} + +#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE +int ixgbe_fcoe_ddp_enable(struct ixgbe_adapter *adapter) +#else +static int ixgbe_fcoe_ddp_enable(struct ixgbe_adapter *adapter) +#endif +{ + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + + if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) + return -EINVAL; + + fcoe->ddp_pool = alloc_percpu(struct ixgbe_fcoe_ddp_pool); + + if (!fcoe->ddp_pool) { + e_err(drv, "failed to allocate percpu DDP resources\n"); + return -ENOMEM; + } + + adapter->netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; + + /* X550 has different DDP Max limit */ + if (adapter->hw.mac.type == ixgbe_mac_X550) + adapter->netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX_X550 - 1; + + return 0; +} + +#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE +void ixgbe_fcoe_ddp_disable(struct ixgbe_adapter *adapter) +#else +static void ixgbe_fcoe_ddp_disable(struct ixgbe_adapter *adapter) +#endif +{ + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + + adapter->netdev->fcoe_ddp_xid = 0; + + if (!fcoe->ddp_pool) + return; + + free_percpu(fcoe->ddp_pool); + fcoe->ddp_pool = NULL; +} + +#ifdef HAVE_NETDEV_OPS_FCOE_ENABLE +/** + * ixgbe_fcoe_enable - Turn on FCoE offload feature + * @netdev: The corresponding network device + * + * This function enables the Fibre Channel over Ethernet (FCoE) offload + * feature on the ixgbe network adapter, specifically for the 82599 model. + * It increments the FCoE reference count, checks for FCoE capability, and + * ensures that FCoE is not already enabled. The function allocates memory + * for DDP pools, updates network device features, and reinitializes + * interrupt schemes. It returns an error if FCoE is not capable or already + * enabled. + * + * Return: 0 on success, or -EINVAL on failure. + */ +int ixgbe_fcoe_enable(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + + atomic_inc(&fcoe->refcnt); + + if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) + return -EINVAL; + + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) + return -EINVAL; + + e_info(drv, "Enabling FCoE offload features.\n"); + + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + e_warn(probe, "Enabling FCoE on PF will disable legacy VFs\n"); + + if (netif_running(netdev)) + netdev->netdev_ops->ndo_stop(netdev); + + /* Allocate per CPU memory to track DDP pools */ + ixgbe_fcoe_ddp_enable(adapter); + + /* enable FCoE and notify stack */ + adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; +#ifdef HAVE_NETDEV_FCOE_MTU + netdev->fcoe_mtu = true; +#else + netdev->features |= NETIF_F_FCOE_MTU; +#endif + netdev_features_change(netdev); + + /* release existing queues and reallocate them */ + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_init_interrupt_scheme(adapter); + + if (netif_running(netdev)) + netdev->netdev_ops->ndo_open(netdev); + + return 0; +} + +/** + * ixgbe_fcoe_disable - Turn off FCoE offload feature + * @netdev: The corresponding network device + * + * This function disables the Fibre Channel over Ethernet (FCoE) offload + * feature on the ixgbe network adapter, specifically for the 82599 model. + * It decrements the reference count for FCoE, stops the network device if + * it is running, and frees per-CPU memory used for tracking DDP pools. The + * function also updates the network device's features and reinitializes + * interrupt schemes. It returns an error if FCoE is not enabled or if the + * reference count is not zero. + * + * Return: 0 on success, or -EINVAL on failure. + */ +int ixgbe_fcoe_disable(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (!atomic_dec_and_test(&adapter->fcoe.refcnt)) + return -EINVAL; + + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return -EINVAL; + + e_info(drv, "Disabling FCoE offload features.\n"); + if (netif_running(netdev)) + netdev->netdev_ops->ndo_stop(netdev); + + /* Free per CPU memory to track DDP pools */ + ixgbe_fcoe_ddp_disable(adapter); + + /* disable FCoE and notify stack */ + adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; +#ifdef HAVE_NETDEV_FCOE_MTU + netdev->fcoe_mtu = false; +#else + netdev->features &= ~NETIF_F_FCOE_MTU; +#endif + + netdev_features_change(netdev); + + /* release existing queues and reallocate them */ + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_init_interrupt_scheme(adapter); + + if (netif_running(netdev)) + netdev->netdev_ops->ndo_open(netdev); + + return 0; +} +#endif /* HAVE_NETDEV_OPS_FCOE_ENABLE */ + +#if IS_ENABLED(CONFIG_DCB) +#ifdef HAVE_DCBNL_OPS_GETAPP +/** + * ixgbe_fcoe_getapp - retrieves current user priority bitmap for FCoE + * @netdev: the corresponding net_device + * + * Finds out the corresponding user priority bitmap from the current + * traffic class that FCoE belongs to. Returns 0 as the invalid user + * priority bitmap to indicate an error. + * + * Returns : 802.1p user priority bitmap for FCoE + */ +u8 ixgbe_fcoe_getapp(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + return 1 << adapter->fcoe.up; +} +#endif /* HAVE_DCBNL_OPS_GETAPP */ +#endif /* CONFIG_DCB */ +#ifdef HAVE_NETDEV_OPS_FCOE_GETWWN +/** + * ixgbe_fcoe_get_wwn - Get World Wide Name (WWN) for the node or port + * @netdev: The ixgbe network device + * @wwn: Pointer to store the World Wide Name + * @type: The type of World Wide Name (node or port) + * + * This function retrieves the World Wide Name (WWN) for either the node or + * the port of the ixgbe network adapter. It checks if both the prefix and + * the SAN MAC address are valid, and then forms the WWN based on the NAA-2 + * format for IEEE Extended name identifiers, as specified in the T10 FC-LS + * Specification, Section 15.3. The function returns an error if the prefix + * or SAN MAC address is invalid. + * + * Return: 0 on success, or -EINVAL on failure. + */ +int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) +{ + int rc = -EINVAL; + u16 prefix = 0xffff; + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_mac_info *mac = &adapter->hw.mac; + + switch (type) { + case NETDEV_FCOE_WWNN: + prefix = mac->wwnn_prefix; + break; + case NETDEV_FCOE_WWPN: + prefix = mac->wwpn_prefix; + break; + default: + break; + } + + if ((prefix != 0xffff) && + is_valid_ether_addr(mac->san_addr)) { + *wwn = ((u64) prefix << 48) | + ((u64) mac->san_addr[0] << 40) | + ((u64) mac->san_addr[1] << 32) | + ((u64) mac->san_addr[2] << 24) | + ((u64) mac->san_addr[3] << 16) | + ((u64) mac->san_addr[4] << 8) | + ((u64) mac->san_addr[5]); + rc = 0; + } + return rc; +} +#endif /* HAVE_NETDEV_OPS_FCOE_GETWWN */ + +/** + * ixgbe_fcoe_get_tc - Get the current Traffic Class (TC) for FCoE + * @adapter: Pointer to the device adapter structure + * + * This function retrieves the current Traffic Class (TC) that Fibre Channel + * over Ethernet (FCoE) is mapped to for the ixgbe network adapter. It uses + * the priority-to-TC mapping of the network device to determine the TC + * associated with the FCoE user priority (UP). + * + * Return: The Traffic Class (TC) that FCoE is mapped to. + */ +u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter) +{ + return netdev_get_prio_tc_map(adapter->netdev, adapter->fcoe.up); +} +#endif /* CONFIG_FCOE */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.h new file mode 100644 index 0000000000..ed631fac32 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fcoe.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_FCOE_H_ +#define _IXGBE_FCOE_H_ + +#if IS_ENABLED(CONFIG_FCOE) + +#include +#include + +/* shift bits within STAT fo FCSTAT */ +#define IXGBE_RXDADV_FCSTAT_SHIFT 4 + +/* ddp user buffer */ +#define IXGBE_BUFFCNT_MAX 256 /* 8 bits bufcnt */ +#define IXGBE_FCPTR_ALIGN 16 +#define IXGBE_FCPTR_MAX (IXGBE_BUFFCNT_MAX * sizeof(dma_addr_t)) +#define IXGBE_FCBUFF_4KB 0x0 +#define IXGBE_FCBUFF_8KB 0x1 +#define IXGBE_FCBUFF_16KB 0x2 +#define IXGBE_FCBUFF_64KB 0x3 +#define IXGBE_FCBUFF_MAX 65536 /* 64KB max */ +#define IXGBE_FCBUFF_MIN 4096 /* 4KB min */ +#define IXGBE_FCOE_DDP_MAX 512 /* 9 bits xid */ +#define IXGBE_FCOE_DDP_MAX_X550 2048 /* 11 bits xid */ + +/* Default user priority to use for FCoE */ +#define IXGBE_FCOE_DEFUP 3 + +/* fcerr */ +#define IXGBE_FCERR_BADCRC 0x00100000 +#define IXGBE_FCERR_EOFSOF 0x00200000 +#define IXGBE_FCERR_NOFIRST 0x00300000 +#define IXGBE_FCERR_OOOSEQ 0x00400000 +#define IXGBE_FCERR_NODMA 0x00500000 +#define IXGBE_FCERR_PKTLOST 0x00600000 + +/* FCoE DDP for target mode */ +#define __IXGBE_FCOE_TARGET 1 + +struct ixgbe_fcoe_ddp { + int len; + u32 err; + unsigned int sgc; + struct scatterlist *sgl; + dma_addr_t udp; + u64 *udl; + struct dma_pool *pool; +}; + +/* per cpu variables */ +struct ixgbe_fcoe_ddp_pool { + struct dma_pool *pool; + u64 noddp; + u64 noddp_ext_buff; +}; + +struct ixgbe_fcoe { + struct ixgbe_fcoe_ddp_pool __percpu *ddp_pool; + atomic_t refcnt; + spinlock_t lock; + struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX_X550]; + void *extra_ddp_buffer; + dma_addr_t extra_ddp_buffer_dma; + unsigned long mode; + u8 up; + u8 up_set; +}; +#endif /* CONFIG_FCOE */ + +#endif /* _IXGBE_FCOE_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.c new file mode 100644 index 0000000000..da45f4bc0c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.c @@ -0,0 +1,945 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#include +#include +#if IS_ENABLED(CONFIG_PLDMFW) +#include +#else +#include "kcompat_pldmfw.h" +#endif + +#include "ixgbe_fw_update.h" + +struct ixgbe_fwu_priv { + struct pldmfw context; + + struct ixgbe_adapter *adapter; + struct netlink_ext_ack *extack; + + /* Track which NVM banks to activate at the end of the update */ + u8 activate_flags; + + /* Track the firmware response of the required reset to complete the + * flash update. + * + * 0 - IXGBE_ACI_NVM_POR_FLAG - A full power on is required + * 1 - IXGBE_ACI_NVM_PERST_FLAG - A cold PCIe reset is required + * 2 - IXGBE_ACI_NVM_EMPR_FLAG - An EMP reset is required + */ + u8 reset_level; + + /* Track if EMP reset is available */ + u8 emp_reset_available; +}; + +/** + * ixgbe_send_package_data - Send record package data to firmware + * @context: PLDM fw update structure + * @data: pointer to the package data + * @length: length of the package data + * + * Send a copy of the package data associated with the PLDM record matching + * this device to the firmware. + * + * Note that this function sends an ACI command that will fail unless the + * NVM resource has been acquired. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_send_package_data(struct pldmfw *context, + const u8 *data, u16 length) +{ + struct ixgbe_fwu_priv *priv = container_of(context, + struct ixgbe_fwu_priv, + context); + struct netlink_ext_ack *extack = priv->extack; + struct ixgbe_adapter *adapter = priv->adapter; + struct ixgbe_hw *hw = &adapter->hw; + struct device *dev = context->dev; + u8 *package_data; + s32 status; + + dev_dbg(dev, "Sending PLDM record package data to firmware\n"); + + package_data = kmemdup(data, length, GFP_KERNEL); + if (!package_data) + return -ENOMEM; + + status = ixgbe_nvm_set_pkg_data(hw, false, package_data, length); + + kfree(package_data); + + if (status) { + dev_err(dev, + "Failed to send record package data to firmware, err %d aci_err %d\n", + status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to record package data to firmware"); + return -EIO; + } + + return 0; +} + +/** + * ixgbe_check_component_response - Report firmware response to a component + * @adapter: device private data structure + * @id: component id being checked + * @response: indicates whether this component can be updated + * @code: code indicating reason for response + * @extack: netlink extended ACK structure + * + * Check whether firmware indicates if this component can be updated. Report + * a suitable error message over the netlink extended ACK if the component + * cannot be updated. + * + * Return: 0 if the component can be updated, or -ECANCELED of the + * firmware indicates the component cannot be updated. + */ +static int ixgbe_check_component_response(struct ixgbe_adapter *adapter, + u16 id, u8 response, u8 code, + struct netlink_ext_ack *extack) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + const char *component; + + switch (id) { + case NVM_COMP_ID_OROM: + component = "fw.undi"; + break; + case NVM_COMP_ID_NVM: + component = "fw.mgmt"; + break; + case NVM_COMP_ID_NETLIST: + component = "fw.netlist"; + break; + default: + WARN(1, "Unexpected unknown component identifier 0x%02x", id); + return -EINVAL; + } + + dev_dbg(dev, "%s: firmware response 0x%x, code 0x%x\n", + component, response, code); + + switch (response) { + case IXGBE_ACI_NVM_PASS_COMP_CAN_BE_UPDATED: + /* firmware indicated this update is good to proceed */ + return 0; + case IXGBE_ACI_NVM_PASS_COMP_CAN_MAY_BE_UPDATEABLE: + dev_warn(dev, + "firmware recommends not updating %s, as it may result in a downgrade. Continuing anyways\n", + component); + return 0; + case IXGBE_ACI_NVM_PASS_COMP_CAN_NOT_BE_UPDATED: + dev_info(dev, "firmware has rejected updating %s\n", component); + break; + case IXGBE_ACI_NVM_PASS_COMP_PARTIAL_CHECK: + if (ixgbe_fw_recovery_mode(&adapter->hw)) + return 0; + break; + } + + switch (code) { + case IXGBE_ACI_NVM_PASS_COMP_STAMP_IDENTICAL_CODE: + dev_err(dev, + "Component comparison stamp for %s is identical to the running image\n", + component); + NL_SET_ERR_MSG_MOD(extack, + "Component comparison stamp is identical to running image"); + break; + case IXGBE_ACI_NVM_PASS_COMP_STAMP_LOWER: + dev_err(dev, + "Component comparison stamp for %s is lower than the running image\n", + component); + NL_SET_ERR_MSG_MOD(extack, + "Component comparison stamp is lower than running image"); + break; + case IXGBE_ACI_NVM_PASS_COMP_INVALID_STAMP_CODE: + dev_err(dev, + "Component comparison stamp for %s is invalid\n", + component); + NL_SET_ERR_MSG_MOD(extack, + "Component comparison stamp is invalid"); + break; + case IXGBE_ACI_NVM_PASS_COMP_CONFLICT_CODE: + dev_err(dev, + "%s conflicts with a previous component table\n", + component); + NL_SET_ERR_MSG_MOD(extack, + "Component table conflict occurred"); + break; + case IXGBE_ACI_NVM_PASS_COMP_PRE_REQ_NOT_MET_CODE: + dev_err(dev, + "Pre-requisites for component %s have not been met\n", + component); + NL_SET_ERR_MSG_MOD(extack, "Component pre-requisites not met"); + break; + case IXGBE_ACI_NVM_PASS_COMP_NOT_SUPPORTED_CODE: + dev_err(dev, "%s is not a supported component\n", + component); + NL_SET_ERR_MSG_MOD(extack, "Component not supported"); + break; + case IXGBE_ACI_NVM_PASS_COMP_CANNOT_DOWNGRADE_CODE: + dev_err(dev, + "Security restrictions prevent %s from being downgraded\n", + component); + NL_SET_ERR_MSG_MOD(extack, "Component cannot be downgraded"); + break; + case IXGBE_ACI_NVM_PASS_COMP_INCOMPLETE_IMAGE_CODE: + dev_err(dev, "Received an incomplete component image for %s\n", + component); + NL_SET_ERR_MSG_MOD(extack, "Incomplete component image"); + break; + case IXGBE_ACI_NVM_PASS_COMP_VER_STR_IDENTICAL_CODE: + dev_err(dev, + "Component version for %s is identical to the running image\n", + component); + NL_SET_ERR_MSG_MOD(extack, + "Component version is identical to running image"); + break; + case IXGBE_ACI_NVM_PASS_COMP_VER_STR_LOWER_CODE: + dev_err(dev, + "Component version for %s is lower than the running image\n", + component); + NL_SET_ERR_MSG_MOD(extack, + "Component version is lower than the running image"); + break; + default: + dev_err(dev, "Unexpected response code 0x02%x for %s\n", + code, component); + NL_SET_ERR_MSG_MOD(extack, + "Received unexpected response code from firmware"); + break; + } + + return -ECANCELED; +} + +/** + * ixgbe_send_component_table - Send PLDM component table to firmware + * @context: PLDM fw update structure + * @component: the component to process + * @transfer_flag: relative transfer order of this component + * + * Read relevant data from the component and forward it to the device + * firmware. Check the response to determine if the firmware indicates that + * the update can proceed. + * + * Send ACI commands related to the NVM, and assume + * the NVM resource has been acquired. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_send_component_table(struct pldmfw *context, + struct pldmfw_component *component, + u8 transfer_flag) +{ + struct ixgbe_fwu_priv *priv = container_of(context, + struct ixgbe_fwu_priv, + context); + struct ixgbe_adapter *adapter = priv->adapter; + struct netlink_ext_ack *extack = priv->extack; + struct ixgbe_aci_cmd_nvm_comp_tbl *comp_tbl; + u8 comp_response, comp_response_code; + struct ixgbe_hw *hw = &adapter->hw; + struct device *dev = context->dev; + size_t length; + s32 status; + + switch (component->identifier) { + case NVM_COMP_ID_OROM: + case NVM_COMP_ID_NVM: + case NVM_COMP_ID_NETLIST: + break; + default: + dev_err(dev, + "Unable to update due to a firmware component with unknown ID %u\n", + component->identifier); + NL_SET_ERR_MSG_MOD(extack, + "Unable to update due to unknown firmware component"); + return -EOPNOTSUPP; + } + + length = struct_size(comp_tbl, cvs, component->version_len); + comp_tbl = (struct ixgbe_aci_cmd_nvm_comp_tbl *) + ixgbe_malloc(hw, length); + if (!comp_tbl) + return -ENOMEM; + + comp_tbl->comp_class = cpu_to_le16(component->classification); + comp_tbl->comp_id = cpu_to_le16(component->identifier); + comp_tbl->comp_class_idx = FWU_COMP_CLASS_IDX_NOT_USE; + comp_tbl->comp_cmp_stamp = cpu_to_le32(component->comparison_stamp); + comp_tbl->cvs_type = component->version_type; + comp_tbl->cvs_len = component->version_len; + + memcpy(comp_tbl->cvs, component->version_string, + component->version_len); + + dev_dbg(dev, "Sending component table to firmware\n"); + + status = ixgbe_nvm_pass_component_tbl(hw, (u8 *)comp_tbl, length, + transfer_flag, &comp_response, + &comp_response_code); + + ixgbe_free(hw, comp_tbl); + + if (status) { + dev_err(dev, + "Failed to transfer component table to firmware, err %d\n", + status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to transfer component table to firmware"); + return -EIO; + } + + return ixgbe_check_component_response(adapter, + component->identifier, + comp_response, + comp_response_code, extack); +} + +/** + * ixgbe_write_one_nvm_block - Write an NVM block and await completion response + * @adapter: the PF data structure + * @module: the module to write to + * @offset: offset in bytes + * @block_size: size of the block to write, up to 4k + * @block: pointer to block of data to write + * @last_cmd: whether this is the last command + * @reset_level: storage for reset level required + * @extack: netlink extended ACK structure + * + * Write a block of data to a flash module, and await for the completion + * response message from firmware. + * + * Note this function assumes the caller has acquired the NVM resource. + * + * On successful return, reset level indicates the device reset required to + * complete the update. + * + * 0 - IXGBE_ACI_NVM_POR_FLAG - A full power on is required + * 1 - IXGBE_ACI_NVM_PERST_FLAG - A cold PCIe reset is required + * 2 - IXGBE_ACI_NVM_EMPR_FLAG - An EMP reset is required + * + * Return: 0 on success, or a negative error code on failure. + */ +int ixgbe_write_one_nvm_block(struct ixgbe_adapter *adapter, + u16 module, u32 offset, + u16 block_size, u8 *block, bool last_cmd, + u8 *reset_level, + struct netlink_ext_ack *extack) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + s32 status; + + dev_dbg(dev, "Writing block of %u bytes for module 0x%02x at offset %u\n", + block_size, module, offset); + status = ixgbe_aci_update_nvm(hw, module, offset, block_size, block, + last_cmd, 0); + if (status) { + dev_err(dev, "Failed to flash module 0x%02x with block of size %u at offset %u, err %d\n", + module, block_size, offset, status); + NL_SET_ERR_MSG_MOD(extack, "Failed to program flash module"); + return -EIO; + } + /* For the last command to write the NVM bank, newer versions of + * firmware indicate the required level of reset to complete + * activation of firmware. If the firmware supports this, cache the + * response for indicating to the user later. Otherwise, assume that + * a full power cycle is required. + */ + if (reset_level && last_cmd && module == E610_SR_1ST_NVM_BANK_PTR) { + if (hw->dev_caps.common_cap.pcie_reset_avoidance) { + *reset_level = IXGBE_ACI_NVM_RESET_LVL_M; + dev_dbg(dev, "Required reset level is %u\n", + *reset_level); + } else { + *reset_level = IXGBE_ACI_NVM_POR_FLAG; + dev_dbg(dev, "Firmware doesn't support indicating required reset level. Assuming a power cycle is required\n"); + } + } + + return 0; +} + +/** + * ixgbe_write_nvm_module - Write data to an NVM module + * @adapter: the PF driver structure + * @module: the module id to program + * @component: the name of the component being updated + * @image: buffer of image data to write to the NVM + * @length: length of the buffer + * @reset_level: storage for reset level required + * @extack: netlink extended ACK structure + * + * Loop over the data for a given NVM module and program it in 4 Kb + * blocks. Notify devlink core of progress after each block is programmed. + * Loops over a block of data and programs the NVM in 4k block chunks. + * + * Note this function assumes the caller has acquired the NVM resource. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_write_nvm_module(struct ixgbe_adapter *adapter, u16 module, + const char *component, const u8 *image, + u32 length, u8 *reset_level, + struct netlink_ext_ack *extack) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct devlink *devlink = adapter->devlink; + u32 offset = 0; + bool last_cmd; + u8 *block; + int err; + + dev_dbg(dev, "Beginning write of flash component '%s', module 0x%02x\n", + component, module); + + devlink_flash_update_status_notify(devlink, "Flashing", + component, 0, length); + + block = ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE); + if (!block) + return -ENOMEM; + + do { + u32 block_size; + + block_size = min_t(u32, IXGBE_ACI_MAX_BUFFER_SIZE, + length - offset); + last_cmd = !(offset + block_size < length); + + memcpy(block, image + offset, block_size); + + err = ixgbe_write_one_nvm_block(adapter, module, offset, + block_size, block, last_cmd, + reset_level, extack); + if (err) + break; + + offset += block_size; + + devlink_flash_update_status_notify(devlink, "Flashing", + component, offset, length); + } while (!last_cmd); + + dev_dbg(dev, "Completed write of flash component '%s' module 0x%02x\n", + component, module); + + if (err) + devlink_flash_update_status_notify(devlink, "Flashing failed", + component, length, length); + else + devlink_flash_update_status_notify(devlink, "Flashing done", + component, length, length); + + ixgbe_free(hw, block); + + return err; +} + +/* Length in seconds to wait before timing out when erasing a flash module. + * Yes, erasing really can take minutes to complete. + */ +#define IXGBE_FW_ERASE_TIMEOUT 300 + +/** + * ixgbe_erase_nvm_module - Erase an NVM module and await firmware completion + * @adapter: the PF data structure + * @module: the module to erase + * @component: name of the component being updated + * @extack: netlink extended ACK structure + * + * Erase the inactive NVM bank associated with this module, and await for + * a completion response message from firmware. + * + * Note this function assumes the caller has acquired the NVM resource. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_erase_nvm_module(struct ixgbe_adapter *adapter, u16 module, + const char *component, + struct netlink_ext_ack *extack) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct devlink *devlink = adapter->devlink; + struct ixgbe_hw *hw = &adapter->hw; + s32 status; + int err; + + dev_dbg(dev, "Beginning erase of flash component '%s', module 0x%02x\n", + component, module); + + devlink_flash_update_timeout_notify(devlink, "Erasing", component, + IXGBE_FW_ERASE_TIMEOUT); + + status = ixgbe_aci_erase_nvm(hw, module); + if (status) { + dev_err(dev, "Failed to erase %s (module 0x%02x), err %d\n", + component, module, status); + NL_SET_ERR_MSG_MOD(extack, "Failed to erase flash module"); + err = -EIO; + + devlink_flash_update_status_notify(devlink, "Erasing failed", + component, 0, 0); + } else { + err = 0; + + devlink_flash_update_status_notify(devlink, "Erasing done", + component, 0, 0); + } + + return err; +} + +/** + * ixgbe_switch_flash_banks - Tell firmware to switch NVM banks + * @adapter: Pointer to the PF data structure + * @activate_flags: flags used for the activation command + * @emp_reset_available: on return, indicates if EMP reset is available + * @extack: netlink extended ACK structure + * + * Notify firmware to activate the newly written flash banks, and wait for the + * firmware response. + * + * Return: 0 on success or an error code on failure. + */ +static int ixgbe_switch_flash_banks(struct ixgbe_adapter *adapter, + u8 activate_flags, + u8 *emp_reset_available, + struct netlink_ext_ack *extack) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw *hw = &adapter->hw; + u8 response_flags; + s32 status; + + status = ixgbe_nvm_write_activate(hw, activate_flags, &response_flags); + if (status) { + dev_err(dev, "Failed to switch active flash banks, err %d\n", + status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to switch active flash banks"); + return -EIO; + } + /* Newer versions of firmware have support to indicate whether an EMP + * reset to reload firmware is available. For older firmware, EMP + * reset is always available. + */ + if (emp_reset_available) { + if (hw->dev_caps.common_cap.reset_restrict_support) { + *emp_reset_available = + response_flags & IXGBE_ACI_NVM_EMPR_ENA; + dev_dbg(dev, + "Firmware indicated that EMP reset is %s\n", + *emp_reset_available ? + "available" : "not available"); + } else { + *emp_reset_available = IXGBE_ACI_NVM_EMPR_ENA; + dev_dbg(dev, + "Firmware does not support restricting EMP reset availability\n"); + } + } + + return 0; +} + +/** + * ixgbe_flash_component - Flash a component of the NVM + * @context: PLDM fw update structure + * @component: the component table to program + * + * Program the flash contents for a given component. First, determine the + * module id. Then, erase the secondary bank for this module. Finally, write + * the contents of the component to the NVM. + * + * Note this function assumes the caller has acquired the NVM resource. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_flash_component(struct pldmfw *context, + struct pldmfw_component *component) +{ + struct ixgbe_fwu_priv *priv = container_of(context, + struct ixgbe_fwu_priv, + context); + struct netlink_ext_ack *extack = priv->extack; + struct ixgbe_adapter *adapter = priv->adapter; + const char *name; + u8 *reset_level; + u16 module; + int err; + u8 flag; + + switch (component->identifier) { + case NVM_COMP_ID_OROM: + module = E610_SR_1ST_OROM_BANK_PTR; + flag = IXGBE_ACI_NVM_ACTIV_SEL_OROM; + reset_level = NULL; + name = "fw.undi"; + break; + case NVM_COMP_ID_NVM: + module = E610_SR_1ST_NVM_BANK_PTR; + flag = IXGBE_ACI_NVM_ACTIV_SEL_NVM; + reset_level = &priv->reset_level; + name = "fw.mgmt"; + break; + case NVM_COMP_ID_NETLIST: + module = E610_SR_NETLIST_BANK_PTR; + flag = IXGBE_ACI_NVM_ACTIV_SEL_NETLIST; + reset_level = NULL; + name = "fw.netlist"; + break; + + default: + /* This should not trigger, since we check the id before + * sending the component table to firmware. + */ + WARN(1, "Unexpected unknown component identifier 0x%02x", + component->identifier); + return -EINVAL; + } + + /* Mark this component for activating at the end */ + priv->activate_flags |= flag; + + err = ixgbe_erase_nvm_module(adapter, module, name, extack); + if (err) + return err; + + return ixgbe_write_nvm_module(adapter, module, name, + component->component_data, + component->component_size, reset_level, + extack); +} + +/** + * ixgbe_finalize_update - Perform last steps to complete device update + * @context: PLDM fw update structure + * + * Called as the last step of the update process. Complete the update by + * telling the firmware to switch active banks, and perform a reset of + * configured. + * + * Return: 0 on success, or an error code on failure. + */ +static int ixgbe_finalize_update(struct pldmfw *context) +{ + struct ixgbe_fwu_priv *priv = container_of(context, + struct ixgbe_fwu_priv, + context); + struct ixgbe_adapter *adapter = priv->adapter; + struct netlink_ext_ack *extack = priv->extack; + struct devlink *devlink; + struct device *dev; + int err; + + /* Finally, notify firmware to activate the written NVM banks */ + err = ixgbe_switch_flash_banks(adapter, priv->activate_flags, + &priv->emp_reset_available, extack); + if (err) + return err; + + devlink = adapter->devlink; + dev = ixgbe_pf_to_dev(adapter); + + /* If the required reset is EMPR, but EMPR is disabled, report that + * a reboot is required instead. + */ + if (priv->reset_level == IXGBE_ACI_NVM_EMPR_FLAG && + !priv->emp_reset_available) { + dev_dbg(dev, + "Firmware indicated EMP reset as sufficient, but EMP reset is disabled\n"); + priv->reset_level = IXGBE_ACI_NVM_PERST_FLAG; + } + + switch (priv->reset_level) { + case IXGBE_ACI_NVM_EMPR_FLAG: + devlink_flash_update_status_notify(devlink, + "Activate new firmware by devlink reload", + NULL, 0, 0); + break; + case IXGBE_ACI_NVM_PERST_FLAG: + devlink_flash_update_status_notify(devlink, + "Activate new firmware by rebooting the system", + NULL, 0, 0); + break; + case IXGBE_ACI_NVM_POR_FLAG: + devlink_flash_update_status_notify(devlink, + "Activate new firmware by power cycling the system", + NULL, 0, 0); + break; + default: + devlink_flash_update_status_notify(devlink, + "Suggested is to activate new firmware by devlink reload, if it doesn't work then a power cycle is required", + NULL, 0, 0); + break; + } + + adapter->fw_emp_reset_disabled = !priv->emp_reset_available; + + return 0; +} + +static const struct pldmfw_ops ixgbe_fwu_ops_e610 = { + .match_record = &pldmfw_op_pci_match_record, + .send_package_data = &ixgbe_send_package_data, + .send_component_table = &ixgbe_send_component_table, + .flash_component = &ixgbe_flash_component, + .finalize_update = &ixgbe_finalize_update, +}; + +/** + * ixgbe_get_pending_updates - Check if the component has a pending update + * @adapter: the PF driver structure + * @pending: on return, bitmap of updates pending + * @extack: Netlink extended ACK + * + * Check if the device has any pending updates on any flash components. + * + * Return: 0 on success, or a negative error code on failure. + * Updates pending with the bitmap of pending updates. + */ +int ixgbe_get_pending_updates(struct ixgbe_adapter *adapter, u8 *pending, + struct netlink_ext_ack *extack) +{ + struct device *dev = ixgbe_pf_to_dev(adapter); + struct ixgbe_hw_dev_caps *dev_caps; + struct ixgbe_hw *hw = &adapter->hw; + s32 status; + + dev_caps = ixgbe_malloc(hw, sizeof(*dev_caps)); + if (!dev_caps) + return -ENOMEM; + + status = ixgbe_discover_dev_caps(hw, dev_caps); + if (status) { + NL_SET_ERR_MSG_MOD(extack, + "Unable to read device capabilities"); + ixgbe_free(hw, dev_caps); + return -EIO; + } + + *pending = 0; + + if (dev_caps->common_cap.nvm_update_pending_nvm) { + dev_info(dev, + "The fw.mgmt flash component has a pending update\n"); + *pending |= IXGBE_ACI_NVM_ACTIV_SEL_NVM; + } + + if (dev_caps->common_cap.nvm_update_pending_orom) { + dev_info(dev, + "The fw.undi flash component has a pending update\n"); + *pending |= IXGBE_ACI_NVM_ACTIV_SEL_OROM; + } + + if (dev_caps->common_cap.nvm_update_pending_netlist) { + dev_info(dev, + "The fw.netlist flash component has a pending update\n"); + *pending |= IXGBE_ACI_NVM_ACTIV_SEL_NETLIST; + } + + ixgbe_free(hw, dev_caps); + + return 0; +} + +/** + * ixgbe_cancel_pending_update - Cancel any pending update for a component + * @adapter: the PF driver structure + * @component: if not NULL, the name of the component being updated + * @extack: Netlink extended ACK structure + * + * Cancel any pending update for the specified component. If component is + * NULL, all device updates will be canceled. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int ixgbe_cancel_pending_update(struct ixgbe_adapter *adapter, + const char *component, + struct netlink_ext_ack *extack) +{ + struct devlink *devlink = adapter->devlink; + struct ixgbe_hw *hw = &adapter->hw; + s32 status; + u8 pending; + int err; + + err = ixgbe_get_pending_updates(adapter, &pending, extack); + if (err) + return err; + + /* If the flash_update request is for a specific component, ignore all + * of the other components. + */ + if (component) { + if (strcmp(component, "fw.mgmt") == 0) + pending &= IXGBE_ACI_NVM_ACTIV_SEL_NVM; + else if (strcmp(component, "fw.undi") == 0) + pending &= IXGBE_ACI_NVM_ACTIV_SEL_OROM; + else if (strcmp(component, "fw.netlist") == 0) + pending &= IXGBE_ACI_NVM_ACTIV_SEL_NETLIST; + else + WARN(1, "Unexpected flash component %s", component); + } + + /* There is no previous pending update, so this request may continue */ + if (!pending) + return 0; + + /* In order to allow overwriting a previous pending update, notify + * firmware to cancel that update by issuing the appropriate command. + */ + devlink_flash_update_status_notify(devlink, + "Canceling previous pending update", + component, 0, 0); + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); + if (status) { + dev_err(ixgbe_pf_to_dev(adapter), + "Failed to acquire device flash lock, err %d\n", + status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to acquire device flash lock"); + return -EIO; + } + + pending |= IXGBE_ACI_NVM_REVERT_LAST_ACTIV; + err = ixgbe_switch_flash_banks(adapter, pending, NULL, extack); + + ixgbe_release_nvm(hw); + + /* Since we've canceled the pending update, we no longer know if EMP + * reset is restricted. + */ + adapter->fw_emp_reset_disabled = false; + + return err; +} + +/** + * ixgbe_flash_pldm_image - Write a PLDM-formatted firmware image to the device + * @devlink: pointer to devlink associated with the device to update + * @params: devlink flash update parameters + * @extack: netlink extended ACK structure + * + * Parse the data for a given firmware file, verifying that it is a valid PLDM + * formatted image that matches this device. + * + * Extract the device record Package Data and Component Tables and send them + * to the firmware. Extract and write the flash data for each of the three + * main flash components, "fw.mgmt", "fw.undi", and "fw.netlist". Notify + * firmware once the data is written to the inactive banks. + * + * Return: 0 on success or a negative error code on failure. + */ +int ixgbe_flash_pldm_image(struct devlink *devlink, + struct devlink_flash_update_params *params, + struct netlink_ext_ack *extack) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_fwu_priv priv; +#ifndef HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FW + const struct firmware *fw; +#endif + struct ixgbe_hw *hw; + struct device *dev; + u8 preservation; + s32 status; + int err; + + adapter = *(struct ixgbe_adapter **)devlink_priv(devlink); + dev = ixgbe_pf_to_dev(adapter); + hw = &adapter->hw; + + switch (params->overwrite_mask) { + case 0: + /* preserve all settings and identifiers */ + preservation = IXGBE_ACI_NVM_PRESERVE_ALL; + break; + case DEVLINK_FLASH_OVERWRITE_SETTINGS: + /* overwrite settings, but preserve vital information such as + * device identifiers. + */ + preservation = IXGBE_ACI_NVM_PRESERVE_SELECTED; + break; + case (DEVLINK_FLASH_OVERWRITE_SETTINGS | + DEVLINK_FLASH_OVERWRITE_IDENTIFIERS): + /* overwrite both settings and identifiers, preserve nothing */ + preservation = IXGBE_ACI_NVM_NO_PRESERVATION; + break; + default: + NL_SET_ERR_MSG_MOD(extack, + "Requested overwrite mask is not supported"); + return -EOPNOTSUPP; + } + + if (!hw->dev_caps.common_cap.nvm_unified_update && + !ixgbe_fw_recovery_mode(hw)) { + NL_SET_ERR_MSG_MOD(extack, + "Current firmware does not support unified update"); + return -EOPNOTSUPP; + } + + memset(&priv, 0, sizeof(priv)); + + priv.context.ops = &ixgbe_fwu_ops_e610; + priv.context.dev = dev; + priv.extack = extack; + priv.adapter = adapter; + priv.activate_flags = preservation; + + devlink_flash_update_status_notify(devlink, + "Preparing to flash", NULL, 0, 0); + + err = ixgbe_cancel_pending_update(adapter, NULL, extack); + if (err) + return err; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); + if (status) { + dev_err(dev, + "Failed to acquire device flash lock, err %d aci_err %d\n", + status, hw->aci.last_status); + NL_SET_ERR_MSG_MOD(extack, + "Failed to acquire device flash lock"); + return -EIO; + } + +#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FW + err = pldmfw_flash_image(&priv.context, params->fw); +#else + err = request_firmware(&fw, params->file_name, dev); + if (err) { + NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk"); + ixgbe_release_nvm(hw); + return err; + } + + err = pldmfw_flash_image(&priv.context, fw); + + release_firmware(fw); +#endif + if (err == -ENOENT) { + dev_err(dev, + "Firmware image has no record matching this device\n"); + NL_SET_ERR_MSG_MOD(extack, + "Firmware image has no record matching this device"); + } else if (err) { + /* Do not set a generic extended ACK message here. A more + * specific message may already have been set by one of our + * ops. + */ + dev_err(dev, "Failed to flash PLDM image, err %d", err); + } + + ixgbe_release_nvm(hw); + + return err; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.h new file mode 100644 index 0000000000..c395a49438 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_fw_update.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_FW_UPDATE_H_ +#define _IXGBE_FW_UPDATE_H_ + +int ixgbe_flash_pldm_image(struct devlink *devlink, + struct devlink_flash_update_params *params, + struct netlink_ext_ack *extack); +int ixgbe_get_pending_updates(struct ixgbe_adapter *adapter, u8 *pending, + struct netlink_ext_ack *extack); +int ixgbe_write_one_nvm_block(struct ixgbe_adapter *adapter, + u16 module, u32 offset, + u16 block_size, u8 *block, bool last_cmd, + u8 *reset_level, + struct netlink_ext_ack *extack); + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_lib.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_lib.c new file mode 100644 index 0000000000..6758c864cf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_lib.c @@ -0,0 +1,1407 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" +#include "ixgbe_sriov.h" + +#ifdef HAVE_TX_MQ +/** + * ixgbe_cache_ring_dcb_vmdq - Descriptor ring to register mapping for VMDq + * @adapter: board private structure to initialize + * + * Cache the descriptor ring offsets for VMDq to the assigned rings. It + * will also try to cache the proper offsets if RSS/FCoE are enabled along + * with VMDq. + * + **/ +static bool ixgbe_cache_ring_dcb_vmdq(struct ixgbe_adapter *adapter) +{ +#if IS_ENABLED(CONFIG_FCOE) + struct ixgbe_ring_feature *fcoe = &adapter->ring_feature[RING_F_FCOE]; +#endif /* CONFIG_FCOE */ + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + int i; + u16 reg_idx; + u8 tcs = netdev_get_num_tc(adapter->netdev); + + /* verify we have DCB enabled before proceeding */ + if (tcs <= 1) + return false; + + /* verify we have VMDq enabled before proceeding */ + if (!(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)) + return false; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + /* + * The bits on the 82598 are reversed compared to the other + * adapters. The DCB bits are the higher order bits and the + * lower bits belong to the VMDq pool. In order to sort + * this out we have to swap the bits to get the correct layout + */ + for (i = 0; i < adapter->num_rx_queues; i++) { + reg_idx = ((i >> 3) | (i << 3)) & 0x3F; + adapter->rx_ring[i]->reg_idx = reg_idx; + } + for (i = 0; i < adapter->num_tx_queues; i++) { + reg_idx = ((i >> 4) | (i << 2)) & 0x1F; + adapter->tx_ring[i]->reg_idx = reg_idx; + } + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + /* start at VMDq register offset for SR-IOV enabled setups */ + reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask); + for (i = 0; i < adapter->num_rx_queues; i++, reg_idx++) { + /* If we are greater than indices move to next pool */ + if ((reg_idx & ~vmdq->mask) >= tcs) { + reg_idx = __ALIGN_MASK(reg_idx, ~vmdq->mask); + } + adapter->rx_ring[i]->reg_idx = reg_idx; + } + + reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask); + for (i = 0; i < adapter->num_tx_queues; i++, reg_idx++) { + /* If we are greater than indices move to next pool */ + if ((reg_idx & ~vmdq->mask) >= tcs) + reg_idx = __ALIGN_MASK(reg_idx, ~vmdq->mask); + adapter->tx_ring[i]->reg_idx = reg_idx; + } + + break; + default: + break; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* nothing to do if FCoE is disabled */ + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return true; + + /* The work is already done if the FCoE ring is shared */ + if (fcoe->offset < tcs) + return true; + + /* The FCoE rings exist separately, we need to move their reg_idx */ + if (fcoe->indices) { + u16 queues_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + u8 fcoe_tc = ixgbe_fcoe_get_tc(adapter); + + reg_idx = (vmdq->offset + vmdq->indices) * queues_per_pool; + for (i = fcoe->offset; i < adapter->num_rx_queues; i++) { + reg_idx = __ALIGN_MASK(reg_idx, ~vmdq->mask) + fcoe_tc; + adapter->rx_ring[i]->reg_idx = reg_idx; + reg_idx++; + } + + reg_idx = (vmdq->offset + vmdq->indices) * queues_per_pool; + for (i = fcoe->offset; i < adapter->num_tx_queues; i++) { + reg_idx = __ALIGN_MASK(reg_idx, ~vmdq->mask) + fcoe_tc; + adapter->tx_ring[i]->reg_idx = reg_idx; + reg_idx++; + } + } +#endif /* CONFIG_FCOE */ + + return true; +} + +/* ixgbe_get_first_reg_idx - Return first register index associated with ring */ +static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, + unsigned int *tx, unsigned int *rx) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct net_device *dev = adapter->netdev; + u8 num_tcs = netdev_get_num_tc(dev); + + *tx = 0; + *rx = 0; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + /* TxQs/TC: 4 RxQs/TC: 8 */ + *tx = tc << 2; /* 0, 4, 8, 12, 16, 20, 24, 28 */ + *rx = tc << 3; /* 0, 8, 16, 24, 32, 40, 48, 56 */ + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + if (num_tcs > 4) { + /* + * TCs : TC0/1 TC2/3 TC4-7 + * TxQs/TC: 32 16 8 + * RxQs/TC: 16 16 16 + */ + *rx = tc << 4; + if (tc < 3) + *tx = tc << 5; /* 0, 32, 64 */ + else if (tc < 5) + *tx = (tc + 2) << 4; /* 80, 96 */ + else + *tx = (tc + 8) << 3; /* 104, 112, 120 */ + } else { + /* + * TCs : TC0 TC1 TC2/3 + * TxQs/TC: 64 32 16 + * RxQs/TC: 32 32 32 + */ + *rx = tc << 5; + if (tc < 2) + *tx = tc << 6; /* 0, 64 */ + else + *tx = (tc + 4) << 4; /* 96, 112 */ + } + default: + break; + } +} + +/** + * ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB + * @adapter: board private structure to initialize + * + * Cache the descriptor ring offsets for DCB to the assigned rings. + * + **/ +static bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) +{ + int tc, offset, rss_i, i; + unsigned int tx_idx, rx_idx; + struct net_device *dev = adapter->netdev; + u8 num_tcs = netdev_get_num_tc(dev); + + if (num_tcs <= 1) + return false; + + rss_i = adapter->ring_feature[RING_F_RSS].indices; + + for (tc = 0, offset = 0; tc < num_tcs; tc++, offset += rss_i) { + ixgbe_get_first_reg_idx(adapter, tc, &tx_idx, &rx_idx); + for (i = 0; i < rss_i; i++, tx_idx++, rx_idx++) { + adapter->tx_ring[offset + i]->reg_idx = tx_idx; + adapter->rx_ring[offset + i]->reg_idx = rx_idx; + adapter->tx_ring[offset + i]->dcb_tc = tc; + adapter->rx_ring[offset + i]->dcb_tc = tc; + } + } + + return true; +} + +#endif /* HAVE_TX_MQ */ +/** + * ixgbe_cache_ring_vmdq - Descriptor ring to register mapping for VMDq + * @adapter: board private structure to initialize + * + * Cache the descriptor ring offsets for VMDq to the assigned rings. It + * will also try to cache the proper offsets if RSS/FCoE/SRIOV are enabled along + * with VMDq. + * + **/ +static bool ixgbe_cache_ring_vmdq(struct ixgbe_adapter *adapter) +{ +#if IS_ENABLED(CONFIG_FCOE) + struct ixgbe_ring_feature *fcoe = &adapter->ring_feature[RING_F_FCOE]; +#endif /* CONFIG_FCOE */ + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + struct ixgbe_ring_feature *rss = &adapter->ring_feature[RING_F_RSS]; + u16 reg_idx; + int i; + + /* only proceed if VMDq is enabled */ + if (!(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)) + return false; + + /* start at VMDq register offset for SR-IOV enabled setups */ + reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask); + for (i = 0; i < adapter->num_rx_queues; i++, reg_idx++) { +#if IS_ENABLED(CONFIG_FCOE) + /* Allow first FCoE queue to be mapped as RSS */ + if (fcoe->offset && (i > fcoe->offset)) + break; +#endif /* CONFIG_FCOE */ + /* If we are greater than indices move to next pool */ + if ((reg_idx & ~vmdq->mask) >= rss->indices) { + reg_idx = __ALIGN_MASK(reg_idx, ~vmdq->mask); + } + adapter->rx_ring[i]->reg_idx = reg_idx; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* FCoE uses a linear block of queues so just assigning 1:1 */ + for (; i < adapter->num_rx_queues; i++, reg_idx++) { + adapter->rx_ring[i]->reg_idx = reg_idx; + } +#endif /* CONFIG_FCOE */ + + reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask); + for (i = 0; i < adapter->num_tx_queues; i++, reg_idx++) { +#if IS_ENABLED(CONFIG_FCOE) + /* Allow first FCoE queue to be mapped as RSS */ + if (fcoe->offset && (i > fcoe->offset)) + break; +#endif + /* If we are greater than indices move to next pool */ + if ((reg_idx & rss->mask) >= rss->indices) + reg_idx = __ALIGN_MASK(reg_idx, ~vmdq->mask); + adapter->tx_ring[i]->reg_idx = reg_idx; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* FCoE uses a linear block of queues so just assigning 1:1 */ + for (; i < adapter->num_tx_queues; i++, reg_idx++) + adapter->tx_ring[i]->reg_idx = reg_idx; +#endif /* CONFIG_FCOE */ + + + return true; +} + +/** + * ixgbe_cache_ring_rss - Descriptor ring to register mapping for RSS + * @adapter: board private structure to initialize + * + * Cache the descriptor ring offsets for RSS, ATR, FCoE, and SR-IOV. + * + **/ +static bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) +{ + int i, reg_idx; + + for (i = 0; i < adapter->num_rx_queues; i++) { + adapter->rx_ring[i]->reg_idx = i; + } + for (i = 0, reg_idx = 0; i < adapter->num_tx_queues; i++, reg_idx++) + adapter->tx_ring[i]->reg_idx = reg_idx; + for (i = 0; i < adapter->num_xdp_queues; i++, reg_idx++) + adapter->xdp_ring[i]->reg_idx = reg_idx; + + return true; +} + +/** + * ixgbe_cache_ring_register - Descriptor ring to register mapping + * @adapter: board private structure to initialize + * + * Once we know the feature-set enabled for the device, we'll cache + * the register offset the descriptor ring is assigned to. + * + * Note, the order the various feature calls is important. It must start with + * the "most" features enabled at the same time, then trickle down to the + * least amount of features turned on at once. + **/ +static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) +{ +#ifdef HAVE_TX_MQ + if (ixgbe_cache_ring_dcb_vmdq(adapter)) + return; + + if (ixgbe_cache_ring_dcb(adapter)) + return; + +#endif + if (ixgbe_cache_ring_vmdq(adapter)) + return; + + ixgbe_cache_ring_rss(adapter); +} + +static int ixgbe_xdp_queues(struct ixgbe_adapter *adapter) +{ +#ifdef HAVE_XDP_SUPPORT + int queues = min_t(int, IXGBE_MAX_XDP_QS, nr_cpu_ids); + + return adapter->xdp_prog ? queues : 0; +#else + return 0; +#endif +} + +#define IXGBE_RSS_64Q_MASK 0x3F +#define IXGBE_RSS_16Q_MASK 0xF +#define IXGBE_RSS_8Q_MASK 0x7 +#define IXGBE_RSS_4Q_MASK 0x3 +#define IXGBE_RSS_2Q_MASK 0x1 +#define IXGBE_RSS_DISABLED_MASK 0x0 + +#ifdef HAVE_TX_MQ +/** + * ixgbe_set_dcb_vmdq_queues: Allocate queues for VMDq devices w/ DCB + * @adapter: board private structure to initialize + * + * When VMDq (Virtual Machine Devices queue) is enabled, allocate queues + * and VM pools where appropriate. Also assign queues based on DCB + * priorities and map accordingly.. + * + **/ +static bool ixgbe_set_dcb_vmdq_queues(struct ixgbe_adapter *adapter) +{ + int i; + u16 vmdq_i = adapter->ring_feature[RING_F_VMDQ].limit; + u16 vmdq_m = 0; +#if IS_ENABLED(CONFIG_FCOE) + u16 fcoe_i = 0; +#endif + u8 tcs = netdev_get_num_tc(adapter->netdev); + + /* verify we have DCB enabled before proceeding */ + if (tcs <= 1) + return false; + + /* verify we have VMDq enabled before proceeding */ + if (!(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)) + return false; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + /* 4 pools w/ 8TC per pool */ + vmdq_i = min_t(u16, vmdq_i, 4); + vmdq_m = 0x7; + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + + /* Add starting offset to total pool count */ + vmdq_i += adapter->ring_feature[RING_F_VMDQ].offset; + + /* 16 pools w/ 8 TC per pool */ + if (tcs > 4) { + vmdq_i = min_t(u16, vmdq_i, 16); + vmdq_m = IXGBE_82599_VMDQ_8Q_MASK; + /* 32 pools w/ 4 TC per pool */ + } else { + vmdq_i = min_t(u16, vmdq_i, 32); + vmdq_m = IXGBE_82599_VMDQ_4Q_MASK; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* queues in the remaining pools are available for FCoE */ + fcoe_i = (128 / __ALIGN_MASK(1, ~vmdq_m)) - vmdq_i; +#endif /* CONFIG_FCOE */ + + /* remove the starting offset from the pool count */ + vmdq_i -= adapter->ring_feature[RING_F_VMDQ].offset; + + break; + default: + /* unknown hardware, only support one pool w/ one queue */ + vmdq_i = 1; + tcs = 1; + break; + } + + /* save features for later use */ + adapter->ring_feature[RING_F_VMDQ].indices = vmdq_i; + adapter->ring_feature[RING_F_VMDQ].mask = vmdq_m; + + /* + * We do not support DCB, VMDq, and RSS all simultaneously + * so we will disable RSS since it is the lowest priority + */ + adapter->ring_feature[RING_F_RSS].indices = 1; + adapter->ring_feature[RING_F_RSS].mask = IXGBE_RSS_DISABLED_MASK; + + adapter->num_rx_pools = vmdq_i; + adapter->num_rx_queues_per_pool = tcs; + + adapter->num_tx_queues = vmdq_i * tcs; + adapter->num_xdp_queues = 0; + adapter->num_rx_queues = vmdq_i * tcs; + + /* disable ATR as it is not supported when VMDq is enabled */ + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + +#if IS_ENABLED(CONFIG_FCOE) + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + struct ixgbe_ring_feature *fcoe; + + fcoe = &adapter->ring_feature[RING_F_FCOE]; + + /* limit ourselves based on feature limits */ + fcoe_i = min_t(u16, fcoe_i, fcoe->limit); + + if (fcoe_i) { + /* alloc queues for FCoE separately */ + fcoe->indices = fcoe_i; + fcoe->offset = vmdq_i * tcs; + + /* add queues to adapter */ + adapter->num_tx_queues += fcoe_i; + adapter->num_rx_queues += fcoe_i; + } else if (tcs > 1) { + /* use queue belonging to FcoE TC */ + fcoe->indices = 1; + fcoe->offset = ixgbe_fcoe_get_tc(adapter); + } else { + adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; + + fcoe->indices = 0; + fcoe->offset = 0; + } + } +#endif /* CONFIG_FCOE */ + + /* configure TC to queue mapping */ + for (i = 0; i < tcs; i++) + netdev_set_tc_queue(adapter->netdev, i, 1, i); + + return true; +} + +/** + * ixgbe_set_dcb_queues: Allocate queues for a DCB-enabled device + * @adapter: board private structure to initialize + * + * When DCB (Data Center Bridging) is enabled, allocate queues for + * each traffic class. If multiqueue isn't available,then abort DCB + * initialization. + * + * This function handles all combinations of DCB, RSS, and FCoE. + * + **/ +static bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) +{ + struct net_device *dev = adapter->netdev; + struct ixgbe_ring_feature *f; + int rss_i, rss_m, i; + int tcs; + + /* Map queue offset and counts onto allocated tx queues */ + tcs = netdev_get_num_tc(dev); + + if (tcs <= 1) + return false; + + /* determine the upper limit for our current DCB mode */ +#ifndef HAVE_NETDEV_SELECT_QUEUE + rss_i = adapter->indices; +#else + rss_i = dev->num_tx_queues / tcs; +#endif + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + /* 8 TC w/ 4 queues per TC */ + rss_i = min_t(u16, rss_i, 4); + rss_m = IXGBE_RSS_4Q_MASK; + } else if (tcs > 4) { + /* 8 TC w/ 8 queues per TC */ + rss_i = min_t(u16, rss_i, 8); + rss_m = IXGBE_RSS_8Q_MASK; + } else { + /* 4 TC w/ 16 queues per TC */ + rss_i = min_t(u16, rss_i, 16); + rss_m = IXGBE_RSS_16Q_MASK; + } + + /* set RSS mask and indices */ + f = &adapter->ring_feature[RING_F_RSS]; + rss_i = min_t(u16, rss_i, f->limit); + f->indices = rss_i; + f->mask = rss_m; + + /* disable ATR as it is not supported when DCB is enabled */ + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + +#if IS_ENABLED(CONFIG_FCOE) + /* + * FCoE enabled queues require special configuration indexed + * by feature specific indices and mask. Here we map FCoE + * indices onto the DCB queue pairs allowing FCoE to own + * configuration later. + */ + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + u8 tc = ixgbe_fcoe_get_tc(adapter); + + f = &adapter->ring_feature[RING_F_FCOE]; + f->indices = min_t(u16, rss_i, f->limit); + f->offset = rss_i * tc; + } +#endif /* CONFIG_FCOE */ + + for (i = 0; i < tcs; i++) + netdev_set_tc_queue(dev, i, rss_i, rss_i * i); + + adapter->num_tx_queues = rss_i * tcs; + adapter->num_xdp_queues = 0; + adapter->num_rx_queues = rss_i * tcs; + + return true; +} + +#endif +/** + * ixgbe_set_vmdq_queues: Allocate queues for VMDq devices + * @adapter: board private structure to initialize + * + * When VMDq (Virtual Machine Devices queue) is enabled, allocate queues + * and VM pools where appropriate. If RSS is available, then also try and + * enable RSS and map accordingly. + * + **/ +static bool ixgbe_set_vmdq_queues(struct ixgbe_adapter *adapter) +{ + u16 vmdq_i = adapter->ring_feature[RING_F_VMDQ].limit; + u16 vmdq_m = 0; + u16 rss_i = adapter->ring_feature[RING_F_RSS].limit; + u16 rss_m = IXGBE_RSS_DISABLED_MASK; +#if IS_ENABLED(CONFIG_FCOE) + u16 fcoe_i = 0; +#endif + + /* only proceed if VMDq is enabled */ + if (!(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)) + return false; + + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + vmdq_i = min_t(u16, vmdq_i, 16); + /* 16 pool mode with 1 queue per pool */ + if ((vmdq_i > 4) || (rss_i == 1)) { + vmdq_m = 0x0F; + rss_i = 1; + /* 4 pool mode with 8 queue per pool */ + } else { + vmdq_m = 0x18; + rss_m = IXGBE_RSS_8Q_MASK; + rss_i = min_t(u16, rss_i, 8); + } + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + + /* Add starting offset to total pool count */ + vmdq_i += adapter->ring_feature[RING_F_VMDQ].offset; + + /* double check we are limited to maximum pools */ + vmdq_i = min_t(u16, IXGBE_MAX_VMDQ_INDICES, vmdq_i); + + /* 64 pool mode with 2 queues per pool */ + if (vmdq_i > 32) { + vmdq_m = IXGBE_82599_VMDQ_2Q_MASK; + rss_m = IXGBE_RSS_2Q_MASK; + rss_i = min_t(u16, rss_i, 2); + /* 32 pool mode with up to 4 queues per pool */ + } else { + vmdq_m = IXGBE_82599_VMDQ_4Q_MASK; + rss_m = IXGBE_RSS_4Q_MASK; + /* We can support 4, 2, or 1 queues */ + rss_i = (rss_i > 3) ? 4 : (rss_i > 1) ? 2 : 1; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* queues in the remaining pools are available for FCoE */ + fcoe_i = 128 - (vmdq_i * __ALIGN_MASK(1, ~vmdq_m)); +#endif + + /* remove the starting offset from the pool count */ + vmdq_i -= adapter->ring_feature[RING_F_VMDQ].offset; + + break; + default: + /* unknown hardware, support one pool w/ one queue */ + vmdq_i = 1; + rss_i = 1; + break; + } + + /* save features for later use */ + adapter->ring_feature[RING_F_VMDQ].indices = vmdq_i; + adapter->ring_feature[RING_F_VMDQ].mask = vmdq_m; + + /* limit RSS based on user input and save for later use */ + adapter->ring_feature[RING_F_RSS].indices = rss_i; + adapter->ring_feature[RING_F_RSS].mask = rss_m; + + adapter->num_rx_pools = vmdq_i; + adapter->num_rx_queues_per_pool = rss_i; + + adapter->num_rx_queues = vmdq_i * rss_i; +#ifdef HAVE_TX_MQ + adapter->num_tx_queues = vmdq_i * rss_i; +#else + adapter->num_tx_queues = vmdq_i; +#endif /* HAVE_TX_MQ */ + adapter->num_xdp_queues = 0; + + /* disable ATR as it is not supported when VMDq is enabled */ + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + +#if IS_ENABLED(CONFIG_FCOE) + /* + * FCoE can use rings from adjacent buffers to allow RSS + * like behavior. To account for this we need to add the + * FCoE indices to the total ring count. + */ + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + struct ixgbe_ring_feature *fcoe; + + fcoe = &adapter->ring_feature[RING_F_FCOE]; + + /* limit ourselves based on feature limits */ + fcoe_i = min_t(u16, fcoe_i, fcoe->limit); + + if (vmdq_i > 1 && fcoe_i) { + /* alloc queues for FCoE separately */ + fcoe->indices = fcoe_i; + fcoe->offset = vmdq_i * rss_i; + } else { + /* merge FCoE queues with RSS queues */ + fcoe_i = min_t(u16, fcoe_i + rss_i, num_online_cpus()); + + /* limit indices to rss_i if MSI-X is disabled */ + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) + fcoe_i = rss_i; + + /* attempt to reserve some queues for just FCoE */ + fcoe->indices = min_t(u16, fcoe_i, fcoe->limit); + fcoe->offset = fcoe_i - fcoe->indices; + fcoe_i -= rss_i; + } + + /* add queues to adapter */ + adapter->num_tx_queues += fcoe_i; + adapter->num_rx_queues += fcoe_i; + } +#endif /* CONFIG_FCOE */ + return true; +} + +/** + * ixgbe_set_rss_queues: Allocate queues for RSS + * @adapter: board private structure to initialize + * + * This is our "base" multiqueue mode. RSS (Receive Side Scaling) will try + * to allocate one Rx queue per CPU, and if available, one Tx queue per CPU. + * + **/ +static bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_ring_feature *f; + u16 rss_i; + + /* set mask for 16 queue limit of RSS */ + f = &adapter->ring_feature[RING_F_RSS]; + rss_i = f->limit; + + f->indices = rss_i; + if (hw->mac.type < ixgbe_mac_X550) + f->mask = IXGBE_RSS_16Q_MASK; + else + f->mask = IXGBE_RSS_64Q_MASK; + + /* disable ATR by default, it will be configured below */ + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + + /* + * Use Flow Director in addition to RSS to ensure the best + * distribution of flows across cores, even when an FDIR flow + * isn't matched. + */ + if (rss_i > 1 && adapter->atr_sample_rate) { + f = &adapter->ring_feature[RING_F_FDIR]; + + rss_i = f->indices = f->limit; + + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* + * FCoE can exist on the same rings as standard network traffic + * however it is preferred to avoid that if possible. In order + * to get the best performance we allocate as many FCoE queues + * as we can and we place them at the end of the ring array to + * avoid sharing queues with standard RSS on systems with 24 or + * more CPUs. + */ + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + struct net_device *dev = adapter->netdev; + u16 fcoe_i; + + f = &adapter->ring_feature[RING_F_FCOE]; + + /* merge FCoE queues with RSS queues */ + fcoe_i = min_t(u16, f->limit + rss_i, num_online_cpus()); + fcoe_i = min_t(u16, fcoe_i, dev->num_tx_queues); + + /* limit indices to rss_i if MSI-X is disabled */ + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) + fcoe_i = rss_i; + + /* attempt to reserve some queues for just FCoE */ + f->indices = min_t(u16, fcoe_i, f->limit); + f->offset = fcoe_i - f->indices; + rss_i = max_t(u16, fcoe_i, rss_i); + } +#endif /* CONFIG_FCOE */ + + adapter->num_rx_queues = rss_i; +#ifdef HAVE_TX_MQ + adapter->num_tx_queues = rss_i; +#endif + adapter->num_xdp_queues = ixgbe_xdp_queues(adapter); + + return true; +} + +/* + * ixgbe_set_num_queues: Allocate queues for device, feature dependent + * @adapter: board private structure to initialize + * + * This is the top level queue allocation routine. The order here is very + * important, starting with the "most" number of features turned on at once, + * and ending with the smallest set of features. This way large combinations + * can be allocated if they're turned on, and smaller combinations are the + * fallthrough conditions. + * + **/ +static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) +{ + /* Start with base case */ + adapter->num_rx_queues = 1; + adapter->num_tx_queues = 1; + adapter->num_xdp_queues = 0; + adapter->num_rx_pools = adapter->num_rx_queues; + adapter->num_rx_queues_per_pool = 1; + +#ifdef HAVE_TX_MQ + if (ixgbe_set_dcb_vmdq_queues(adapter)) + return; + + if (ixgbe_set_dcb_queues(adapter)) + return; + +#endif + if (ixgbe_set_vmdq_queues(adapter)) + return; + + ixgbe_set_rss_queues(adapter); +} + +/** + * ixgbe_acquire_msix_vectors - acquire MSI-X vectors + * @adapter: board private structure + * + * Attempts to acquire a suitable range of MSI-X vector interrupts. Will + * return a negative error code if unable to acquire MSI-X vectors for any + * reason. + */ +static int ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i, vectors, vector_threshold; + + if (!(adapter->flags & IXGBE_FLAG_MSIX_CAPABLE)) + return -EOPNOTSUPP; + + /* We start by asking for one vector per queue pair with XDP queues + * being stacked with TX queues. + */ + vectors = max(adapter->num_rx_queues, adapter->num_tx_queues); + vectors = max(vectors, adapter->num_xdp_queues); + + /* It is easy to be greedy for MSI-X vectors. However, it really + * doesn't do much good if we have a lot more vectors than CPUs. We'll + * be somewhat conservative and only ask for (roughly) the same number + * of vectors as there are CPUs. + */ + vectors = min_t(int, vectors, num_online_cpus()); + + /* Some vectors are necessary for non-queue interrupts */ + vectors += NON_Q_VECTORS; + + /* Hardware can only support a maximum of hw.mac->max_msix_vectors. + * With features such as RSS and VMDq, we can easily surpass the + * number of Rx and Tx descriptor queues supported by our device. + * Thus, we cap the maximum in the rare cases where the CPU count also + * exceeds our vector limit + */ + vectors = min_t(int, vectors, hw->mac.max_msix_vectors); + + /* We want a minimum of two MSI-X vectors for (1) a TxQ[0] + RxQ[0] + * handler, and (2) an Other (Link Status Change, etc.) handler. + */ + vector_threshold = MIN_MSIX_COUNT; + + adapter->msix_entries = kcalloc(vectors, + sizeof(struct msix_entry), + GFP_KERNEL); + if (!adapter->msix_entries) + return -ENOMEM; + + for (i = 0; i < vectors; i++) + adapter->msix_entries[i].entry = i; + + vectors = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, + vector_threshold, vectors); + + if (vectors < 0) { + /* A negative count of allocated vectors indicates an error in + * acquiring within the specified range of MSI-X vectors */ + e_dev_warn("Failed to allocate MSI-X interrupts. Err: %d\n", + vectors); + + adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; + kfree(adapter->msix_entries); + adapter->msix_entries = NULL; + + return vectors; + } + + /* we successfully allocated some number of vectors within our + * requested range. + */ + adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; + + /* Adjust for only the vectors we'll use, which is minimum + * of max_q_vectors, or the number of vectors we were allocated. + */ + vectors -= NON_Q_VECTORS; + adapter->num_q_vectors = min_t(int, vectors, adapter->max_q_vectors); + + return 0; +} + +static void ixgbe_add_ring(struct ixgbe_ring *ring, + struct ixgbe_ring_container *head) +{ + ring->next = head->ring; + head->ring = ring; + head->count++; +} + +/** + * ixgbe_alloc_q_vector - Allocate memory for a single interrupt vector + * @adapter: board private structure to initialize + * @v_count: q_vectors allocated on adapter, used for ring interleaving + * @v_idx: index of vector in adapter struct + * @txr_count: total number of Tx rings to allocate + * @txr_idx: index of first Tx ring to allocate + * @xdp_count: total number of XDP rings to allocate + * @xdp_idx: index of first XDP ring to allocate + * @rxr_count: total number of Rx rings to allocate + * @rxr_idx: index of first Rx ring to allocate + * + * We allocate one q_vector. If allocation fails we return -ENOMEM. + **/ +static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, + unsigned int v_count, unsigned int v_idx, + unsigned int txr_count, unsigned int txr_idx, + unsigned int xdp_count, unsigned int xdp_idx, + unsigned int rxr_count, unsigned int rxr_idx) +{ + struct ixgbe_q_vector *q_vector; + struct ixgbe_ring *ring; + int node = -1; +#ifdef HAVE_IRQ_AFFINITY_HINT + int cpu = -1; + u8 tcs = netdev_get_num_tc(adapter->netdev); +#endif + int ring_count; + + /* note this will allocate space for the ring structure as well! */ + ring_count = txr_count + rxr_count + xdp_count; + +#ifdef HAVE_IRQ_AFFINITY_HINT + /* customize cpu for Flow Director mapping */ + if ((tcs <= 1) && !(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)) { + u16 rss_i = adapter->ring_feature[RING_F_RSS].indices; + if (rss_i > 1 && adapter->atr_sample_rate) { + if (cpu_online(v_idx)) { + cpu = v_idx; + node = cpu_to_node(cpu); + } + } + } + +#endif + /* allocate q_vector and rings */ + q_vector = kzalloc_node(struct_size(q_vector, ring, ring_count), + GFP_KERNEL, node); + + if (!q_vector) + q_vector = kzalloc(struct_size(q_vector, ring, ring_count), + GFP_KERNEL); + if (!q_vector) + return -ENOMEM; + + /* setup affinity mask and node */ +#ifdef HAVE_IRQ_AFFINITY_HINT + if (cpu != -1) + cpumask_set_cpu(cpu, &q_vector->affinity_mask); +#endif + q_vector->node = node; + + /* initialize CPU for DCA */ + q_vector->cpu = -1; + + /* initialize NAPI */ + netif_napi_add(adapter->netdev, &q_vector->napi, ixgbe_poll); +#ifndef HAVE_NETIF_NAPI_ADD_CALLS_NAPI_HASH_ADD +#ifdef HAVE_NDO_BUSY_POLL + napi_hash_add(&q_vector->napi); +#endif +#endif + +#ifdef HAVE_NDO_BUSY_POLL + /* initialize busy poll */ + atomic_set(&q_vector->state, IXGBE_QV_STATE_DISABLE); + +#endif + /* tie q_vector and adapter together */ + adapter->q_vector[v_idx] = q_vector; + q_vector->adapter = adapter; + q_vector->v_idx = v_idx; + + /* initialize work limits */ + q_vector->tx.work_limit = adapter->tx_work_limit; + + /* Initialize setting for adaptive ITR */ + q_vector->tx.itr = IXGBE_ITR_ADAPTIVE_MAX_USECS | + IXGBE_ITR_ADAPTIVE_LATENCY; + q_vector->rx.itr = IXGBE_ITR_ADAPTIVE_MAX_USECS | + IXGBE_ITR_ADAPTIVE_LATENCY; + + /* intialize ITR */ + if (txr_count && !rxr_count) { + /* tx only vector */ + if (adapter->tx_itr_setting == 1) + q_vector->itr = IXGBE_12K_ITR; + else + q_vector->itr = adapter->tx_itr_setting; + } else { + /* rx or rx/tx vector */ + if (adapter->rx_itr_setting == 1) + q_vector->itr = IXGBE_20K_ITR; + else + q_vector->itr = adapter->rx_itr_setting; + } + + /* initialize pointer to rings */ + ring = q_vector->ring; + + while (txr_count) { + /* assign generic ring traits */ + ring->dev = ixgbe_pf_to_dev(adapter); + ring->netdev = adapter->netdev; + + /* configure backlink on ring */ + ring->q_vector = q_vector; + + /* update q_vector Tx values */ + ixgbe_add_ring(ring, &q_vector->tx); + + /* apply Tx specific ring traits */ + ring->count = adapter->tx_ring_count; + ring->queue_index = txr_idx; + + /* assign ring to adapter */ + adapter->tx_ring[txr_idx] = ring; + + /* update count and index */ + txr_count--; + txr_idx += v_count; + + /* push pointer to next ring */ + ring++; + } + + while (xdp_count) { + /* assign generic ring traits */ + ring->dev = &adapter->pdev->dev; + ring->netdev = adapter->netdev; + + /* configure backlink on ring */ + ring->q_vector = q_vector; + + /* update q_vector Tx values */ + ixgbe_add_ring(ring, &q_vector->tx); + + /* apply Tx specific ring traits */ + ring->count = adapter->tx_ring_count; + ring->queue_index = xdp_idx; + set_ring_xdp(ring); + + spin_lock_init(&ring->tx_lock); + + /* assign ring to adapter */ + adapter->xdp_ring[xdp_idx] = ring; + + /* update count and index */ + xdp_count--; + xdp_idx++; + + /* push pointer to next ring */ + ring++; + } + while (rxr_count) { + /* assign generic ring traits */ + ring->dev = ixgbe_pf_to_dev(adapter); + ring->netdev = adapter->netdev; + + /* configure backlink on ring */ + ring->q_vector = q_vector; + + /* update q_vector Rx values */ + ixgbe_add_ring(ring, &q_vector->rx); + + /* + * 82599 errata, UDP frames with a 0 checksum + * can be marked as checksum errors. + */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); + +#if IS_ENABLED(CONFIG_FCOE) + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + struct ixgbe_ring_feature *f; + f = &adapter->ring_feature[RING_F_FCOE]; + + if ((rxr_idx >= f->offset) && + (rxr_idx < f->offset + f->indices)) { + set_bit(__IXGBE_RX_FCOE, &ring->state); + } + } +#endif /* CONFIG_FCOE */ + + /* apply Rx specific ring traits */ + ring->count = adapter->rx_ring_count; + ring->queue_index = rxr_idx; + + /* assign ring to adapter */ + adapter->rx_ring[rxr_idx] = ring; + + /* update count and index */ + rxr_count--; + rxr_idx += v_count; + + /* push pointer to next ring */ + ring++; + } + +#ifdef HAVE_PTP_1588_CLOCK + /* Init PTP structures. */ + INIT_LIST_HEAD(&q_vector->ptp_skbs_e600); + spin_lock_init(&q_vector->ptp_skbs_lock_e600); + +#endif /* HAVE_PTP_1588_CLOCK */ + return 0; +} + +/** + * ixgbe_free_q_vector - Free memory allocated for specific interrupt vector + * @adapter: board private structure to initialize + * @v_idx: Index of vector to be freed + * + * This function frees the memory allocated to the q_vector. In addition if + * NAPI is enabled it will delete any references to the NAPI struct prior + * to freeing the q_vector. + **/ +static void ixgbe_free_q_vector(struct ixgbe_adapter *adapter, int v_idx) +{ + struct ixgbe_q_vector *q_vector = adapter->q_vector[v_idx]; + struct ixgbe_ring *ring; + + ixgbe_for_each_ring(ring, q_vector->tx) { + if (ring_is_xdp(ring)) + adapter->xdp_ring[ring->queue_index] = NULL; + else + adapter->tx_ring[ring->queue_index] = NULL; + } + + ixgbe_for_each_ring(ring, q_vector->rx) + adapter->rx_ring[ring->queue_index] = NULL; + + adapter->q_vector[v_idx] = NULL; +#ifdef HAVE_NDO_BUSY_POLL + napi_hash_del(&q_vector->napi); +#endif + netif_napi_del(&q_vector->napi); + kfree_rcu(q_vector, rcu); +} + +/** + * ixgbe_alloc_q_vectors - Allocate memory for interrupt vectors + * @adapter: board private structure to initialize + * + * We allocate one q_vector per queue interrupt. If allocation fails we + * return -ENOMEM. + **/ +static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) +{ + unsigned int q_vectors = adapter->num_q_vectors; + unsigned int rxr_remaining = adapter->num_rx_queues; + unsigned int txr_remaining = adapter->num_tx_queues; + unsigned int xdp_remaining = adapter->num_xdp_queues; + unsigned int rxr_idx = 0, txr_idx = 0, xdp_idx = 0, v_idx = 0; + int err; +#ifdef HAVE_AF_XDP_ZC_SUPPORT + int i; +#endif + + if (q_vectors >= (rxr_remaining + txr_remaining + xdp_remaining)) { + for (; rxr_remaining; v_idx++) { + err = ixgbe_alloc_q_vector(adapter, q_vectors, v_idx, + 0, 0, 0, 0, 1, rxr_idx); + if (err) + goto err_out; + + /* update counts and index */ + rxr_remaining--; + rxr_idx++; + } + } + + for (; v_idx < q_vectors; v_idx++) { + int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - v_idx); + int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - v_idx); + int xqpv = DIV_ROUND_UP(xdp_remaining, q_vectors - v_idx); + + err = ixgbe_alloc_q_vector(adapter, q_vectors, v_idx, + tqpv, txr_idx, + xqpv, xdp_idx, + rqpv, rxr_idx); + + if (err) + goto err_out; + + /* update counts and index */ + rxr_remaining -= rqpv; + txr_remaining -= tqpv; + xdp_remaining -= xqpv; + rxr_idx++; + txr_idx++; + xdp_idx += xqpv; + } + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + for (i = 0; i < adapter->num_rx_queues; i++) { + if (adapter->rx_ring[i]) + adapter->rx_ring[i]->ring_idx = i; + } + + for (i = 0; i < adapter->num_tx_queues; i++) { + if (adapter->tx_ring[i]) + adapter->tx_ring[i]->ring_idx = i; + } + + for (i = 0; i < adapter->num_xdp_queues; i++) { + if (adapter->xdp_ring[i]) + adapter->xdp_ring[i]->ring_idx = i; + } + +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ + return IXGBE_SUCCESS; + +err_out: + adapter->num_tx_queues = 0; + adapter->num_xdp_queues = 0; + adapter->num_rx_queues = 0; + adapter->num_q_vectors = 0; + + while (v_idx--) + ixgbe_free_q_vector(adapter, v_idx); + + return -ENOMEM; +} + +/** + * ixgbe_free_q_vectors - Free memory allocated for interrupt vectors + * @adapter: board private structure to initialize + * + * This function frees the memory allocated to the q_vectors. In addition if + * NAPI is enabled it will delete any references to the NAPI struct prior + * to freeing the q_vector. + **/ +static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter) +{ + int v_idx = adapter->num_q_vectors; + + adapter->num_tx_queues = 0; + adapter->num_xdp_queues = 0; + adapter->num_rx_queues = 0; + adapter->num_q_vectors = 0; + + while (v_idx--) + ixgbe_free_q_vector(adapter, v_idx); +} + +void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter) +{ + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; + pci_disable_msix(adapter->pdev); + kfree(adapter->msix_entries); + adapter->msix_entries = NULL; + } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { + adapter->flags &= ~IXGBE_FLAG_MSI_ENABLED; + pci_disable_msi(adapter->pdev); + } +} + +/** + * ixgbe_set_interrupt_capability - set MSI-X or MSI if supported + * @adapter: board private structure to initialize + * + * Attempt to configure the interrupts using the best available + * capabilities of the hardware and the kernel. + **/ +void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) +{ + int err; + + /* We will try to get MSI-X interrupts first */ + if (!ixgbe_acquire_msix_vectors(adapter)) + return; + + /* At this point, we do not have MSI-X capabilities. We need to + * reconfigure or disable various features which require MSI-X + * capability. + */ + + /* Disable DCB unless we only have a single traffic class */ + if (netdev_get_num_tc(adapter->netdev) > 1) { + e_dev_warn("Number of DCB TCs exceeds number of available queues. Disabling DCB support.\n"); + netdev_reset_tc(adapter->netdev); + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + + adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; + adapter->temp_dcb_cfg.pfc_mode_enable = false; + adapter->dcb_cfg.pfc_mode_enable = false; + } + + adapter->dcb_cfg.num_tcs.pg_tcs = 1; + adapter->dcb_cfg.num_tcs.pfc_tcs = 1; + + /* Disable VMDq support */ + e_dev_warn("Disabling VMQd support\n"); + adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED; + +#ifdef CONFIG_PCI_IOV + /* Disable SR-IOV support */ + e_dev_warn("Disabling SR-IOV support\n"); + ixgbe_disable_sriov(adapter); +#endif /* CONFIG_PCI_IOV */ + + /* Disable RSS */ + e_dev_warn("Disabling RSS support\n"); + adapter->ring_feature[RING_F_RSS].limit = 1; + + /* recalculate number of queues now that many features have been + * changed or disabled. + */ + ixgbe_set_num_queues(adapter); + adapter->num_q_vectors = 1; + + if (!(adapter->flags & IXGBE_FLAG_MSI_CAPABLE)) + return; + + err = pci_enable_msi(adapter->pdev); + if (err) + e_dev_warn("Failed to allocate MSI interrupt, falling back to legacy. Error: %d\n", + err); + else + adapter->flags |= IXGBE_FLAG_MSI_ENABLED; +} + +/** + * ixgbe_init_interrupt_scheme - Determine proper interrupt scheme + * @adapter: board private structure to initialize + * + * We determine which interrupt scheme to use based on... + * - Kernel support (MSI, MSI-X) + * - which can be user-defined (via MODULE_PARAM) + * - Hardware queue count (num_*_queues) + * - defined by miscellaneous hardware support/features (RSS, etc.) + **/ +int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) +{ + int err; + + /* Number of supported queues */ + ixgbe_set_num_queues(adapter); + + /* Set interrupt mode */ + ixgbe_set_interrupt_capability(adapter); + + /* Allocate memory for queues */ + err = ixgbe_alloc_q_vectors(adapter); + if (err) { + e_err(probe, "Unable to allocate memory for queue vectors\n"); + ixgbe_reset_interrupt_capability(adapter); + return err; + } + + ixgbe_cache_ring_register(adapter); + +#ifdef HAVE_XDP_SUPPORT + e_dev_info("Multiqueue %s: Rx Queue count = %u, Tx Queue count = %u XDP Queue count = %u\n", + (adapter->num_rx_queues > 1) ? "Enabled" : "Disabled", + adapter->num_rx_queues, adapter->num_tx_queues, + adapter->num_xdp_queues); +#else + e_dev_info("Multiqueue %s: Rx Queue count = %u, Tx Queue count = %u\n", + (adapter->num_rx_queues > 1) ? "Enabled" : "Disabled", + adapter->num_rx_queues, adapter->num_tx_queues); +#endif + set_bit(__IXGBE_DOWN, adapter->state); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings + * @adapter: board private structure to clear interrupt scheme on + * + * We go through and clear interrupt specific resources and reset the structure + * to pre-load conditions + **/ +void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) +{ + adapter->num_tx_queues = 0; + adapter->num_xdp_queues = 0; + adapter->num_rx_queues = 0; + + ixgbe_free_q_vectors(adapter); + ixgbe_reset_interrupt_capability(adapter); +} + +void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens, + u32 fcoe_sof_eof, u32 type_tucmd, u32 mss_l4len_idx) +{ + struct ixgbe_adv_tx_context_desc *context_desc; + u16 i = tx_ring->next_to_use; + + context_desc = IXGBE_TX_CTXTDESC(tx_ring, i); + + i++; + tx_ring->next_to_use = (i < tx_ring->count) ? i : 0; + + /* set bits to identify this as an advanced context descriptor */ + type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT; + + context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); + context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof); + context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd); + context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_main.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_main.c new file mode 100644 index 0000000000..ff4e305b1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_main.c @@ -0,0 +1,15931 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/****************************************************************************** + Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code +******************************************************************************/ +#include "ixgbe.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NETIF_F_TSO +#include +#ifdef NETIF_F_TSO6 +#include +#include +#endif /* NETIF_F_TSO6 */ +#endif /* NETIF_F_TSO */ +#ifdef SIOCETHTOOL +#include +#endif + +#include +#include "kcompat_generated_defs.h" +#ifdef HAVE_XDP_SUPPORT +#include +#include +#include +#endif +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +#include +#else +#include +#endif +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#ifdef HAVE_UDP_ENC_RX_OFFLOAD +#include +#include +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ +#ifdef HAVE_VXLAN_RX_OFFLOAD +#include +#endif /* HAVE_VXLAN_RX_OFFLOAD */ +#ifdef NETIF_F_HW_TC +#include +#include +#include +#endif /* NETIF_F_HW_TC */ + + +#include "ixgbe_devlink.h" +#include "ixgbe_dcb_82599.h" +#include "ixgbe_sriov.h" +#include "ixgbe_txrx_common.h" +#ifdef HAVE_TC_SETUP_CLSU32 +#include "ixgbe_model.h" +#endif /* HAVE_TC_SETUP_CLSU32 */ +#ifdef HAVE_PTP_1588_CLOCK +#include "ixgbe_ptp_e600.h" +#endif /* HAVE_PTP_1588_CLOCK */ + +#define DRV_HW_PERF + +#define FPGA + +#define DRIVERIOV + +#define BYPASS_TAG + +#define RELEASE_TAG + +#define DRV_VERSION "6.3.6" \ + DRIVERIOV DRV_HW_PERF FPGA \ + BYPASS_TAG RELEASE_TAG +#define DRV_SUMMARY "Intel(R) 10GbE PCI Express Linux Network Driver" +const char ixgbe_driver_version[] = DRV_VERSION; +#ifdef HAVE_NON_CONST_PCI_DRIVER_NAME +char ixgbe_driver_name[] = "ixgbe"; +#else +const char ixgbe_driver_name[] = "ixgbe"; +#endif +static const char ixgbe_driver_string[] = DRV_SUMMARY; +static const char ixgbe_copyright[] = "Copyright (C) 1999 - 2026 Intel Corporation"; +static const char ixgbe_overheat_msg[] = + "Network adapter has been stopped because it has over heated. " + "Restart the computer. If the problem persists, " + "power off the system and replace the adapter"; + +/* ixgbe_pci_tbl - PCI Device ID Table + * + * Wildcard entries (PCI_ANY_ID) should come last + * Last entry must be all 0s + * + * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, + * Class, Class Mask, private data (not used) } + */ +static const struct pci_device_id ixgbe_pci_tbl[] = { + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT2), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_DA_DUAL_PORT), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KR), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_EM), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_BACKPLANE_FCOE), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_FCOE), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_QSFP_SF_QP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T1), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550T1), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KX4), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_XFI), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KR), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_SFP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_10G_T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_1G_T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_KR), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_KR_L), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SFP_N), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SGMII), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SGMII_L), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_10G_T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_QSFP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_QSFP_N), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SFP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_1G_T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_1G_T_L), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_E610_BACKPLANE), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_E610_SFP), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_E610_10G_T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_E610_2_5G_T), 0}, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_E610_SGMII), 0}, + /* required last entry */ + { .device = 0 } +}; +MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); + +#if IS_ENABLED(CONFIG_DCA) +static int ixgbe_notify_dca(struct notifier_block *, unsigned long event, + void *p); +static struct notifier_block dca_notifier = { + .notifier_call = ixgbe_notify_dca, + .next = NULL, + .priority = 0 +}; +#endif /* CONFIG_DCA */ +static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *); +static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *); +static void ixgbe_watchdog_update_link(struct ixgbe_adapter *); + +MODULE_AUTHOR("Intel Corporation, "); +MODULE_DESCRIPTION(DRV_SUMMARY); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +DEFINE_STATIC_KEY_FALSE(ixgbe_xdp_locking_key); +EXPORT_SYMBOL(ixgbe_xdp_locking_key); + +#define DEFAULT_DEBUG_LEVEL_SHIFT 3 + +static ushort fwlog_method = IXGBE_FWLOG_METHOD_ARQ; +module_param(fwlog_method, ushort, 0644); +MODULE_PARM_DESC(fwlog_method, "FW event logging method. 0=ARQ event logging, 1=UART event logging\n"); + +static struct workqueue_struct *ixgbe_wq; + +static bool ixgbe_is_sfp(struct ixgbe_hw *hw); +static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev); + +static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_hw *hw, + u32 reg, u16 *value) +{ + struct ixgbe_adapter *adapter = hw->back; + struct pci_dev *parent_dev; + struct pci_bus *parent_bus; + int pos; + + parent_bus = adapter->pdev->bus->parent; + if (!parent_bus) + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + + parent_dev = parent_bus->self; + if (!parent_dev) + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + + pos = pci_find_capability(parent_dev, PCI_CAP_ID_EXP); + if (!pos) + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + + pci_read_config_word(parent_dev, pos + reg, value); + if (*value == IXGBE_FAILED_READ_CFG_WORD && + ixgbe_check_cfg_remove(hw, parent_dev)) + return IXGBE_ERR_FEATURE_NOT_SUPPORTED; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_parent_bus_info - Set PCI bus info for devices behind a switch + * @hw: Pointer to the hardware structure + * + * This function sets the PCI bus information, including speed, width, and + * type, within the ixgbe_hw structure for devices located behind a switch. + * It retrieves the negotiated link width and speed from the PCI configuration + * space of the parent device. If the read operation fails, it falls back to + * default values. + * + * Return: IXGBE_SUCCESS on successful execution. + */ +static s32 ixgbe_get_parent_bus_info(struct ixgbe_hw *hw) +{ + u16 link_status = 0; + int err; + + hw->bus.type = ixgbe_bus_type_pci_express; + + /* Get the negotiated link width and speed from PCI config space of the + * parent, as this device is behind a switch + */ + err = ixgbe_read_pci_cfg_word_parent(hw, 18, &link_status); + + /* If the read fails, fallback to default */ + if (err) + link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); + + ixgbe_set_pci_config_data_generic(hw, link_status); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_pcie_from_parent - determine whether to use parent for PCIe info + * @hw: hw specific details + * + * This function is used by probe to determine whether a device's PCIe info + * (speed, width, etc) should be obtained from the parent bus or directly. This + * is useful for specialized device configurations containing PCIe bridges. + */ +static inline bool ixgbe_pcie_from_parent(struct ixgbe_hw *hw) +{ + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_QSFP_SF_QP: + case IXGBE_DEV_ID_82599_SFP_SF_QP: + return true; + default: + return false; + } +} + +static void ixgbe_check_minimum_link(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct pci_dev *pdev; + + /* Some devices are not connected over PCIe and thus do not negotiate + * speed. These devices do not have valid bus info, and thus any report + * we generate may not be correct. + */ + if (hw->bus.type == ixgbe_bus_type_internal) + return; + + /* determine whether to use the parent device */ + if (ixgbe_pcie_from_parent(&adapter->hw)) + pdev = adapter->pdev->bus->parent->self; + else + pdev = adapter->pdev; + + pcie_print_link_status(pdev); +} + +/** + * ixgbe_enumerate_functions - Determine the number of ports on the device + * @adapter: Pointer to the adapter structure + * + * This function enumerates the physical functions co-located on a single slot + * to determine the number of ports a device has. This information is useful + * for assessing the PCIe bandwidth required for optimal performance. The + * function handles cases where devices are behind a parent switch by using a + * hardcoded number of ports. It also accounts for virtual functions and + * mismatched device IDs, returning -1 if the number of functions cannot be + * reliably determined. + * + * Return: Number of physical functions (ports) on success, or -1 if the + * number cannot be determined. + */ +static inline int ixgbe_enumerate_functions(struct ixgbe_adapter *adapter) +{ + struct pci_dev *entry, *pdev = adapter->pdev; + int physfns = 0; + + /* Some cards can not use the generic count PCIe functions method, + * because they are behind a parent switch, so we hardcode these to + * correct number of ports. + */ + if (ixgbe_pcie_from_parent(&adapter->hw)) { + physfns = 4; + } else { + list_for_each_entry(entry, &pdev->bus->devices, bus_list) { +#ifdef CONFIG_PCI_IOV + /* don't count virtual functions */ + if (entry->is_virtfn) + continue; +#endif + + /* When the devices on the bus don't all match our device ID, + * we can't reliably determine the correct number of + * functions. This can occur if a function has been direct + * attached to a virtual machine using VT-d, for example. In + * this case, simply return -1 to indicate this. + */ + if ((entry->vendor != pdev->vendor) || + (entry->device != pdev->device)) + return -1; + + physfns++; + } + } + + return physfns; +} + +static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter) +{ + if (!test_bit(__IXGBE_DOWN, adapter->state) && + !test_bit(__IXGBE_REMOVING, adapter->state) && + !test_and_set_bit(__IXGBE_SERVICE_SCHED, adapter->state)) + queue_work(ixgbe_wq, &adapter->service_task); +} + +static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter) +{ + /* In case something went really wrong with scheduling, trigger BUG. */ + BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, adapter->state)); + + /* flush memory to make sure state is correct before next watchog */ + smp_mb__before_atomic(); + clear_bit(__IXGBE_SERVICE_SCHED, adapter->state); +} + +static void ixgbe_remove_adapter(struct ixgbe_hw *hw) +{ + struct ixgbe_adapter *adapter = hw->back; + + if (!hw->hw_addr) + return; + hw->hw_addr = NULL; + e_dev_err("Adapter removed\n"); + if (test_bit(__IXGBE_SERVICE_INITED, adapter->state)) + ixgbe_service_event_schedule(adapter); +} + +static u32 +ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg) +{ + u8 __iomem *reg_addr; + u32 value; + int i; + + reg_addr = READ_ONCE(hw->hw_addr); + if (IXGBE_REMOVED(reg_addr)) + return IXGBE_FAILED_READ_REG; + + /* Register read of 0xFFFFFFFF can indicate the adapter has been + * removed, so perform several status register reads to determine if + * the adapter has been removed. + */ + for (i = 0; i < IXGBE_FAILED_READ_RETRIES; ++i) { + value = readl(reg_addr + IXGBE_STATUS); + if (value != IXGBE_FAILED_READ_REG) + break; + mdelay(3); + } + + if (value == IXGBE_FAILED_READ_REG) + ixgbe_remove_adapter(hw); + else + value = readl(reg_addr + reg); + return value; +} + +static u32 +ixgbe_validate_register_read(struct ixgbe_hw *_hw, u32 reg, bool quiet) +{ + int i; + u32 value; + u8 __iomem *reg_addr; + struct ixgbe_adapter *adapter = _hw->back; + + reg_addr = READ_ONCE(_hw->hw_addr); + if (IXGBE_REMOVED(reg_addr)) + return IXGBE_FAILED_READ_REG; + for (i = 0; i < IXGBE_DEAD_READ_RETRIES; ++i) { + value = readl(reg_addr + reg); + if (value != IXGBE_DEAD_READ_REG) + break; + } + if (quiet) + return value; + if (value == IXGBE_DEAD_READ_REG) + e_err(drv, "%s: register %x read unchanged\n", __func__, reg); + else + e_warn(hw, "%s: register %x read recovered after %d retries\n", + __func__, reg, i + 1); + return value; +} + +u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg, bool quiet) +{ + u32 value; + u8 __iomem *reg_addr; + + reg_addr = READ_ONCE(hw->hw_addr); + if (IXGBE_REMOVED(reg_addr)) + return IXGBE_FAILED_READ_REG; + if (unlikely(hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE)) { + struct ixgbe_adapter *adapter; + int i; + + for (i = 0; i < 200; ++i) { + value = readl(reg_addr + IXGBE_MAC_SGMII_BUSY); + if (likely(!value)) + goto writes_completed; + if (value == IXGBE_FAILED_READ_REG) { + ixgbe_remove_adapter(hw); + return IXGBE_FAILED_READ_REG; + } + udelay(5); + } + + adapter = hw->back; + e_warn(hw, "register writes incomplete %08x\n", value); + } + +writes_completed: + value = readl(reg_addr + reg); + if (unlikely(value == IXGBE_FAILED_READ_REG)) + value = ixgbe_check_remove(hw, reg); + if (unlikely(value == IXGBE_DEAD_READ_REG)) + value = ixgbe_validate_register_read(hw, reg, quiet); + return value; +} + +static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter) +{ + u32 ctrl_ext; + + /* Let firmware take over control of h/w */ + ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, + ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); +} + +static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) +{ + u32 ctrl_ext; + + /* Let firmware know the driver has taken over */ + ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, + ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); +} + +/* + * ixgbe_set_ivar - set the IVAR registers, mapping interrupt causes to vectors + * @adapter: pointer to adapter struct + * @direction: 0 for Rx, 1 for Tx, -1 for other causes + * @queue: queue to map the corresponding interrupt to + * @msix_vector: the vector to map to the corresponding queue + * + */ +static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, + u8 queue, u8 msix_vector) +{ + u32 ivar, index; + struct ixgbe_hw *hw = &adapter->hw; + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + msix_vector |= IXGBE_IVAR_ALLOC_VAL; + if (direction == -1) + direction = 0; + index = (((direction * 64) + queue) >> 2) & 0x1F; + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index)); + ivar &= ~(0xFF << (8 * (queue & 0x3))); + ivar |= (msix_vector << (8 * (queue & 0x3))); + IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + if (direction == -1) { + /* other causes */ + msix_vector |= IXGBE_IVAR_ALLOC_VAL; + index = ((queue & 1) * 8); + ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR_MISC); + ivar &= ~(0xFF << index); + ivar |= (msix_vector << index); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR_MISC, ivar); + break; + } else { + /* tx or rx causes */ + msix_vector |= IXGBE_IVAR_ALLOC_VAL; + index = ((16 * (queue & 1)) + (8 * direction)); + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(queue >> 1)); + ivar &= ~(0xFF << index); + ivar |= (msix_vector << index); + IXGBE_WRITE_REG(hw, IXGBE_IVAR(queue >> 1), ivar); + break; + } + default: + break; + } +} + +void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, + u64 qmask) +{ + u32 mask; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + mask = (IXGBE_EIMS_RTX_QUEUE & qmask); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + mask = (qmask & 0xFFFFFFFF); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); + mask = (qmask >> 32); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask); + break; + default: + break; + } +} + +static void ixgbe_update_xoff_rx_lfc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *hwstats = &adapter->stats; + int i; + u32 data; + + if ((hw->fc.current_mode != ixgbe_fc_full) && + (hw->fc.current_mode != ixgbe_fc_rx_pause)) + return; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + break; + default: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } + hwstats->lxoffrxc += data; + + /* refill credits (no tx hang) if we received xoff */ + if (!data) + return; + + for (i = 0; i < adapter->num_tx_queues; i++) + clear_bit(__IXGBE_HANG_CHECK_ARMED, + &adapter->tx_ring[i]->state); + for (i = 0; i < adapter->num_xdp_queues; i++) + clear_bit(__IXGBE_HANG_CHECK_ARMED, + &adapter->xdp_ring[i]->state); +} + +static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *hwstats = &adapter->stats; + u32 xoff[8] = {0}; + u8 tc; + int i; + bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; + +#ifdef HAVE_DCBNL_IEEE + if (adapter->ixgbe_ieee_pfc) + pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); + +#endif + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !pfc_en) { + ixgbe_update_xoff_rx_lfc(adapter); + return; + } + + /* update stats for each tc, only valid with PFC enabled */ + for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) { + u32 pxoffrxc; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + pxoffrxc = IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + break; + default: + pxoffrxc = IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + } + hwstats->pxoffrxc[i] += pxoffrxc; + /* Get the TC for given UP */ + tc = netdev_get_prio_tc_map(adapter->netdev, i); + xoff[tc] += pxoffrxc; + } + + /* disarm tx queues that have received xoff frames */ + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + + tc = tx_ring->dcb_tc; + if ((tc <= 7) && (xoff[tc])) + clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); + } + for (i = 0; i < adapter->num_xdp_queues; i++) { + struct ixgbe_ring *xdp_ring = adapter->xdp_ring[i]; + + tc = xdp_ring->dcb_tc; + if (tc <= 7 && xoff[tc]) + clear_bit(__IXGBE_HANG_CHECK_ARMED, &xdp_ring->state); + } +} + +static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring) +{ + return ring->stats.packets; +} + +static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring) +{ + unsigned int head, tail; + + head = ring->next_to_clean; + tail = ring->next_to_use; + + return ((head <= tail) ? tail : tail + ring->count) - head; +} + +/** + * ixgbe_get_vf_idx - provide vf index number of defined queue + * @adapter: pointer to the adpter struct + * @queue: tx queue identifier + * @vf: output vf index + * + * Returns : IXGBE_SUCCESS if vf provided or error number + * + * This function provide vf index number associated to the input queue + */ +static s32 ixgbe_get_vf_idx(struct ixgbe_adapter *adapter, u16 queue, u16 *vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u8 queue_count; + u32 reg; + + if (queue > adapter->num_tx_queues - 1) + return IXGBE_ERR_PARAM; + + /* + * Determine number of queues by checking + * number of virtual functions + */ + reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + switch (reg & IXGBE_GCR_EXT_VT_MODE_MASK) { + case IXGBE_GCR_EXT_VT_MODE_64: + queue_count = 2; + break; + case IXGBE_GCR_EXT_VT_MODE_32: + queue_count = 4; + break; + case IXGBE_GCR_EXT_VT_MODE_16: + queue_count = 8; + break; + default: + return IXGBE_ERR_CONFIG; + } + + *vf = queue / queue_count; + + return IXGBE_SUCCESS; +} + +static bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) +{ + u32 tx_done = ixgbe_get_tx_completed(tx_ring); + u32 tx_done_old = tx_ring->tx_stats.tx_done_old; + u32 tx_pending = ixgbe_get_tx_pending(tx_ring); + bool ret = false; + + clear_check_for_tx_hang(tx_ring); + + /* + * Check for a hung queue, but be thorough. This verifies + * that a transmit has been completed since the previous + * check AND there is at least one packet pending. The + * ARMED bit is set to indicate a potential hang. The + * bit is cleared if a pause frame is received to remove + * false hang detection due to PFC or 802.3x frames. By + * requiring this to fail twice we avoid races with + * PFC clearing the ARMED bit and conditions where we + * run the check_tx_hang logic with a transmit completion + * pending but without time to complete it yet. + */ + if ((tx_done_old == tx_done) && tx_pending) { + /* make sure it is true for two checks in a row */ + ret = test_and_set_bit(__IXGBE_HANG_CHECK_ARMED, + &tx_ring->state); + } else { + /* update completed stats and continue */ + tx_ring->tx_stats.tx_done_old = tx_done; + /* reset the countdown */ + clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); + } + + return ret; +} + +/** + * ixgbe_tx_timeout_reset - Initiate a reset due to a Tx timeout + * @adapter: Pointer to the driver private structure + * + * This function initiates a reset of the ixgbe network adapter in response + * to a transmit (Tx) timeout. It sets a reset request flag and schedules a + * service event to handle the reset, ensuring that the operation occurs + * outside of interrupt context. The function checks if the adapter is not + * already marked as down before proceeding with the reset request. + */static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter) +{ + + /* Do the reset outside of interrupt context */ + if (!test_bit(__IXGBE_DOWN, adapter->state)) { + set_bit(__IXGBE_RESET_REQUESTED, adapter->state); + ixgbe_service_event_schedule(adapter); + } +} + +/** + * ixgbe_tx_timeout - Respond to a Tx hang event + * @netdev: Network interface device structure pointer + * @txqueue: Specific Tx queue (used if HAVE_TX_TIMEOUT_TXQUEUE is defined) + * + * This function responds to a transmit (Tx) hang event on the ixgbe network + * adapter. It checks each Tx queue for a real Tx hang and initiates a reset + * if a hang is detected. If no real hang is found, it logs a message about + * a fake Tx hang and increases the kernel's watchdog timeout to prevent + * premature timeout events. + */ +#ifdef HAVE_TX_TIMEOUT_TXQUEUE +static void ixgbe_tx_timeout(struct net_device *netdev, unsigned int txqueue) +#else +static void ixgbe_tx_timeout(struct net_device *netdev) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool real_tx_hang = false; + int i; + +#define TX_TIMEO_LIMIT 16000 + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) + real_tx_hang = true; + } + + if (real_tx_hang) { + ixgbe_tx_timeout_reset(adapter); + } else { + e_info(drv, "Fake Tx hang detected with timeout of %d " + "seconds\n", netdev->watchdog_timeo/HZ); + + /* fake Tx hang - increase the kernel timeout */ + if (netdev->watchdog_timeo < TX_TIMEO_LIMIT) + netdev->watchdog_timeo *= 2; + } +} + +/** + * ixgbe_reset_pf_report - reset pf and print reset report + * @tx_ring: tx ring number + * @next: next ring + * + * Prints a message containing details about the tx hang. + * Then reset the current PF adapter. + */ +static void ixgbe_reset_pf_report(struct ixgbe_ring *tx_ring, + unsigned int next) +{ + struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev); + struct ixgbe_hw *hw = &adapter->hw; + + e_err(drv, "Detected Tx Unit Hang%s\n" + " Tx Queue <%d>\n" + " TDH, TDT <%x>, <%x>\n" + " next_to_use <%x>\n" + " next_to_clean <%x>\n" + "tx_buffer_info[next_to_clean]\n" + " time_stamp <%lx>\n" + " jiffies <%lx>\n", + ring_is_xdp(tx_ring) ? " (XDP)" : "", + tx_ring->queue_index, + IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)), + IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)), + tx_ring->next_to_use, next, + tx_ring->tx_buffer_info[next].time_stamp, jiffies); + + if (!ring_is_xdp(tx_ring)) + netif_stop_subqueue(tx_ring->netdev, + tx_ring->queue_index); +} + +/** + * ixgbe_reset_vf_report - reset vf and print reset report + * @adapter: structure containing ring specific data + * @vf: vf index + * + * Print a message containing details about maliciuos driver detection. + * Disable malicious VF driver if the detection happened several times. + */ +static void ixgbe_reset_vf_report(struct ixgbe_adapter *adapter, u16 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (ixgbe_is_mac_E6xx(hw->mac.type)) { + e_info(drv, + "Malicious Driver Detection tx hang detected on PF %d VF %d MAC: %pM mdd-disable-vf=on", + hw->bus.func, vf, + adapter->vfinfo[vf].vf_mac_addresses); + + adapter->tx_hang_count[vf]++; + if (adapter->tx_hang_count[vf] == IXGBE_MAX_TX_VF_HANGS) { + ixgbe_set_vf_link_state(adapter, vf, + IFLA_VF_LINK_STATE_DISABLE); + adapter->tx_hang_count[vf] = 0; + } + } +} + +/** + * ixgbe_check_illegal_queue - check illegality packet + * @adapter: structure containing ring specific data + * @queue: queue index + * + * Returns : true if queue contain illegality packet + * + * Check if tx descriptor connected with input queue + * contain illegal packet. + */ +static bool ixgbe_check_illegal_queue(struct ixgbe_adapter *adapter, + u16 queue) +{ + struct ixgbe_adv_tx_context_desc cd; + struct ixgbe_hw *hw = &adapter->hw; + u32 mss_len, header_len, reg; + u16 i; + + for (i = 0; i < IXGBE_MAX_TX_DESCRIPTORS; i++) { + /* + * HW will clear bit IXGBE_TXDESCIC_READY when address + * is written to “Address” field. HW will set this bit + * when iCache read is done, and data is ready at TIC_DWx. + * Set descriptor address. + */ + IXGBE_WRITE_REG(hw, IXGBE_TXDESCIC, queue*i); + do { + reg = IXGBE_READ_REG(hw, IXGBE_TXDESCIC); + } while (!(reg & IXGBE_TXDESCIC_READY)); + + /* read tx descriptor access registers */ + cd.vlan_macip_lens = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(0)); + cd.seqnum_seed = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(1)); + cd.type_tucmd_mlhl = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(2)); + cd.mss_l4len_idx = IXGBE_READ_REG(hw, IXGBE_TIC_DW2(3)); + + /* check if Advanced Context Descriptor */ + if ((cd.type_tucmd_mlhl & 0x00F00000 >> 20) == 2) { + /* Determine legality */ + /* check for illegal MSS and Header length */ + mss_len = cd.mss_l4len_idx & 0xFFFF0000 >> 16; + header_len = cd.vlan_macip_lens & 0x000001FF; + if ((mss_len + header_len) > 16384) { + e_info(probe, + "mss len + header len too long\n"); + return true; + } + } + } + + return false; +} + +/** + * ixgbe_handle_mdd_event - handle mdd event + * @adapter: structure containing ring specific data + * @tx_ring: tx descriptor ring to handle + * + * Reset VF driver if malicious vf detected or + * illegal packet in an any queue detected. + */ +static void ixgbe_handle_mdd_event(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) +{ + u16 vf, q; + + if (adapter->flags & IXGBE_FLAG_MDD_ENABLED && + adapter->vfinfo && ixgbe_check_mdd_event(adapter)) { + /* vf mdd info and malicious vf detected */ + if (!ixgbe_get_vf_idx(adapter, tx_ring->queue_index, + &vf)) { + ixgbe_reset_vf_report(adapter, vf); + } + } else { + /* malicious vf not detected */ + for (q = 0; q < IXGBE_MAX_TX_QUEUES; q++) { + if (ixgbe_check_illegal_queue(adapter, q) && + !ixgbe_get_vf_idx(adapter, q, &vf)) { + /* illegal queue detected */ + ixgbe_reset_vf_report(adapter, vf); + } + } + } +} + +/** + * ixgbe_clean_tx_irq - Reclaim resources after transmit completes + * @q_vector: Structure containing interrupt and ring information + * @tx_ring: Transmit ring to clean + * @napi_budget: Used to determine if we are in netpoll + * + * This function reclaims resources after a transmit (Tx) operation completes + * on the ixgbe network adapter. It processes completed Tx descriptors, frees + * associated buffers, updates statistics, and checks for Tx hangs. If a Tx + * hang is detected, it initiates a reset. The function also manages queue + * wake-up conditions based on available descriptors and network carrier + * status. + * + * Return: true if the budget is exhausted or a reset is needed, false + * otherwise. + */ +static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *tx_ring, int napi_budget) +{ + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ixgbe_tx_buffer *tx_buffer; + union ixgbe_adv_tx_desc *tx_desc; + unsigned int total_bytes = 0, total_packets = 0; + unsigned int budget = q_vector->tx.work_limit; + unsigned int i = tx_ring->next_to_clean; + + if (test_bit(__IXGBE_DOWN, adapter->state)) + return true; + + tx_buffer = &tx_ring->tx_buffer_info[i]; + tx_desc = IXGBE_TX_DESC(tx_ring, i); + i -= tx_ring->count; + + do { + union ixgbe_adv_tx_desc *eop_desc = tx_buffer->next_to_watch; + + /* if next_to_watch is not set then there is no work pending */ + if (!eop_desc) + break; + + /* prevent any other reads prior to eop_desc */ + smp_rmb(); + + /* if DD is not set pending work has not been completed */ + if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD))) + break; + + /* clear next_to_watch to prevent false hangs */ + tx_buffer->next_to_watch = NULL; + + /* update the statistics for this packet */ + total_bytes += tx_buffer->bytecount; + total_packets += tx_buffer->gso_segs; + + /* free the skb */ +#ifdef HAVE_XDP_SUPPORT + if (ring_is_xdp(tx_ring)) +#ifdef HAVE_XDP_FRAME_STRUCT + xdp_return_frame(tx_buffer->xdpf); +#else + page_frag_free(tx_buffer->data); +#endif + else + napi_consume_skb(tx_buffer->skb, napi_budget); +#else + napi_consume_skb(tx_buffer->skb, napi_budget); +#endif + + /* unmap skb header data */ + dma_unmap_single(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + + /* clear tx_buffer data */ + dma_unmap_len_set(tx_buffer, len, 0); + + /* unmap remaining buffers */ + while (tx_desc != eop_desc) { + tx_buffer++; + tx_desc++; + i++; + if (unlikely(!i)) { + i -= tx_ring->count; + tx_buffer = tx_ring->tx_buffer_info; + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + } + + /* unmap any remaining paged data */ + if (dma_unmap_len(tx_buffer, len)) { + dma_unmap_page(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + dma_unmap_len_set(tx_buffer, len, 0); + } + } + + /* move us one more past the eop_desc for start of next pkt */ + tx_buffer++; + tx_desc++; + i++; + if (unlikely(!i)) { + i -= tx_ring->count; + tx_buffer = tx_ring->tx_buffer_info; + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + } + + /* issue prefetch for next Tx descriptor */ + prefetch(tx_desc); + + /* update budget accounting */ + budget--; + } while (likely(budget)); + + i += tx_ring->count; + tx_ring->next_to_clean = i; + u64_stats_update_begin(&tx_ring->syncp); + tx_ring->stats.bytes += total_bytes; + tx_ring->stats.packets += total_packets; + u64_stats_update_end(&tx_ring->syncp); + q_vector->tx.total_bytes += total_bytes; + q_vector->tx.total_packets += total_packets; + + if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_handle_mdd_event(adapter, tx_ring); + /* reset PF */ + ixgbe_reset_pf_report(tx_ring, i); + + e_info(probe, + "tx hang %d detected on queue %d, resetting adapter\n", + adapter->tx_timeout_count + 1, tx_ring->queue_index); + + ixgbe_tx_timeout_reset(adapter); + + /* the adapter is about to reset, no point in enabling stuff */ + return true; + } + + if (ring_is_xdp(tx_ring)) + return !!budget; + netdev_tx_completed_queue(txring_txq(tx_ring), + total_packets, total_bytes); + +#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) + if (unlikely(total_packets && netif_carrier_ok(netdev_ring(tx_ring)) && + (ixgbe_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD))) { + /* Make sure that anybody stopping the queue after this + * sees the new next_to_clean. + */ + smp_mb(); +#ifdef HAVE_TX_MQ + if (__netif_subqueue_stopped(netdev_ring(tx_ring), + ring_queue_index(tx_ring)) && + !test_bit(__IXGBE_DOWN, q_vector->adapter->state)) { + netif_wake_subqueue(netdev_ring(tx_ring), + ring_queue_index(tx_ring)); + ++tx_ring->tx_stats.restart_queue; + } +#else + if (netif_queue_stopped(netdev_ring(tx_ring)) && + !test_bit(__IXGBE_DOWN, q_vector->adapter->state)) { + netif_wake_queue(netdev_ring(tx_ring)); + ++tx_ring->tx_stats.restart_queue; + } +#endif + } + + return !!budget; +} + +#if IS_ENABLED(CONFIG_DCA) +static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring, + int cpu) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 txctrl = 0; + u16 reg_offset; + + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + txctrl = dca3_get_tag(tx_ring->dev, cpu); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + reg_offset = IXGBE_DCA_TXCTRL(tx_ring->reg_idx); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + reg_offset = IXGBE_DCA_TXCTRL_82599(tx_ring->reg_idx); + txctrl <<= IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599; + break; + default: + /* for unknown hardware do not write register */ + return; + } + + /* + * We can enable relaxed ordering for reads, but not writes when + * DCA is enabled. This is due to a known issue in some chipsets + * which will cause the DCA tag to be cleared. + */ + txctrl |= IXGBE_DCA_TXCTRL_DESC_RRO_EN | + IXGBE_DCA_TXCTRL_DATA_RRO_EN | + IXGBE_DCA_TXCTRL_DESC_DCA_EN; + + IXGBE_WRITE_REG(hw, reg_offset, txctrl); +} + +static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cpu) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rxctrl = 0; + u8 reg_idx = rx_ring->reg_idx; + + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + rxctrl = dca3_get_tag(rx_ring->dev, cpu); + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + rxctrl <<= IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599; + break; + default: + break; + } + + /* + * We can enable relaxed ordering for reads, but not writes when + * DCA is enabled. This is due to a known issue in some chipsets + * which will cause the DCA tag to be cleared. + */ + rxctrl |= IXGBE_DCA_RXCTRL_DESC_RRO_EN | + IXGBE_DCA_RXCTRL_DATA_DCA_EN | + IXGBE_DCA_RXCTRL_DESC_DCA_EN; + + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl); +} + +static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector) +{ + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ixgbe_ring *ring; + int cpu = get_cpu(); + + if (q_vector->cpu == cpu) + goto out_no_update; + + ixgbe_for_each_ring(ring, q_vector->tx) + ixgbe_update_tx_dca(adapter, ring, cpu); + + ixgbe_for_each_ring(ring, q_vector->rx) + ixgbe_update_rx_dca(adapter, ring, cpu); + + q_vector->cpu = cpu; +out_no_update: + put_cpu(); +} + +static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) +{ + int v_idx; + + /* always use CB2 mode, difference is masked in the CB driver */ + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, + IXGBE_DCA_CTRL_DCA_MODE_CB2); + else + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, + IXGBE_DCA_CTRL_DCA_DISABLE); + + for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) { + adapter->q_vector[v_idx]->cpu = -1; + ixgbe_update_dca(adapter->q_vector[v_idx]); + } +} + +static int __ixgbe_notify_dca(struct device *dev, void *data) +{ + struct ixgbe_adapter *adapter = dev_get_drvdata(dev); + unsigned long event = *(unsigned long *)data; + + if (!(adapter->flags & IXGBE_FLAG_DCA_CAPABLE)) + return 0; + + switch (event) { + case DCA_PROVIDER_ADD: + /* if we're already enabled, don't do it again */ + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + break; + if (dca_add_requester(dev) == IXGBE_SUCCESS) { + adapter->flags |= IXGBE_FLAG_DCA_ENABLED; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, + IXGBE_DCA_CTRL_DCA_MODE_CB2); + break; + } + /* fall through - DCA is disabled */ + fallthrough; + case DCA_PROVIDER_REMOVE: + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { + dca_remove_requester(dev); + adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, + IXGBE_DCA_CTRL_DCA_DISABLE); + } + break; + } + + return IXGBE_SUCCESS; +} +#endif /* CONFIG_DCA */ + +#ifdef NETIF_F_RXHASH +#define IXGBE_RSS_L4_TYPES_MASK \ + ((1ul << IXGBE_RXDADV_RSSTYPE_IPV4_TCP) | \ + (1ul << IXGBE_RXDADV_RSSTYPE_IPV4_UDP) | \ + (1ul << IXGBE_RXDADV_RSSTYPE_IPV6_TCP) | \ + (1ul << IXGBE_RXDADV_RSSTYPE_IPV6_UDP) | \ + (1ul << IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX) | \ + (1ul << IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX)) + +static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + u16 rss_type; + + if (!(netdev_ring(ring)->features & NETIF_F_RXHASH)) + return; + + rss_type = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info) & + IXGBE_RXDADV_RSSTYPE_MASK; + + if (!rss_type) + return; + + skb_set_hash(skb, le32_to_cpu(rx_desc->wb.lower.hi_dword.rss), + (IXGBE_RSS_L4_TYPES_MASK & (1ul << rss_type)) ? + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); +} +#endif /* NETIF_F_RXHASH */ + +#if IS_ENABLED(CONFIG_FCOE) +/** + * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type + * @ring: structure containing ring specific data + * @rx_desc: advanced rx descriptor + * + * Returns : true if it is FCoE pkt + */ +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc) +{ + __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + + return test_bit(__IXGBE_RX_FCOE, &ring->state) && + ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == + (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << + IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); +} +#endif /* CONFIG_FCOE */ + +/** + * ixgbe_rx_checksum - Indicate in skb if hardware indicated a good checksum + * @ring: Structure containing ring-specific data + * @rx_desc: Current Rx descriptor being processed + * @skb: Socket buffer currently being received and modified + * + * This function checks the receive (Rx) descriptor for checksum status and + * updates the socket buffer (skb) accordingly. It verifies if the checksum + * offload is enabled and processes the checksum status for IP, TCP, and UDP + * packets. The function handles special cases for encapsulated packets and + * known hardware errata, marking the skb with the appropriate checksum + * status. + */ +static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + bool encap_pkt = false; + + skb_checksum_none_assert(skb); + + /* Rx csum disabled */ + if (!(netdev_ring(ring)->features & NETIF_F_RXCSUM)) + return; + + /* check for VXLAN or Geneve packet type */ + if (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) { + encap_pkt = true; +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) + skb->encapsulation = 1; +#endif /* HAVE_UDP_ENC_RX_OFFLOAD || HAVE_VXLAN_RX_OFFLOAD */ + skb->ip_summed = CHECKSUM_NONE; + } + + /* if IP and error */ + if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) && + ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) { + ring->rx_stats.csum_err++; + return; + } + + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_L4CS)) + return; + + if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) { + + /* + * 82599 errata, UDP frames with a 0 checksum can be marked as + * checksum errors. + */ + if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_UDP)) && + test_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state)) + return; + + ring->rx_stats.csum_err++; + return; + } + + /* It must be a TCP or UDP packet with a valid checksum */ + skb->ip_summed = CHECKSUM_UNNECESSARY; + if (encap_pkt) { + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_OUTERIPCS)) + return; + + if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_OUTERIPER)) { + skb->ip_summed = CHECKSUM_NONE; + return; + } +#ifdef HAVE_SKBUFF_CSUM_LEVEL + /* If we checked the outer header let the stack know */ + skb->csum_level = 1; +#endif /* HAVE_SKBUFF_CSUM_LEVEL */ + } +} + +static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) +{ + rx_ring->next_to_use = val; +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + + /* update next to alloc since we have filled the ring */ + rx_ring->next_to_alloc = val; +#endif + /* + * Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). + */ + wmb(); + writel(val, rx_ring->tail); +} + +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +static bool ixgbe_alloc_mapped_skb(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi) +{ + struct sk_buff *skb = bi->skb; + dma_addr_t dma = bi->dma; + + if (unlikely(dma)) + return true; + + if (likely(!skb)) { + skb = netdev_alloc_skb_ip_align(netdev_ring(rx_ring), + rx_ring->rx_buf_len); + if (unlikely(!skb)) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + return false; + } + + bi->skb = skb; + + } + + dma = dma_map_single(rx_ring->dev, skb->data, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); + + /* + * if mapping failed free memory back to system since + * there isn't much point in holding memory we can't use + */ + if (dma_mapping_error(rx_ring->dev, dma)) { + dev_kfree_skb_any(skb); + bi->skb = NULL; + + rx_ring->rx_stats.alloc_rx_buff_failed++; + return false; + } + + bi->dma = dma; + return true; +} + +#else /* !CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ +static unsigned int ixgbe_rx_offset(struct ixgbe_ring *rx_ring) +{ + return ring_uses_build_skb(rx_ring) ? IXGBE_SKB_PAD : 0; +} + +static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi) +{ + struct page *page = bi->page; + dma_addr_t dma; +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); + dma_set_attr(DMA_ATTR_WEAK_ORDERING, &attrs); +#endif + + /* since we are recycling buffers we should seldom need to alloc */ + if (likely(page)) + return true; + + /* alloc new page for storage */ + page = dev_alloc_pages(ixgbe_rx_pg_order(rx_ring)); + if (unlikely(!page)) { + rx_ring->rx_stats.alloc_rx_page_failed++; + return false; + } + + /* map page for use */ + dma = dma_map_page_attrs(rx_ring->dev, page, 0, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE, +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + &attrs); +#else + IXGBE_RX_DMA_ATTR); +#endif + + /* + * if mapping failed free memory back to system since + * there isn't much point in holding memory we can't use + */ + if (dma_mapping_error(rx_ring->dev, dma)) { + __free_pages(page, ixgbe_rx_pg_order(rx_ring)); + + rx_ring->rx_stats.alloc_rx_page_failed++; + return false; + } + + bi->dma = dma; + bi->page = page; + bi->page_offset = ixgbe_rx_offset(rx_ring); +#ifdef HAVE_PAGE_COUNT_BULK_UPDATE + page_ref_add(page, USHRT_MAX - 1); + bi->pagecnt_bias = USHRT_MAX; +#else + bi->pagecnt_bias = 1; +#endif + rx_ring->rx_stats.alloc_rx_page++; + + return true; +} +#endif /* !CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + +/** + * ixgbe_alloc_rx_buffers - Replace used receive buffers + * @rx_ring: Ring to place buffers on + * @cleaned_count: Number of buffers to replace + * + * This function replaces used receive buffers on the specified Rx ring of + * the ixgbe network adapter. It allocates new buffers and updates the Rx + * descriptors with the addresses of these buffers. The function handles + * both packet split and non-packet split modes, ensuring that the buffers + * are properly synchronized for device use. It also refreshes the descriptor + * information and releases the Rx descriptors if necessary. + */ +void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) +{ + union ixgbe_adv_rx_desc *rx_desc; + struct ixgbe_rx_buffer *bi; + u16 i = rx_ring->next_to_use; +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + u16 bufsz; +#endif + + /* nothing to do */ + if (!cleaned_count) + return; + + rx_desc = IXGBE_RX_DESC(rx_ring, i); + bi = &rx_ring->rx_buffer_info[i]; + i -= rx_ring->count; +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + + bufsz = ixgbe_rx_bufsz(rx_ring); +#endif + + do { +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + if (!ixgbe_alloc_mapped_skb(rx_ring, bi)) + break; +#else + if (!ixgbe_alloc_mapped_page(rx_ring, bi)) + break; + + /* sync the buffer for use by the device */ + dma_sync_single_range_for_device(rx_ring->dev, bi->dma, + bi->page_offset, bufsz, + DMA_FROM_DEVICE); +#endif + + /* + * Refresh the desc even if buffer_addrs didn't change + * because each write-back erases this info. + */ +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); +#else + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset); +#endif + + rx_desc++; + bi++; + i++; + if (unlikely(!i)) { + rx_desc = IXGBE_RX_DESC(rx_ring, 0); + bi = rx_ring->rx_buffer_info; + i -= rx_ring->count; + } + + /* clear the length for the next_to_use descriptor */ + rx_desc->wb.upper.length = 0; + + cleaned_count--; + } while (cleaned_count); + + i += rx_ring->count; + + if (rx_ring->next_to_use != i) + ixgbe_release_rx_desc(rx_ring, i); +} + +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +/** + * ixgbe_merge_active_tail - Merge active tail into LRO skb + * @tail: Pointer to the active tail in the frag_list + * + * This function merges the length and data of an active tail into the + * socket buffer (skb) containing the frag_list. It updates the length, + * data length, and true size of the head skb to include the tail's + * attributes. The function then resets the tail's head pointer to NULL, + * effectively merging the tail into the head while leaving the head's + * pointer to the tail intact. + * + * Return: Pointer to the head skb after merging. + */ +static inline struct sk_buff *ixgbe_merge_active_tail(struct sk_buff *tail) +{ + struct sk_buff *head = IXGBE_CB(tail)->head; + + if (!head) + return tail; + + head->len += tail->len; + head->data_len += tail->len; + head->truesize += tail->truesize; + + IXGBE_CB(tail)->head = NULL; + + return head; +} + +/** + * ixgbe_add_active_tail - Add an active tail to the skb frag_list + * @head: Pointer to the start of the skb + * @tail: Pointer to the active tail to add to the frag_list + * + * This function adds an active tail to the end of the frag_list of the + * specified socket buffer (skb). The tail is still receiving data, so its + * statistics are not yet added to the main skb. This is handled later by + * the `ixgbe_merge_active_tail` function. If there is an existing tail, + * it is merged before adding the new tail. + */ +static inline void ixgbe_add_active_tail(struct sk_buff *head, + struct sk_buff *tail) +{ + struct sk_buff *old_tail = IXGBE_CB(head)->tail; + + if (old_tail) { + ixgbe_merge_active_tail(old_tail); + old_tail->next = tail; + } else { + skb_shinfo(head)->frag_list = tail; + } + + IXGBE_CB(tail)->head = head; + IXGBE_CB(head)->tail = tail; +} + +/** + * ixgbe_close_active_frag_list - Clean up pointers on a frag_list skb + * @head: Pointer to the head of an active frag_list + * + * This function clears the `frag_tail_tracker` pointer on an active + * frag_list within the specified socket buffer (skb). It merges the active + * tail into the head and resets the tail pointer to NULL. The function + * returns true if the tail pointer was set and successfully cleared. + * + * Return: true if the tail pointer was set and cleared, false otherwise. + */ +static inline bool ixgbe_close_active_frag_list(struct sk_buff *head) +{ + struct sk_buff *tail = IXGBE_CB(head)->tail; + + if (!tail) + return false; + + ixgbe_merge_active_tail(tail); + + IXGBE_CB(head)->tail = NULL; + + return true; +} +#endif + +#ifdef HAVE_VLAN_RX_REGISTER +/** + * ixgbe_receive_skb - Send a completed packet up the network stack + * @q_vector: Structure containing interrupt and ring information + * @skb: Packet to send up the stack + * + * This function processes a completed packet (skb) and sends it up the + * network stack. It handles VLAN-tagged packets by checking for a VLAN + * group and using appropriate VLAN handling functions. For non-VLAN packets, + * it uses standard network stack functions to pass the packet up. The + * function also considers whether netpoll is enabled for the queue vector. + */ +static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb) +{ + u16 vlan_tag = IXGBE_CB(skb)->vid; + +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) + if (vlan_tag & VLAN_VID_MASK) { + /* by placing vlgrp at start of structure we can alias it */ + struct vlan_group **vlgrp = netdev_priv(skb->dev); + if (!*vlgrp) + dev_kfree_skb_any(skb); + else if (q_vector->netpoll_rx) + vlan_hwaccel_rx(skb, *vlgrp, vlan_tag); + else + vlan_gro_receive(&q_vector->napi, + *vlgrp, vlan_tag, skb); + } else { +#endif /* NETIF_F_HW_VLAN_TX || NETIF_F_HW_VLAN_CTAG_TX */ + if (q_vector->netpoll_rx) + netif_rx(skb); + else + napi_gro_receive(&q_vector->napi, skb); +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) + } +#endif /* NETIF_F_HW_VLAN_TX || NETIF_F_HW_VLAN_CTAG_TX */ +} +#endif /* HAVE_VLAN_RX_REGISTER */ + +#ifdef NETIF_F_GSO +static void ixgbe_set_rsc_gso_size(struct ixgbe_ring __maybe_unused *ring, + struct sk_buff *skb) +{ + u16 hdr_len = skb_headlen(skb); + + /* set gso_size to avoid messing up TCP MSS */ + skb_shinfo(skb)->gso_size = DIV_ROUND_UP((skb->len - hdr_len), + IXGBE_CB(skb)->append_cnt); + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; +} + +#endif /* NETIF_F_GSO */ +static void ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring, + struct sk_buff *skb) +{ + /* if append_cnt is 0 then frame is not RSC */ + if (!IXGBE_CB(skb)->append_cnt) + return; + + rx_ring->rx_stats.rsc_count += IXGBE_CB(skb)->append_cnt; + rx_ring->rx_stats.rsc_flush++; + +#ifdef NETIF_F_GSO + ixgbe_set_rsc_gso_size(rx_ring, skb); + +#endif + /* gso_size is computed using append_cnt so always clear it last */ + IXGBE_CB(skb)->append_cnt = 0; +} + +static void ixgbe_rx_vlan(struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ +#ifdef NETIF_F_HW_VLAN_CTAG_RX + if ((netdev_ring(ring)->features & NETIF_F_HW_VLAN_CTAG_RX) && +#else + if ((netdev_ring(ring)->features & NETIF_F_HW_VLAN_RX) && +#endif + ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) +#ifndef HAVE_VLAN_RX_REGISTER + __vlan_hwaccel_put_tag(skb, + htons(ETH_P_8021Q), + le16_to_cpu(rx_desc->wb.upper.vlan)); +#else + IXGBE_CB(skb)->vid = le16_to_cpu(rx_desc->wb.upper.vlan); + else + IXGBE_CB(skb)->vid = 0; +#endif +} + +/** + * ixgbe_process_skb_fields - Populate skb header fields from Rx descriptor + * @rx_ring: Rx descriptor ring packet is being transacted on + * @rx_desc: Pointer to the end-of-packet (EOP) Rx descriptor + * @skb: Pointer to the current skb being populated + * + * This function populates various fields in the socket buffer (skb) based + * on information from the Rx descriptor and ring. It updates the hash, + * checksum, VLAN, timestamp, protocol, and other relevant fields. The + * function also handles specific features like receive-side scaling (RSS), + * hardware timestamping, and VLAN processing, ensuring the skb is fully + * prepared for further processing in the network stack. + */ +void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ +#ifdef HAVE_PTP_1588_CLOCK + u32 flags = rx_ring->q_vector->adapter->flags; + +#endif + ixgbe_update_rsc_stats(rx_ring, skb); + +#ifdef NETIF_F_RXHASH + ixgbe_rx_hash(rx_ring, rx_desc, skb); + +#endif /* NETIF_F_RXHASH */ + ixgbe_rx_checksum(rx_ring, rx_desc, skb); +#ifdef HAVE_PTP_1588_CLOCK + if (unlikely(flags & IXGBE_FLAG_RX_HWTSTAMP_ENABLED)) + ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb); + else + rx_ring->q_vector->ptp_hold_rx_skb = false; + +#endif + ixgbe_rx_vlan(rx_ring, rx_desc, skb); + + skb_record_rx_queue(skb, ring_queue_index(rx_ring)); + skb->protocol = eth_type_trans(skb, netdev_ring(rx_ring)); +} + +void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ +#ifdef HAVE_NDO_BUSY_POLL + skb_mark_napi_id(skb, &q_vector->napi); + + if (ixgbe_qv_busy_polling(q_vector) || q_vector->netpoll_rx) { + netif_receive_skb(skb); + /* exit early if we busy polled */ + return; + } +#endif + +#ifdef HAVE_VLAN_RX_REGISTER + ixgbe_receive_skb(q_vector, skb); +#else + napi_gro_receive(&q_vector->napi, skb); +#endif +#ifndef NETIF_F_GRO + + netdev_ring(rx_ring)->last_rx = jiffies; +#endif +} + +/** + * ixgbe_is_non_eop - Handle processing of non-EOP buffers + * @rx_ring: Rx ring being processed + * @rx_desc: Rx descriptor for the current buffer + * @skb: Current socket buffer containing the buffer in progress + * + * This function processes non-end-of-packet (non-EOP) buffers in the receive + * (Rx) ring. It updates the next-to-clean index and checks if the current + * buffer is an EOP buffer. If it is not an EOP buffer, the function chains + * the current skb to the next buffer and returns true, indicating that + * further processing is needed. If the buffer is an EOP buffer, the function + * returns false, indicating that no further chaining is required. + * + * Return: true if the buffer is non-EOP and requires chaining, false if it + * is an EOP buffer. + */ +static bool ixgbe_is_non_eop(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + struct sk_buff *next_skb; +#endif + u32 ntc = rx_ring->next_to_clean + 1; + + /* fetch, update, and store next to clean */ + ntc = (ntc < rx_ring->count) ? ntc : 0; + rx_ring->next_to_clean = ntc; + + prefetch(IXGBE_RX_DESC(rx_ring, ntc)); + + /* update RSC append count if present */ + if (ring_is_rsc_enabled(rx_ring)) { + __le32 rsc_enabled = rx_desc->wb.lower.lo_dword.data & + cpu_to_le32(IXGBE_RXDADV_RSCCNT_MASK); + + if (unlikely(rsc_enabled)) { + u32 rsc_cnt = le32_to_cpu(rsc_enabled); + + rsc_cnt >>= IXGBE_RXDADV_RSCCNT_SHIFT; + IXGBE_CB(skb)->append_cnt += rsc_cnt - 1; + + /* update ntc based on RSC value */ + ntc = le32_to_cpu(rx_desc->wb.upper.status_error); + ntc &= IXGBE_RXDADV_NEXTP_MASK; + ntc >>= IXGBE_RXDADV_NEXTP_SHIFT; + } + } + + /* if we are the last buffer then there is nothing else to do */ + if (likely(ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) + return false; + + /* place skb in next buffer to be received */ +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + next_skb = rx_ring->rx_buffer_info[ntc].skb; + + ixgbe_add_active_tail(skb, next_skb); + IXGBE_CB(next_skb)->head = skb; +#else + rx_ring->rx_buffer_info[ntc].skb = skb; +#endif + rx_ring->rx_stats.non_eop_descs++; + + return true; +} + +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +/** + * ixgbe_pull_tail - ixgbe specific version of skb_pull_tail + * @skb: pointer to current skb being adjusted + * + * This function is an ixgbe specific version of __pskb_pull_tail. The + * main difference between this version and the original function is that + * this function can make several assumptions about the state of things + * that allow for significant optimizations versus the standard function. + * As a result we can do things like drop a frag and maintain an accurate + * truesize for the skb. + */ +static void ixgbe_pull_tail(struct sk_buff *skb) +{ + skb_frag_t *frag = &skb_shinfo(skb)->frags[0]; + unsigned char *va; + unsigned int pull_len; + + /* + * it is valid to use page_address instead of kmap since we are + * working with pages allocated out of the lomem pool per + * alloc_page(GFP_ATOMIC) + */ + va = skb_frag_address(frag); + + /* + * we need the header to contain the greater of either ETH_HLEN or + * 60 bytes if the skb->len is less than 60 for skb_pad. + */ + pull_len = eth_get_headlen(skb->dev, va, IXGBE_RX_HDR_SIZE); + + /* align pull length to size of long to optimize memcpy performance */ + skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long))); + + /* update all of the pointers */ + skb_frag_size_sub(frag, pull_len); + skb_frag_off_add(frag, pull_len); + skb->data_len -= pull_len; + skb->tail += pull_len; +} + +/** + * ixgbe_dma_sync_frag - perform DMA sync for first frag of SKB + * @rx_ring: rx descriptor ring packet is being transacted on + * @skb: pointer to current skb being updated + * + * This function provides a basic DMA sync up for the first fragment of an + * skb. The reason for doing this is that the first fragment cannot be + * unmapped until we have reached the end of packet descriptor for a buffer + * chain. + */ +static void ixgbe_dma_sync_frag(struct ixgbe_ring *rx_ring, + struct sk_buff *skb) +{ +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); + dma_set_attr(DMA_ATTR_WEAK_ORDERING, &attrs); + +#endif + /* if the page was released unmap it, else just sync our portion */ + if (unlikely(IXGBE_CB(skb)->page_released)) { + dma_unmap_page_attrs(rx_ring->dev, IXGBE_CB(skb)->dma, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE, +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + &attrs); +#else + IXGBE_RX_DMA_ATTR); +#endif + } else if (ring_uses_build_skb(rx_ring)) { + unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK; + + dma_sync_single_range_for_cpu(rx_ring->dev, + IXGBE_CB(skb)->dma, + offset, + skb_headlen(skb), + DMA_FROM_DEVICE); + } else { + skb_frag_t *frag = &skb_shinfo(skb)->frags[0]; + + dma_sync_single_range_for_cpu(rx_ring->dev, + IXGBE_CB(skb)->dma, + skb_frag_off(frag), + skb_frag_size(frag), + DMA_FROM_DEVICE); + } +} + +/** + * ixgbe_cleanup_headers - Correct corrupted or empty headers + * @rx_ring: rx descriptor ring packet is being transacted on + * @rx_desc: pointer to the EOP Rx descriptor + * @skb: pointer to current skb being fixed + * + * Check if the skb is valid. In the XDP case it will be an error pointer. + * Return true in this case to abort processing and advance to next + * descriptor. + * + * Check for corrupted packet headers caused by senders on the local L2 + * embedded NIC switch not setting up their Tx Descriptors right. These + * should be very rare. + * + * Also address the case where we are pulling data in on pages only + * and as such no data is present in the skb header. + * + * In addition if skb is not at least 60 bytes we need to pad it so that + * it is large enough to qualify as a valid Ethernet frame. + * + * Returns true if an error was encountered and skb was freed. + */ +bool ixgbe_cleanup_headers(struct ixgbe_ring __maybe_unused *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + /* XDP packets use error pointer so abort at this point */ + if (IS_ERR(skb)) + return true; + + /* verify that the packet does not have any known errors */ + if (unlikely(ixgbe_test_staterr(rx_desc, + IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { + dev_kfree_skb_any(skb); + return true; + } + + /* place header in linear portion of buffer */ + if (!skb_headlen(skb)) + ixgbe_pull_tail(skb); + +#if IS_ENABLED(CONFIG_FCOE) + /* do not attempt to pad FCoE Frames as this will disrupt DDP */ + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) + return false; +#endif + + /* if eth_skb_pad returns an error the skb was freed */ + if (eth_skb_pad(skb)) + return true; + + return false; +} + +/** + * ixgbe_reuse_rx_page - Reuse a page buffer and store it back on the ring + * @rx_ring: Rx descriptor ring to store buffers on + * @old_buff: Donor buffer whose page is to be reused + * + * This function reuses a page buffer from an old Rx buffer and stores it + * back on the Rx ring for future use. It updates the next-to-allocate index + * and transfers the page-related information from the old buffer to a new + * buffer. Each member is moved individually to avoid store forwarding stalls + * and unnecessary copying of the socket buffer (skb). + */ +static void ixgbe_reuse_rx_page(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *old_buff) +{ + struct ixgbe_rx_buffer *new_buff; + u16 nta = rx_ring->next_to_alloc; + + new_buff = &rx_ring->rx_buffer_info[nta]; + + /* update, and store next to alloc */ + nta++; + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; + + /* Transfer page from old buffer to new buffer. + * Move each member individually to avoid possible store + * forwarding stalls and unnecessary copy of skb. + */ + new_buff->dma = old_buff->dma; + new_buff->page = old_buff->page; + new_buff->page_offset = old_buff->page_offset; + new_buff->pagecnt_bias = old_buff->pagecnt_bias; +} + +static inline bool ixgbe_page_is_reserved(struct page *page) +{ + return (page_to_nid(page) != numa_mem_id()) || page_is_pfmemalloc(page); +} + +static bool ixgbe_can_reuse_rx_page(struct ixgbe_rx_buffer *rx_buffer) +{ + unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; + struct page *page = rx_buffer->page; + + /* avoid re-using remote pages */ + if (unlikely(ixgbe_page_is_reserved(page))) + return false; + +#if (PAGE_SIZE < 8192) + /* if we are only owner of page we can reuse it */ +#ifdef HAVE_PAGE_COUNT_BULK_UPDATE + if (unlikely((page_ref_count(page) - pagecnt_bias) > 1)) +#else + if (unlikely((page_count(page) - pagecnt_bias) > 1)) +#endif + return false; +#else + /* The last offset is a bit aggressive in that we assume the + * worst case of FCoE being enabled and using a 3K buffer. + * However this should have minimal impact as the 1K extra is + * still less than one buffer in size. + */ +#define IXGBE_LAST_OFFSET \ + (SKB_WITH_OVERHEAD(PAGE_SIZE) - IXGBE_RXBUFFER_3K) + if (rx_buffer->page_offset > IXGBE_LAST_OFFSET) + return false; +#endif + +#ifdef HAVE_PAGE_COUNT_BULK_UPDATE + /* If we have drained the page fragment pool we need to update + * the pagecnt_bias and page count so that we fully restock the + * number of references the driver holds. + */ + if (unlikely(pagecnt_bias == 1)) { + page_ref_add(page, USHRT_MAX - 1); + rx_buffer->pagecnt_bias = USHRT_MAX; + } +#else + /* Even if we own the page, we are not allowed to use atomic_set() + * This would break get_page_unless_zero() users. + */ + if (likely(!pagecnt_bias)) { + page_ref_inc(page); + rx_buffer->pagecnt_bias = 1; + } +#endif + + return true; +} + +/** + * ixgbe_add_rx_frag - Add contents of Rx buffer to sk_buff + * @rx_ring: Rx descriptor ring to transact packets on + * @rx_buffer: Buffer containing the page to add + * @skb: sk_buff to place the data into + * @size: Size of the data + * + * This function adds the data contained in `rx_buffer->page` to the socket + * buffer (skb). If the data size is less than the skb header size, it is + * directly copied; otherwise, the page is attached as a fragment to the skb. + * The function updates the page offset as necessary and prepares the buffer + * for potential reuse by the adapter. + */ +static void ixgbe_add_rx_frag(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *rx_buffer, + struct sk_buff *skb, + unsigned int size) +{ +#if (PAGE_SIZE < 8192) + unsigned int truesize = ixgbe_rx_pg_size(rx_ring) / 2; +#else + unsigned int truesize = rx_ring->rx_offset ? + SKB_DATA_ALIGN(rx_ring->rx_offset + size) : + SKB_DATA_ALIGN(size); +#endif + + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page, + rx_buffer->page_offset, size, truesize); + +#if (PAGE_SIZE < 8192) + rx_buffer->page_offset ^= truesize; +#else + rx_buffer->page_offset += truesize; +#endif +} + +static struct ixgbe_rx_buffer * +ixgbe_get_rx_buffer(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, struct sk_buff **skb, + const unsigned int size) +{ + struct ixgbe_rx_buffer *rx_buffer; + + rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; + prefetchw(rx_buffer->page); + *skb = rx_buffer->skb; + + /* Delay unmapping of the first packet. It carries the header + * information, HW may still access the header after the writeback. + * Only unmap it when EOP is reached + */ + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP)) { + if (!*skb) + goto skip_sync; + } else { + if (*skb) + ixgbe_dma_sync_frag(rx_ring, *skb); + } + + /* we are reusing so sync this buffer for CPU use */ + dma_sync_single_range_for_cpu(rx_ring->dev, + rx_buffer->dma, + rx_buffer->page_offset, + size, + DMA_FROM_DEVICE); +skip_sync: + rx_buffer->pagecnt_bias--; + + return rx_buffer; +} + +static void ixgbe_put_rx_buffer(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *rx_buffer, + struct sk_buff *skb) +{ +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); + dma_set_attr(DMA_ATTR_WEAK_ORDERING, &attrs); + +#endif + if (ixgbe_can_reuse_rx_page(rx_buffer)) { + /* hand second half of page back to the ring */ + ixgbe_reuse_rx_page(rx_ring, rx_buffer); + } else { + if (!IS_ERR(skb) && IXGBE_CB(skb)->dma == rx_buffer->dma) { + /* the page has been released from the ring */ + IXGBE_CB(skb)->page_released = true; + } else { + /* we are not reusing the buffer so unmap it */ + dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE, +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + &attrs); +#else + IXGBE_RX_DMA_ATTR); +#endif + } + __page_frag_cache_drain(rx_buffer->page, + rx_buffer->pagecnt_bias); + } + + /* clear contents of rx_buffer */ + rx_buffer->page = NULL; + rx_buffer->skb = NULL; +} + +static struct sk_buff *ixgbe_construct_skb(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *rx_buffer, + struct xdp_buff *xdp, + union ixgbe_adv_rx_desc *rx_desc) +{ + unsigned int size = xdp->data_end - xdp->data; +#if (PAGE_SIZE < 8192) + unsigned int truesize = ixgbe_rx_pg_size(rx_ring) / 2; +#else + unsigned int truesize = SKB_DATA_ALIGN(xdp->data_end - + xdp->data_hard_start); +#endif + struct sk_buff *skb; + + /* prefetch first cache line of first page */ + prefetch(xdp->data); +#if L1_CACHE_BYTES < 128 + prefetch(xdp->data + L1_CACHE_BYTES); +#endif + /* Note, we get here by enabling legacy-rx via: + * + * ethtool --set-priv-flags legacy-rx on + * + * In this mode, we currently get 0 extra XDP headroom as + * opposed to having legacy-rx off, where we process XDP + * packets going to stack via ixgbe_build_skb(). The latter + * provides us currently with 192 bytes of headroom. + * + * For ixgbe_construct_skb() mode it means that the + * xdp->data_meta will always point to xdp->data, since + * the helper cannot expand the head. Should this ever + * change in future for legacy-rx mode on, then lets also + * add xdp->data_meta handling here. + */ + + /* allocate a skb to store the frags */ + skb = napi_alloc_skb(&rx_ring->q_vector->napi, IXGBE_RX_HDR_SIZE); + if (unlikely(!skb)) + return NULL; + + if (size > IXGBE_RX_HDR_SIZE) { + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP)) + IXGBE_CB(skb)->dma = rx_buffer->dma; + + skb_add_rx_frag(skb, 0, rx_buffer->page, + xdp->data - page_address(rx_buffer->page), + size, truesize); +#if (PAGE_SIZE < 8192) + rx_buffer->page_offset ^= truesize; +#else + rx_buffer->page_offset += truesize; +#endif + } else { + memcpy(__skb_put(skb, size), + xdp->data, ALIGN(size, sizeof(long))); + rx_buffer->pagecnt_bias++; + } + + return skb; +} + +#ifdef HAVE_SWIOTLB_SKIP_CPU_SYNC +static struct sk_buff *ixgbe_build_skb(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *rx_buffer, + struct xdp_buff *xdp, + union ixgbe_adv_rx_desc *rx_desc) +{ +#ifdef HAVE_XDP_BUFF_DATA_META + unsigned int metasize = xdp->data - xdp->data_meta; + void *va = xdp->data_meta; +#else + void *va = xdp->data; +#endif +#if (PAGE_SIZE < 8192) + unsigned int truesize = ixgbe_rx_pg_size(rx_ring) / 2; +#else + unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + + SKB_DATA_ALIGN(xdp->data_end - + xdp->data_hard_start); +#endif + struct sk_buff *skb; + + /* prefetch first cache line of first page */ + prefetch(va); +#if L1_CACHE_BYTES < 128 + prefetch(va + L1_CACHE_BYTES); +#endif + + /* build an skb around the page buffer */ + skb = napi_build_skb(xdp->data_hard_start, truesize); + if (unlikely(!skb)) + return NULL; + + /* update pointers within the skb to store the data */ + skb_reserve(skb, xdp->data - xdp->data_hard_start); + __skb_put(skb, xdp->data_end - xdp->data); +#ifdef HAVE_XDP_BUFF_DATA_META + if (metasize) + skb_metadata_set(skb, metasize); +#endif + + /* record DMA address if this is the start of a chain of buffers */ + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP)) + IXGBE_CB(skb)->dma = rx_buffer->dma; + + /* update buffer offset */ +#if (PAGE_SIZE < 8192) + rx_buffer->page_offset ^= truesize; +#else + rx_buffer->page_offset += truesize; +#endif + + return skb; +} + +#endif /* HAVE_SWIOTLB_SKIP_CPU_SYNC */ + +static struct sk_buff * +ixgbe_run_xdp(struct ixgbe_adapter __maybe_unused *adapter, + struct ixgbe_ring __maybe_unused *rx_ring, + struct xdp_buff __maybe_unused *xdp) +{ + int result = IXGBE_XDP_PASS; +#ifdef HAVE_XDP_SUPPORT + struct bpf_prog *xdp_prog; + struct ixgbe_ring *ring; +#ifdef HAVE_XDP_FRAME_STRUCT + struct xdp_frame *xdpf; +#endif + int err; + u32 act; + + rcu_read_lock(); + xdp_prog = READ_ONCE(rx_ring->xdp_prog); + + if (!xdp_prog) + goto xdp_out; + +#ifdef HAVE_XDP_FRAME_STRUCT + prefetchw(xdp->data_hard_start); /* xdp_frame write */ +#endif + + act = bpf_prog_run_xdp(xdp_prog, xdp); + switch (act) { + case XDP_PASS: + break; + case XDP_TX: +#ifdef HAVE_XDP_FRAME_STRUCT + xdpf = xdp_convert_buff_to_frame(xdp); + if (unlikely(!xdpf)) { + result = IXGBE_XDP_CONSUMED; + break; + } +#endif + + ring = ixgbe_determine_xdp_ring(adapter); + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_lock(&ring->tx_lock); +#ifdef HAVE_XDP_FRAME_STRUCT + result = ixgbe_xmit_xdp_ring(ring, xdpf); +#else + result = ixgbe_xmit_xdp_ring(ring, xdp); +#endif + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_unlock(&ring->tx_lock); + + break; + case XDP_REDIRECT: + err = xdp_do_redirect(adapter->netdev, xdp, xdp_prog); + if (!err) { + result = IXGBE_XDP_REDIR; + } else { + result = IXGBE_XDP_CONSUMED; + } + break; + default: + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); + fallthrough; + case XDP_ABORTED: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + /* fallthrough -- handle aborts by dropping packet */ + fallthrough; + case XDP_DROP: + result = IXGBE_XDP_CONSUMED; + break; + } +xdp_out: + rcu_read_unlock(); +#endif /* HAVE_XDP_SUPPORT */ + + return ERR_PTR(-result); +} + +static unsigned int ixgbe_rx_frame_truesize(struct ixgbe_ring *rx_ring, + unsigned int size) +{ + unsigned int truesize; + +#if (PAGE_SIZE < 8192) + truesize = ixgbe_rx_pg_size(rx_ring) / 2; +#else + truesize = rx_ring->rx_offset ? + SKB_DATA_ALIGN(rx_ring->rx_offset + size) +#ifdef HAVE_XDP_BUFF_FRAME_SZ + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +#endif + : SKB_DATA_ALIGN(size); +#endif + return truesize; +} + +static void ixgbe_rx_buffer_flip(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *rx_buffer, + unsigned int size) +{ + unsigned int truesize = ixgbe_rx_frame_truesize(rx_ring, size); + +#if (PAGE_SIZE < 8192) + rx_buffer->page_offset ^= truesize; +#else + rx_buffer->page_offset += truesize; +#endif +} + +/** + * ixgbe_clean_rx_irq - Clean completed descriptors from Rx ring + * @q_vector: Structure containing interrupt and ring information + * @rx_ring: Rx descriptor ring to transact packets on + * @budget: Total limit on the number of packets to process + * + * This function processes completed descriptors from the Rx ring using a + * "bounce buffer" approach, which helps avoid IOMMU overhead by maintaining + * page mappings. It retrieves packets, processes them for checksum, VLAN, + * and protocol, and passes them up the network stack. The function also + * handles XDP processing and updates statistics for the number of packets + * and bytes processed. + * + * Return: The number of packets processed. + */ +static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *rx_ring, + int budget) +{ + unsigned int total_rx_bytes = 0; + int total_rx_packets = 0; + struct ixgbe_adapter *adapter = q_vector->adapter; +#if IS_ENABLED(CONFIG_FCOE) + int ddp_bytes; + unsigned int mss = 0; +#endif /* CONFIG_FCOE */ + u16 cleaned_count = ixgbe_desc_unused(rx_ring); + unsigned int offset = rx_ring->rx_offset; + unsigned int xdp_xmit = 0; + struct xdp_buff xdp; + + xdp.data = NULL; + xdp.data_end = NULL; +#ifdef HAVE_XDP_BUFF_RXQ + xdp.rxq = &rx_ring->xdp_rxq; +#endif + +#ifdef HAVE_XDP_BUFF_FRAME_SZ + /* Frame size depend on rx_ring setup when PAGE_SIZE=4K */ +#if (PAGE_SIZE < 8192) + xdp.frame_sz = ixgbe_rx_frame_truesize(rx_ring, 0); +#endif +#endif + + while (likely(total_rx_packets < budget)) { + union ixgbe_adv_rx_desc *rx_desc; + struct ixgbe_rx_buffer *rx_buffer; + struct sk_buff *skb; + unsigned int size; + + /* return some buffers to hardware, one at a time is too slow */ + if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + cleaned_count = 0; + } + + rx_desc = IXGBE_RX_DESC(rx_ring, rx_ring->next_to_clean); + size = le16_to_cpu(rx_desc->wb.upper.length); + if (!size) + break; + + /* This memory barrier is needed to keep us from reading + * any other fields out of the rx_desc until we know the + * descriptor has been written back + */ + dma_rmb(); + + rx_buffer = ixgbe_get_rx_buffer(rx_ring, rx_desc, &skb, size); + + /* retrieve a buffer from the ring */ + if (!skb) { + xdp.data = page_address(rx_buffer->page) + + rx_buffer->page_offset; +#ifdef HAVE_XDP_BUFF_DATA_META + xdp.data_meta = xdp.data; +#endif + xdp.data_hard_start = xdp.data - offset; + xdp.data_end = xdp.data + size; + +#ifdef HAVE_XDP_BUFF_FRAME_SZ +#if (PAGE_SIZE > 4096) + /* At larger PAGE_SIZE, frame_sz depend on len size */ + xdp.frame_sz = ixgbe_rx_frame_truesize(rx_ring, size); +#endif +#endif + skb = ixgbe_run_xdp(adapter, rx_ring, &xdp); + } + + if (IS_ERR(skb)) { + unsigned int xdp_res = -PTR_ERR(skb); + + if (xdp_res & (IXGBE_XDP_TX | IXGBE_XDP_REDIR)) { + xdp_xmit |= xdp_res; + ixgbe_rx_buffer_flip(rx_ring, rx_buffer, size); + } else { + rx_buffer->pagecnt_bias++; + } + total_rx_packets++; + total_rx_bytes += size; + } else if (skb) { + ixgbe_add_rx_frag(rx_ring, rx_buffer, skb, size); +#ifdef HAVE_SWIOTLB_SKIP_CPU_SYNC + } else if (ring_uses_build_skb(rx_ring)) { + skb = ixgbe_build_skb(rx_ring, rx_buffer, + &xdp, rx_desc); +#endif + } else { + skb = ixgbe_construct_skb(rx_ring, rx_buffer, + &xdp, rx_desc); + } + + /* exit if we failed to retrieve a buffer */ + if (!skb) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + rx_buffer->pagecnt_bias++; + break; + } + + ixgbe_put_rx_buffer(rx_ring, rx_buffer, skb); + cleaned_count++; + + /* place incomplete frames back on ring for completion */ + if (ixgbe_is_non_eop(rx_ring, rx_desc, skb)) + continue; + + /* verify the packet layout is correct */ + if (ixgbe_cleanup_headers(rx_ring, rx_desc, skb)) + continue; + + /* probably a little skewed due to removing CRC */ + total_rx_bytes += skb->len; + + /* populate checksum, timestamp, VLAN, and protocol */ + ixgbe_process_skb_fields(rx_ring, rx_desc, skb); + +#if IS_ENABLED(CONFIG_FCOE) + /* if ddp, not passing to ULD unless for FCP_RSP or error */ + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) { + ddp_bytes = ixgbe_fcoe_ddp(q_vector->adapter, + rx_desc, skb); + /* include DDPed FCoE data */ + if (ddp_bytes > 0) { + if (!mss) { + mss = netdev_ring(rx_ring)->mtu - + sizeof(struct fcoe_hdr) - + sizeof(struct fc_frame_header) - + sizeof(struct fcoe_crc_eof); + if (mss > 512) + mss &= ~511; + } + total_rx_bytes += ddp_bytes; + total_rx_packets += (mss >= TCP_MIN_MSS) ? + (int)DIV_ROUND_UP((u64)ddp_bytes, mss): + 1U; + } + if (!ddp_bytes) { + dev_kfree_skb_any(skb); +#ifndef NETIF_F_GRO + netdev_ring(rx_ring)->last_rx = jiffies; +#endif + continue; + } + } +#endif /* CONFIG_FCOE */ + +#ifdef HAVE_PTP_1588_CLOCK + if (likely(!q_vector->ptp_hold_rx_skb)) { + ixgbe_rx_skb(q_vector, rx_ring, rx_desc, skb); + + /* update budget accounting */ + total_rx_packets++; + } else { + q_vector->ptp_hold_rx_skb = false; + } +#else /* !HAVE_PTP_1588_CLOCK */ + ixgbe_rx_skb(q_vector, rx_ring, rx_desc, skb); + + /* update budget accounting */ + total_rx_packets++; +#endif /* HAVE_PTP_1588_CLOCK */ + } + + if (xdp_xmit & IXGBE_XDP_REDIR) + xdp_do_flush(); + + if (xdp_xmit & IXGBE_XDP_TX) { + struct ixgbe_ring *ring = ixgbe_determine_xdp_ring(adapter); + + ixgbe_xdp_ring_update_tail_locked(ring); + } + + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->stats.packets += total_rx_packets; + rx_ring->stats.bytes += total_rx_bytes; + u64_stats_update_end(&rx_ring->syncp); + q_vector->rx.total_packets += total_rx_packets; + q_vector->rx.total_bytes += total_rx_bytes; + + return total_rx_packets; +} + +#else /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ +/** + * ixgbe_clean_rx_irq - Clean completed descriptors from Rx ring - legacy + * @q_vector: structure containing interrupt and ring information + * @rx_ring: rx descriptor ring to transact packets on + * @budget: Total limit on number of packets to process + * + * This function provides a legacy approach to Rx interrupt + * handling. This version will perform better on systems with a low cost + * dma mapping API. + * + * Returns amount of work completed. + **/ +static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *rx_ring, + int budget) +{ + unsigned int total_rx_bytes = 0; + int total_rx_packets = 0; +#if IS_ENABLED(CONFIG_FCOE) + int ddp_bytes; + unsigned int mss = 0; +#endif /* CONFIG_FCOE */ + u16 len = 0; + u16 cleaned_count = ixgbe_desc_unused(rx_ring); + + while (likely(total_rx_packets < budget)) { + struct ixgbe_rx_buffer *rx_buffer; + union ixgbe_adv_rx_desc *rx_desc; + struct sk_buff *skb; + u16 ntc; + + /* return some buffers to hardware, one at a time is too slow */ + if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + cleaned_count = 0; + } + + ntc = rx_ring->next_to_clean; + rx_desc = IXGBE_RX_DESC(rx_ring, ntc); + rx_buffer = &rx_ring->rx_buffer_info[ntc]; + + if (!rx_desc->wb.upper.length) + break; + + /* This memory barrier is needed to keep us from reading + * any other fields out of the rx_desc until we know the + * descriptor has been written back + */ + dma_rmb(); + + skb = rx_buffer->skb; + + prefetch(skb->data); + + len = le16_to_cpu(rx_desc->wb.upper.length); + /* pull the header of the skb in */ + __skb_put(skb, len); + + /* + * Delay unmapping of the first packet. It carries the + * header information, HW may still access the header after + * the writeback. Only unmap it when EOP is reached + */ + if (!IXGBE_CB(skb)->head) { + IXGBE_CB(skb)->dma = rx_buffer->dma; + } else { + skb = ixgbe_merge_active_tail(skb); + dma_unmap_single(rx_ring->dev, + rx_buffer->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + } + + /* clear skb reference in buffer info structure */ + rx_buffer->skb = NULL; + rx_buffer->dma = 0; + + cleaned_count++; + + if (ixgbe_is_non_eop(rx_ring, rx_desc, skb)) + continue; + + dma_unmap_single(rx_ring->dev, + IXGBE_CB(skb)->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + + IXGBE_CB(skb)->dma = 0; + + if (ixgbe_close_active_frag_list(skb) && + !IXGBE_CB(skb)->append_cnt) { + /* if we got here without RSC the packet is invalid */ + dev_kfree_skb_any(skb); + continue; + } + + /* ERR_MASK will only have valid bits if EOP set */ + if (unlikely(ixgbe_test_staterr(rx_desc, + IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { + dev_kfree_skb_any(skb); + continue; + } + + /* probably a little skewed due to removing CRC */ + total_rx_bytes += skb->len; + + /* populate checksum, timestamp, VLAN, and protocol */ + ixgbe_process_skb_fields(rx_ring, rx_desc, skb); + +#if IS_ENABLED(CONFIG_FCOE) + /* if ddp, not passing to ULD unless for FCP_RSP or error */ + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) { + ddp_bytes = ixgbe_fcoe_ddp(q_vector->adapter, + rx_desc, skb); + /* include DDPed FCoE data */ + if (ddp_bytes > 0) { + if (!mss) { + mss = netdev_ring(rx_ring)->mtu - + sizeof(struct fcoe_hdr) - + sizeof(struct fc_frame_header) - + sizeof(struct fcoe_crc_eof); + if (mss > 512) + mss &= ~511; + } + total_rx_bytes += ddp_bytes; + total_rx_packets += (mss >= TCP_MIN_MSS) ? + (int)DIV_ROUND_UP((u64)ddp_bytes, mss): + 1U; + } + if (!ddp_bytes) { + dev_kfree_skb_any(skb); +#ifndef NETIF_F_GRO + netdev_ring(rx_ring)->last_rx = jiffies; +#endif + continue; + } + } + +#endif /* CONFIG_FCOE */ + ixgbe_rx_skb(q_vector, rx_ring, rx_desc, skb); + + /* update budget accounting */ + total_rx_packets++; + } + + rx_ring->stats.packets += total_rx_packets; + rx_ring->stats.bytes += total_rx_bytes; + q_vector->rx.total_packets += total_rx_packets; + q_vector->rx.total_bytes += total_rx_bytes; + + if (cleaned_count) + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + + return total_rx_packets; +} + +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ +#ifdef HAVE_NDO_BUSY_POLL +/** + * ixgbe_busy_poll_recv - Perform busy polling on RX rings + * @napi: NAPI structure associated with the RX queue vector + * + * This function performs busy polling on the receive (RX) rings of the network + * device. It processes incoming packets by cleaning the RX interrupt requests + * and returns the number of packets processed. The function must be called with + * local bottom halves disabled (`local_bh_disable()`). + * + * Return: The number of packets processed, or a negative error code if the + * device is down or busy. + */ +static int ixgbe_busy_poll_recv(struct napi_struct *napi) +{ + struct ixgbe_q_vector *q_vector = + container_of(napi, struct ixgbe_q_vector, napi); + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ixgbe_ring *ring; + int found = 0; + + if (test_bit(__IXGBE_DOWN, adapter->state)) + return LL_FLUSH_FAILED; + + if (!ixgbe_qv_lock_poll(q_vector)) + return LL_FLUSH_BUSY; + + ixgbe_for_each_ring(ring, q_vector->rx) { + found = ixgbe_clean_rx_irq(q_vector, ring, 4); +#ifdef BP_EXTENDED_STATS + if (found) + ring->stats.cleaned += found; + else + ring->stats.misses++; +#endif + if (found) + break; + } + + ixgbe_qv_unlock_poll(q_vector); + + return found; +} + +#endif /* HAVE_NDO_BUSY_POLL */ +/** + * ixgbe_configure_msix - Configure MSI-X hardware + * @adapter: board private structure + * + * ixgbe_configure_msix sets up the hardware to properly generate MSI-X + * interrupts. + **/ +static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) +{ + int v_idx; + u32 mask; + + /* Populate MSIX to EITR Select */ + if (adapter->num_vfs >= 32) { + u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, eitrsel); + } + + /* + * Populate the IVAR table and set the ITR values to the + * corresponding register. + */ + for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[v_idx]; + struct ixgbe_ring *ring; + + ixgbe_for_each_ring(ring, q_vector->rx) + ixgbe_set_ivar(adapter, 0, ring->reg_idx, v_idx); + + ixgbe_for_each_ring(ring, q_vector->tx) + ixgbe_set_ivar(adapter, 1, ring->reg_idx, v_idx); + + ixgbe_write_eitr(q_vector); + } + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX, + v_idx); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + ixgbe_set_ivar(adapter, -1, 1, v_idx); + break; + default: + break; + } + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950); + + /* set up to autoclear timer, and the vectors */ + mask = IXGBE_EIMS_ENABLE_MASK; + mask &= ~(IXGBE_EIMS_OTHER | + IXGBE_EIMS_MAILBOX | + IXGBE_EIMS_LSC); + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + mask &= ~IXGBE_EIMS_FW_EVENT; + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask); +} + +static inline bool ixgbe_container_is_rx(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring_container *rc) +{ + return &q_vector->rx == rc; +} + +/** + * ixgbe_update_itr - update the dynamic ITR value based on statistics + * @q_vector: structure containing interrupt and ring information + * @ring_container: structure containing ring performance data + * + * Stores a new ITR value based on packets and byte + * counts during the last interrupt. The advantage of per interrupt + * computation is faster updates and more accurate ITR for the current + * traffic pattern. Constants in this function were computed + * based on theoretical maximum wire speed and thresholds were set based + * on testing data as well as attempting to minimize response time + * while increasing bulk throughput. + **/ +static void ixgbe_update_itr(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring_container *ring_container) +{ + unsigned int itr = IXGBE_ITR_ADAPTIVE_MIN_USECS | + IXGBE_ITR_ADAPTIVE_LATENCY; + unsigned int avg_wire_size, packets, bytes; + unsigned long next_update = jiffies; + + /* If we don't have any rings just leave ourselves set for maximum + * possible latency so we take ourselves out of the equation. + */ + if (!ring_container->ring) + return; + + /* If we didn't update within up to 1 - 2 jiffies we can assume + * that either packets are coming in so slow there hasn't been + * any work, or that there is so much work that NAPI is dealing + * with interrupt moderation and we don't need to do anything. + */ + if (time_after(next_update, ring_container->next_update)) + goto clear_counts; + + packets = ring_container->total_packets; + bytes = ring_container->total_bytes; + + if (ixgbe_container_is_rx(q_vector, ring_container)) { + /* If Rx and there are 1 to 23 packets and bytes are less than + * 12112 assume insufficient data to use bulk rate limiting + * approach. Instead we will focus on simply trying to target + * receiving 8 times as much data in the next interrupt. + */ + if (packets && packets < 24 && bytes < 12112) { + itr = IXGBE_ITR_ADAPTIVE_LATENCY; + avg_wire_size = (bytes + packets * 24) * 2; + avg_wire_size = clamp_t(unsigned int, + avg_wire_size, 2560, 12800); + goto adjust_for_speed; + } + } + + /* Less than 48 packets we can assume that our current interrupt delay + * is only slightly too low. As such we should increase it by a small + * fixed amount. + */ + if (packets < 48) { + itr = (q_vector->itr >> 2) + IXGBE_ITR_ADAPTIVE_MIN_INC; + if (itr > IXGBE_ITR_ADAPTIVE_MAX_USECS) + itr = IXGBE_ITR_ADAPTIVE_MAX_USECS; + + /* If sample size is 0 - 7 we should probably switch + * to latency mode instead of trying to control + * things as though we are in bulk. + * + * Otherwise if the number of packets is less than 48 + * we should maintain whatever mode we are currently + * in. The range between 8 and 48 is the cross-over + * point between latency and bulk traffic. + */ + if (packets < 8) + itr += IXGBE_ITR_ADAPTIVE_LATENCY; + else + itr += ring_container->itr & IXGBE_ITR_ADAPTIVE_LATENCY; + goto clear_counts; + } + + /* Between 48 and 96 is our "goldilocks" zone where we are working + * out "just right". Just report that our current ITR is good for us. + */ + if (packets < 96) { + itr = q_vector->itr >> 2; + goto clear_counts; + } + + /* If packet count is 96 or greater we are likely looking at a slight + * overrun of the delay we want. Try halving our delay to see if that + * will cut the number of packets in half per interrupt. + */ + if (packets < 256) { + itr = q_vector->itr >> 3; + if (itr < IXGBE_ITR_ADAPTIVE_MIN_USECS) + itr = IXGBE_ITR_ADAPTIVE_MIN_USECS; + goto clear_counts; + } + + /* The paths below assume we are dealing with a bulk ITR since number + * of packets is 256 or greater. We are just going to have to compute + * a value and try to bring the count under control, though for smaller + * packet sizes there isn't much we can do as NAPI polling will likely + * be kicking in sooner rather than later. + */ + itr = IXGBE_ITR_ADAPTIVE_BULK; + + /* If packet counts are 256 or greater we can assume we have a gross + * overestimation of what the rate should be. Instead of trying to fine + * tune it just use the formula below to try and dial in an exact value + * give the current packet size of the frame. + */ + avg_wire_size = bytes / packets; + + /* The following is a crude approximation of: + * wmem_default / (size + overhead) = desired_pkts_per_int + * rate / bits_per_byte / (size + ethernet overhead) = pkt_rate + * (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value + * + * Assuming wmem_default is 212992 and overhead is 640 bytes per + * packet, (256 skb, 64 headroom, 320 shared info), we can reduce the + * formula down to + * + * (170 * (size + 24)) / (size + 640) = ITR + * + * We first do some math on the packet size and then finally bitshift + * by 8 after rounding up. We also have to account for PCIe link speed + * difference as ITR scales based on this. + */ + if (avg_wire_size <= 60) { + /* Start at 50k ints/sec */ + avg_wire_size = 5120; + } else if (avg_wire_size <= 316) { + /* 50K ints/sec to 16K ints/sec */ + avg_wire_size *= 40; + avg_wire_size += 2720; + } else if (avg_wire_size <= 1084) { + /* 16K ints/sec to 9.2K ints/sec */ + avg_wire_size *= 15; + avg_wire_size += 11452; + } else if (avg_wire_size <= 1980) { + /* 9.2K ints/sec to 8K ints/sec */ + avg_wire_size *= 5; + avg_wire_size += 22420; + } else { + /* plateau at a limit of 8K ints/sec */ + avg_wire_size = 32256; + } + +adjust_for_speed: + /* Resultant value is 256 times larger than it needs to be. This + * gives us room to adjust the value as needed to either increase + * or decrease the value based on link speeds of 10G, 2.5G, 1G, etc. + * + * Use addition as we have already recorded the new latency flag + * for the ITR value. + */ + switch (q_vector->adapter->link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + case IXGBE_LINK_SPEED_100_FULL: + default: + itr += DIV_ROUND_UP(avg_wire_size, + IXGBE_ITR_ADAPTIVE_MIN_INC * 256) * + IXGBE_ITR_ADAPTIVE_MIN_INC; + break; + case IXGBE_LINK_SPEED_2_5GB_FULL: + case IXGBE_LINK_SPEED_1GB_FULL: + case IXGBE_LINK_SPEED_10_FULL: + itr += DIV_ROUND_UP(avg_wire_size, + IXGBE_ITR_ADAPTIVE_MIN_INC * 64) * + IXGBE_ITR_ADAPTIVE_MIN_INC; + break; + } + + /* In the case of a latency specific workload only allow us to + * reduce the ITR by at most 2us. By doing this we should dial + * in so that our number of interrupts is no more than 2x the number + * of packets for the least busy workload. So for example in the case + * of a TCP worload the ack packets being received would set the + * the interrupt rate as they are a latency specific workload. + */ + if ((itr & IXGBE_ITR_ADAPTIVE_LATENCY) && itr < ring_container->itr) + itr = ring_container->itr - IXGBE_ITR_ADAPTIVE_MIN_INC; +clear_counts: + /* write back value - clamp to prevent automatic ITR bit interference + * and u8 field overflow. + */ + ring_container->itr = min_t(u16, itr, U8_MAX); + + /* next update should occur within next jiffy */ + ring_container->next_update = next_update + 1; + + ring_container->total_bytes = 0; + ring_container->total_packets = 0; +} + +/** + * ixgbe_write_eitr - write EITR register in hardware specific way + * @q_vector: structure containing interrupt and ring information + * + * This function is made to be called by ethtool and by the driver + * when it needs to update EITR registers at runtime. Hardware + * specific quirks/differences are taken care of here. + */ +void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) +{ + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ixgbe_hw *hw = &adapter->hw; + int v_idx = q_vector->v_idx; + u32 itr_reg = q_vector->itr & IXGBE_MAX_EITR; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + /* must write high and low 16 bits to reset counter */ + itr_reg |= (itr_reg << 16); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + /* + * set the WDIS bit to not clear the timer bits and cause an + * immediate assertion of the interrupt + */ + itr_reg |= IXGBE_EITR_CNT_WDIS; + break; + default: + break; + } + IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg); +} + +static void ixgbe_set_itr(struct ixgbe_q_vector *q_vector) +{ + u32 new_itr; + + ixgbe_update_itr(q_vector, &q_vector->tx); + ixgbe_update_itr(q_vector, &q_vector->rx); + + /* use the smallest value of new ITR delay calculations */ + new_itr = min(q_vector->rx.itr, q_vector->tx.itr); + + /* Clear latency flag if set, shift into correct position */ + new_itr &= IXGBE_ITR_ADAPTIVE_MASK_USECS; + new_itr <<= 2; + + if (new_itr != q_vector->itr) { + /* save the algorithm value here */ + q_vector->itr = new_itr; + + ixgbe_write_eitr(q_vector); + } +} + +/** + * ixgbe_check_overtemp_subtask - check for over temperature + * @adapter: pointer to adapter + **/ +static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr = adapter->interrupt_event; + s32 rc; + + if (test_bit(__IXGBE_DOWN, adapter->state)) + return; + + if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_EVENT)) + return; + + adapter->flags2 &= ~IXGBE_FLAG2_TEMP_SENSOR_EVENT; + + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: + /* + * Since the warning interrupt is for both ports + * we don't have to check if: + * - This interrupt wasn't for our port. + * - We may have missed the interrupt so always have to + * check if we got a LSC + */ + if (!(eicr & IXGBE_EICR_GPI_SDP0) && + !(eicr & IXGBE_EICR_LSC)) + return; + + if (!(eicr & IXGBE_EICR_LSC) && hw->mac.ops.check_link) { + u32 speed; + bool link_up = false; + + hw->mac.ops.check_link(hw, &speed, &link_up, false); + + if (link_up) + return; + } + + /* Check if this is not due to overtemp */ + if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP) + return; + + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + rc = hw->phy.ops.check_overtemp(hw); + if (rc != IXGBE_ERR_OVERTEMP) + return; + break; + default: + if (adapter->hw.mac.type >= ixgbe_mac_X540) + return; + if (!(eicr & IXGBE_EICR_GPI_SDP0_BY_MAC(hw))) + return; + break; + } + e_crit(drv, "%s\n", ixgbe_overheat_msg); + + adapter->interrupt_event = 0; +} + +/** + * ixgbe_check_mng_event - check for mng event + * @adapter: pointer to adapter + * @eicr: interrupt cause + **/ +static void ixgbe_check_mng_event(struct ixgbe_adapter *adapter, u32 eicr) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 fw_reset_cnt; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_E610: + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + if (eicr & IXGBE_EICR_MNG) { + /* Make sure that EICR.MNG event is the result of a + * reset after firmware update + */ + fw_reset_cnt = IXGBE_READ_REG(hw, IXGBE_FWRESETCNT); + if (hw->fw_rst_cnt < fw_reset_cnt) { + hw->fw_rst_cnt = fw_reset_cnt; + set_bit(__IXGBE_RESET_REQUESTED, + adapter->state); + ixgbe_service_event_schedule(adapter); + } + } + break; + default: + break; + } +} + +static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if ((adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) && + (eicr & IXGBE_EICR_GPI_SDP1)) { + e_crit(probe, "Fan has stopped, replace the adapter\n"); + /* write to clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); + } +} + +/** + * ixgbe_print_health_status_string - Print message for given FW health event + * @adapter: pointer to the adapter structure + * @hse: pointer to the health status element containing the health status code + * + * Print the error/diagnostic string in response to the given Health Status + * Event code. + */ +static void +ixgbe_print_health_status_string(struct ixgbe_adapter *adapter, + struct ixgbe_aci_cmd_health_status_elem *hse) +{ + u16 status_code = le16_to_cpu(hse->health_status_code); + u32 internal_data1 = le32_to_cpu(hse->internal_data1); + u32 internal_data2 = le32_to_cpu(hse->internal_data2); + struct net_device *netdev = adapter->netdev; + + switch (status_code) { + case IXGBE_ACI_HEALTH_STATUS_INFO_RECOVERY: + netdev_info(netdev, + "The device is in firmware recovery mode.\n"); + netdev_info(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_info(netdev, "Extended Error: 0x%08x.\n", + internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_FLASH_ACCESS: + netdev_err(netdev, "The flash chip cannot be accessed.\n"); + netdev_err(netdev, + "Possible Solution: If issue persists, call customer support.\n"); + netdev_err(netdev, "Access Type: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_NVM_AUTH: + netdev_err(netdev, "NVM authentication failed.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_OROM_AUTH: + netdev_err(netdev, "Option ROM authentication failed.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_DDP_AUTH: + netdev_err(netdev, "DDP package failed.\n"); + netdev_err(netdev, + "Possible Solution: Update to latest base driver and DDP package.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_NVM_COMPAT: + netdev_err(netdev, "NVM image is incompatible.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_OROM_COMPAT: + netdev_err(netdev, "Option ROM is incompatible.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, + "Expected PCI Device Id: 0x%08x and Expected Module Id: 0x%08x.\n", + internal_data1, internal_data2); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_DCB_MIB: + netdev_err(netdev, + "Supplied MIB file is invalid. DCB reverted to default configuration.\n"); + netdev_err(netdev, + "Possible Solution: Disable FW-LLDP and check DCBx system configuration.\n"); + netdev_err(netdev, "Port Number: %d and MIB Id: %d.\n", + internal_data1, internal_data2); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT: + case IXGBE_ACI_HEALTH_STATUS_ERR_UNKNOWN_MOD_LENIENT: + netdev_err(netdev, "An unsupported module was detected.\n"); + netdev_err(netdev, + "Possible Solution 1: Check your cable connection.\n"); + netdev_err(netdev, + "Possible Solution 2: Change or replace the module or cable.\n"); + netdev_err(netdev, + "Possible Solution 3: Manually set speed and duplex.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MOD_TYPE: + netdev_err(netdev, "Module type is not supported.\n"); + netdev_err(netdev, + "Possible Solution: Change or replace the module or cable.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MOD_QUAL: + netdev_err(netdev, "Module is not qualified.\n"); + netdev_err(netdev, + "Possible Solution 1: Check your cable connection.\n"); + netdev_err(netdev, + "Possible Solution 2: Change or replace the module or cable.\n"); + netdev_err(netdev, + "Possible Solution 3: Manually set speed and duplex.\n"); + netdev_err(netdev, "Port Number: %d\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MOD_COMM: + netdev_err(netdev, + "Device cannot communicate with the module.\n"); + netdev_err(netdev, + "Possible Solution 1: Check your cable connection.\n"); + netdev_err(netdev, + "Possible Solution 2: Change or replace the module or cable.\n"); + netdev_err(netdev, + "Possible Solution 3: Manually set speed and duplex.\n"); + netdev_err(netdev, + "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MOD_CONFLICT: + netdev_err(netdev, "Unresolved module conflict.\n"); + netdev_err(netdev, + "Possible Solution 1: Manually set speed/duplex or use Intel(R) Ethernet Port Configuration Tool to change the port option.\n"); + netdev_err(netdev, + "Possible Solution 2: If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MOD_NOT_PRESENT: + netdev_err(netdev, "Module is not present.\n"); + netdev_err(netdev, + "Possible Solution 1: Check that the module is inserted correctly.\n"); + netdev_err(netdev, + "Possible Solution 2: If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_INFO_MOD_UNDERUTILIZED: + netdev_info(netdev, "Underutilized module.\n"); + netdev_info(netdev, + "Possible Solution 1: Change or replace the module or cable.\n"); + netdev_info(netdev, + "Possible Solution 2: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n"); + netdev_info(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_INVALID_LINK_CFG: + netdev_err(netdev, "Invalid link configuration.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_PORT_ACCESS: + netdev_err(netdev, "Port hardware access error.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_PORT_UNREACHABLE: + netdev_err(netdev, "A port is unreachable.\n"); + netdev_err(netdev, + "Possible Solution 1: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n"); + netdev_err(netdev, + "Possible Solution 2: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_INFO_PORT_SPEED_MOD_LIMITED: + netdev_info(netdev, "Port speed is limited due to module.\n"); + netdev_info(netdev, + "Possible Solution: Change the module or use Intel(R) Ethernet Port Configuration Tool to configure the port option to match the current module speed.\n"); + netdev_info(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_PARALLEL_FAULT: + netdev_err(netdev, "A parallel fault was detected.\n"); + netdev_err(netdev, + "Possible Solution: Check link partner connection and configuration.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_INFO_PORT_SPEED_PHY_LIMITED: + netdev_info(netdev, + "Port speed is limited by PHY capabilities.\n"); + netdev_info(netdev, + "Possible Solution 1: Change the module to align to port option.\n"); + netdev_info(netdev, + "Possible Solution 2: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n"); + netdev_info(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_NETLIST_TOPO: + netdev_err(netdev, "LOM topology netlist is corrupted.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_NETLIST: + netdev_err(netdev, "Unrecoverable netlist error.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_TOPO_CONFLICT: + netdev_err(netdev, "Port topology conflict.\n"); + netdev_err(netdev, + "Possible Solution 1: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n"); + netdev_err(netdev, + "Possible Solution 2: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_LINK_HW_ACCESS: + netdev_err(netdev, "Unrecoverable hardware access error.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_LINK_RUNTIME: + netdev_err(netdev, "Unrecoverable runtime error.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_DNL_INIT: + netdev_err(netdev, + "Link management engine failed to initialize.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_PHY_FW_LOAD: + netdev_err(netdev, + "Failed to load the firmware image in the external PHY.\n"); + netdev_err(netdev, + "Possible Solution: Update to the latest NVM image.\n"); + netdev_err(netdev, "Port Number: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MOD_DIAGNOSTIC_FEATURE: + netdev_err(netdev, + "Module diagnostic feature not implemented.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_NVM_SEC_VIOLATION: + netdev_err(netdev, "NVM Security version violation.\n"); + netdev_err(netdev, + "Non-permitted Security version downgrade attempt, minimum version expected = 0x%08x.\n", + internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_OROM_SEC_VIOLATION: + netdev_err(netdev, "OROM Security version violation.\n"); + netdev_err(netdev, + "Non-permitted Security version downgrade attempt, minimum version expected = 0x%08x.\n", + internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_MNG_TIMEOUT: + netdev_err(netdev, "MNG timeout.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_BMC_RESET: + netdev_err(netdev, "Reset was triggered by Manageability.\n"); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_LAST_MNG_FAIL: + netdev_err(netdev, "Manageability command failed.\n"); + netdev_err(netdev, "MNG type: %d and Failed Opcode: 0x%08x.\n", + internal_data1, internal_data2); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_RESOURCE_ALLOC_FAIL: + netdev_err(netdev, "Resource allocation failure.\n"); + netdev_err(netdev, "Resource type: %d and PF ID: %d.\n", + internal_data1, internal_data2); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_FW_LOOP: + netdev_err(netdev, "Firmware experience resets in loop.\n"); + netdev_err(netdev, + "GLGEN_RSTAT information for EMPR/CORER/GLOBR. EMPR Reason (WD, Exception, ECC etc.): %d.\n", + internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_FW_PFR_FAIL: + netdev_err(netdev, "Firmware failed to execute PF reset.\n"); + netdev_err(netdev, "PF ID: %d.\n", internal_data1); + break; + case IXGBE_ACI_HEALTH_STATUS_ERR_LAST_FAIL_AQ: + netdev_err(netdev, "ACI command failure.\n"); + netdev_err(netdev, + "Failed command opcode: 0x%08x and PF ID: %d.\n", + internal_data1, internal_data2); + break; + default: + break; + } +} + +/** + * ixgbe_process_health_status_event - Process the health status event from FW + * @adapter: pointer to the adapter structure + * @e: event structure containing the Health Status Event opcode + * + * Decode the Health Status Events and print the associated messages + */ +static void ixgbe_process_health_status_event(struct ixgbe_adapter *adapter, + struct ixgbe_aci_event *e) +{ + struct ixgbe_aci_cmd_health_status_elem *health_info; + u16 health_status_elem_count; + int i; + + health_info = (struct ixgbe_aci_cmd_health_status_elem *)e->msg_buf; + health_status_elem_count = + le16_to_cpu(e->desc.params.get_health_status.health_status_count); + + /* In practice it's rare to encounter this event, and even more uncommon + * to observe multiple health status elements in a single message, but + * there's no boundary defined that separates an unlikely scenario from + * an erroneous one. If the count reported by the firmware is clearly + * incorrect then don't process the message and return. + */ + if (health_status_elem_count > (e->buf_len / sizeof(*health_info))) { + netdev_err(adapter->netdev, + "Received a health status event with invalid element count\n"); + return; + } + + for (i = 0; i < health_status_elem_count; i++) { + ixgbe_print_health_status_string(adapter, health_info); + health_info++; + } +} + +static void ixgbe_check_overtemp_event(struct ixgbe_adapter *adapter, u32 eicr) +{ + if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)) + return; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + /* + * Need to check link state so complete overtemp check + * on service task + */ + if (((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC)) && + (!test_bit(__IXGBE_DOWN, adapter->state))) { + adapter->interrupt_event = eicr; + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT; + ixgbe_service_event_schedule(adapter); + return; + } + return; + case ixgbe_mac_X550EM_a: + if (eicr & IXGBE_EICR_GPI_SDP0_X550EM_a) { + adapter->interrupt_event = eicr; + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT; + ixgbe_service_event_schedule(adapter); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, + IXGBE_EICR_GPI_SDP0_X550EM_a); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICR, + IXGBE_EICR_GPI_SDP0_X550EM_a); + } + return; + case ixgbe_mac_X550: + case ixgbe_mac_E610: + case ixgbe_mac_X540: + if (!(eicr & IXGBE_EICR_TS)) + return; + break; + default: + return; + } + + e_crit(drv, "%s\n", ixgbe_overheat_msg); +} + +static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); + + if (!ixgbe_is_sfp(hw)) + return; + if (hw->mac.type >= ixgbe_mac_X540) + eicr_mask = IXGBE_EICR_GPI_SDP0_X540; + + if (eicr & eicr_mask) { + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); + if (!test_bit(__IXGBE_DOWN, adapter->state)) { + adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; + adapter->sfp_poll_time = 0; + ixgbe_service_event_schedule(adapter); + } + } + + if (adapter->hw.mac.type == ixgbe_mac_82599EB && + (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); + if (!test_bit(__IXGBE_DOWN, adapter->state)) { + adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; + ixgbe_service_event_schedule(adapter); + } + } +} + +static void ixgbe_check_lsc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + adapter->lsc_int++; + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; + if (!test_bit(__IXGBE_DOWN, adapter->state)) { + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); + IXGBE_WRITE_FLUSH(hw); + ixgbe_service_event_schedule(adapter); + } +} + +/** + * ixgbe_check_phy_fw_load - check if PHY FW load failed + * @adapter: pointer to adapter structure + * @link_cfg_err: bitmap from the link info structure + * + * Check if external PHY FW load failed and print an error message if it did. + */ +static void ixgbe_check_phy_fw_load(struct ixgbe_adapter *adapter, + u8 link_cfg_err) +{ + if (!(link_cfg_err & IXGBE_ACI_LINK_EXTERNAL_PHY_LOAD_FAILURE)) { + adapter->flags2 &= ~IXGBE_FLAG2_PHY_FW_LOAD_FAILED; + return; + } + + if (adapter->flags2 & IXGBE_FLAG2_PHY_FW_LOAD_FAILED) + return; + + if (link_cfg_err & IXGBE_ACI_LINK_EXTERNAL_PHY_LOAD_FAILURE) { + netdev_err(adapter->netdev, "Device failed to load the FW for the external PHY. Please download and install the latest NVM for your device and try again\n"); + adapter->flags2 |= IXGBE_FLAG2_PHY_FW_LOAD_FAILED; + } +} + +/** + * ixgbe_check_module_power - check module power level + * @adapter: pointer to adapter structure + * @link_cfg_err: bitmap from the link info structure + * + * Check module power level returned by a previous call to aci_get_link_info + * and print error messages if module power level is not supported. + */ +static void ixgbe_check_module_power(struct ixgbe_adapter *adapter, + u8 link_cfg_err) +{ + /* if module power level is supported, clear the flag */ + if (!(link_cfg_err & (IXGBE_ACI_LINK_INVAL_MAX_POWER_LIMIT | + IXGBE_ACI_LINK_MODULE_POWER_UNSUPPORTED))) { + adapter->flags2 &= ~IXGBE_FLAG2_MOD_POWER_UNSUPPORTED; + return; + } + + /* if IXGBE_FLAG2_MOD_POWER_UNSUPPORTED was previously set and the + * above block didn't clear this bit, there's nothing to do + */ + if (adapter->flags2 & IXGBE_FLAG2_MOD_POWER_UNSUPPORTED) + return; + + if (link_cfg_err & IXGBE_ACI_LINK_INVAL_MAX_POWER_LIMIT) { + netdev_err(adapter->netdev, "The installed module is incompatible with the device's NVM image. Cannot start link\n"); + adapter->flags2 |= IXGBE_FLAG2_MOD_POWER_UNSUPPORTED; + } else if (link_cfg_err & IXGBE_ACI_LINK_MODULE_POWER_UNSUPPORTED) { + netdev_err(adapter->netdev, "The module's power requirements exceed the device's power supply. Cannot start link\n"); + adapter->flags2 |= IXGBE_FLAG2_MOD_POWER_UNSUPPORTED; + } +} + +/** + * ixgbe_check_link_cfg_err - check if link configuration failed + * @adapter: pointer to adapter structure + * @link_cfg_err: bitmap from the link info structure + * + * Print if any link configuration failure happens due to the value in the + * link_cfg_err parameter in the link info structure. + */ +static void ixgbe_check_link_cfg_err(struct ixgbe_adapter *adapter, + u8 link_cfg_err) +{ + ixgbe_check_module_power(adapter, link_cfg_err); + ixgbe_check_phy_fw_load(adapter, link_cfg_err); +} + +/** + * ixgbe_process_link_status_event - process the link event + * @adapter: pointer to adapter structure + * @link_up: true if the physical link is up and false if it is down + * @link_speed: current link speed received from the link event + * + * Return: 0 on success and negative on failure. + */ +static int +ixgbe_process_link_status_event(struct ixgbe_adapter *adapter, bool link_up, + u16 link_speed) +{ + struct ixgbe_hw *hw = &adapter->hw; + int status; + + /* update the link info structures and re-enable link events, + * don't bail on failure due to other book keeping needed + */ + status = ixgbe_update_link_info(hw); + if (status) + e_dev_err("Failed to update link status, err %d aq_err %d\n", + status, hw->aci.last_status); + + ixgbe_check_link_cfg_err(adapter, hw->link.link_info.link_cfg_err); + + /* Check if the link state is up after updating link info, and treat + * this event as an UP event since the link is actually UP now. + */ + if (hw->link.link_info.link_info & IXGBE_ACI_LINK_UP) + link_up = true; + + /* turn off PHY if media was removed */ + if (!(adapter->flags2 & IXGBE_FLAG2_NO_MEDIA) && + !(hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE)) { + adapter->flags2 |= IXGBE_FLAG2_NO_MEDIA; + } + + if ((link_up == adapter->link_up) && + link_up == netif_carrier_ok(adapter->netdev) && + link_speed == adapter->link_speed) + return IXGBE_SUCCESS; + + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; + ixgbe_watchdog_update_link(adapter); + + if (link_up) + ixgbe_watchdog_link_is_up(adapter); + else + ixgbe_watchdog_link_is_down(adapter); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_handle_link_status_event - handle link status event via ACI + * @adapter: pointer to adapter structure + * @e: event structure containing link status info + */ +static void +ixgbe_handle_link_status_event(struct ixgbe_adapter *adapter, + struct ixgbe_aci_event *e) +{ + struct ixgbe_aci_cmd_get_link_status_data *link_data; + u16 link_speed; + bool link_up; + + link_data = (struct ixgbe_aci_cmd_get_link_status_data *)e->msg_buf; + + link_up = !!(link_data->link_info & IXGBE_ACI_LINK_UP); + link_speed = le16_to_cpu(link_data->link_speed); + + if (ixgbe_process_link_status_event(adapter, link_up, link_speed)) + e_dev_warn("Could not process link status event"); +} + +/** + * ixgbe_schedule_fw_event - schedule Firmware event + * @adapter: pointer to the adapter structure + * + * If the adapter is not in down, removing or resetting state, + * an event is scheduled. + */ +static void ixgbe_schedule_fw_event(struct ixgbe_adapter *adapter) +{ + if (!ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + return; + + if (!test_bit(__IXGBE_DOWN, adapter->state) && + !test_bit(__IXGBE_REMOVING, adapter->state) && + !test_bit(__IXGBE_RESETTING, adapter->state)) { + adapter->flags2 |= IXGBE_FLAG2_FW_ASYNC_EVENT; + ixgbe_service_event_schedule(adapter); + } +} + +/** + * ixgbe_get_fwlog_data - copy the FW log data from ACI event + * @hw: pointer to private hardware struct + * @event: pointer to message from f/w + */ +static void +ixgbe_get_fwlog_data(struct ixgbe_hw *hw, struct ixgbe_aci_event *event) +{ + struct ixgbe_fwlog_data *fwlog; + + fwlog = &hw->fwlog_ring.rings[hw->fwlog_ring.tail]; + + memset(fwlog->data, 0, PAGE_SIZE); + fwlog->data_size = le16_to_cpu(event->desc.datalen); + + memcpy(fwlog->data, event->msg_buf, fwlog->data_size); + ixgbe_fwlog_ring_increment(&hw->fwlog_ring.tail, hw->fwlog_ring.size); + + if (ixgbe_fwlog_ring_full(&hw->fwlog_ring)) { + /* the rings are full so bump the head to create room */ + ixgbe_fwlog_ring_increment(&hw->fwlog_ring.head, + hw->fwlog_ring.size); + } +} + +/** + * ixgbe_handle_fw_event - handle Firmware event + * @adapter: pointer to the adapter structure + * + * Obtain an event from ACI and then + * depending on the type of event through the opcode + * correspondingly process it. + */ +static void ixgbe_handle_fw_event(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_aci_event event; + bool pending = false; + s32 status; + + if (!ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + return; + + if (adapter->flags2 & IXGBE_FLAG2_FW_ASYNC_EVENT) + adapter->flags2 &= ~IXGBE_FLAG2_FW_ASYNC_EVENT; + + event.buf_len = IXGBE_ACI_MAX_BUFFER_SIZE; + event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); + if (!event.msg_buf) + return; + + do { + u16 opcode; + + status = ixgbe_aci_get_event(hw, &event, &pending); + if (status) + break; + + opcode = le16_to_cpu(event.desc.opcode); + + switch (opcode) { + case ixgbe_aci_opc_get_link_status: + ixgbe_handle_link_status_event(adapter, &event); + break; + case ixgbe_aci_opc_get_health_status: + ixgbe_process_health_status_event(adapter, &event); + break; + case ixgbe_aci_opc_fw_logs_event: + ixgbe_get_fwlog_data(hw, &event); + break; + case ixgbe_aci_opc_temp_tca_event: + e_crit(drv, "%s\n", ixgbe_overheat_msg); + ixgbe_close(netdev); + break; + default: + e_warn(hw, "unknown FW async event captured\n"); + break; + } + + } while (pending); + + kfree(event.msg_buf); +} +static void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, u64 qmask) +{ + u32 mask; + struct ixgbe_hw *hw = &adapter->hw; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + mask = (IXGBE_EIMS_RTX_QUEUE & qmask); + IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + mask = (qmask & 0xFFFFFFFF); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); + mask = (qmask >> 32); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); + break; + default: + break; + } + /* skip the flush */ +} + + +/** + * ixgbe_irq_enable - Enable default interrupt generation settings + * @adapter: board private structure + * @queues: enable irqs for queues + * @flush: flush register write + **/ +static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, + bool flush) +{ + u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); + + /* don't reenable LSC while waiting for link */ + if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) + mask &= ~IXGBE_EIMS_LSC; + + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X550EM_a: + mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(&adapter->hw); + break; + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_E610: + mask |= IXGBE_EIMS_TS; + break; + default: + break; + } + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) + mask |= IXGBE_EIMS_GPI_SDP1; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + mask |= IXGBE_EIMS_GPI_SDP1; + mask |= IXGBE_EIMS_GPI_SDP2; + fallthrough; + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_E610: + mask |= IXGBE_EIMS_FW_EVENT; + fallthrough; + case ixgbe_mac_X550EM_a: + if (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_X_SFP || + adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_SFP || + adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) + mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(&adapter->hw); + if (adapter->hw.phy.type == ixgbe_phy_x550em_ext_t) + mask |= IXGBE_EICR_GPI_SDP0_X540; + mask |= IXGBE_EIMS_ECC; + mask |= IXGBE_EIMS_MAILBOX; +#ifdef HAVE_PTP_1588_CLOCK + mask |= IXGBE_EIMS_TIMESYNC; +#endif + + break; + default: + break; + } + + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && + !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) + mask |= IXGBE_EIMS_FLOW_DIR; + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); + if (queues) + ixgbe_irq_enable_queues(adapter, ~0); + if (flush) + IXGBE_WRITE_FLUSH(&adapter->hw); +} + +static irqreturn_t ixgbe_msix_other(int __always_unused irq, void *data) +{ + struct ixgbe_adapter *adapter = data; + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr; + + /* + * Workaround for Silicon errata #26 on 82598. Use clear-by-write + * instead of clear-by-read. Reading with EICS will return the + * interrupt causes without clearing, which later be done + * with the write to EICR. + */ + eicr = IXGBE_READ_REG(hw, IXGBE_EICS); + + /* The lower 16bits of the EICR register are for the queue interrupts + * which should be masked here in order to not accidently clear them if + * the bits are high when ixgbe_msix_other is called. There is a race + * condition otherwise which results in possible performance loss + * especially if the ixgbe_msix_other interrupt is triggering + * consistently (as it would when PPS is turned on for the X540 device) + */ + eicr &= 0xFFFF0000; + + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); + + if (eicr & IXGBE_EICR_LSC) + ixgbe_check_lsc(adapter); + + if (eicr & IXGBE_EICR_MAILBOX) + ixgbe_msg_task(adapter); + if (eicr & IXGBE_EICR_FW_EVENT) + ixgbe_schedule_fw_event(adapter); + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + if (hw->phy.type == ixgbe_phy_x550em_ext_t && + (eicr & IXGBE_EICR_GPI_SDP0_X540)) { + adapter->flags2 |= IXGBE_FLAG2_PHY_INTERRUPT; + ixgbe_service_event_schedule(adapter); + IXGBE_WRITE_REG(hw, IXGBE_EICR, + IXGBE_EICR_GPI_SDP0_X540); + } + if (eicr & IXGBE_EICR_ECC) { + e_info(link, "Received unrecoverable ECC Err," + "initiating reset.\n"); + set_bit(__IXGBE_RESET_REQUESTED, adapter->state); + ixgbe_service_event_schedule(adapter); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); + } +#ifdef HAVE_TX_MQ + /* Handle Flow Director Full threshold interrupt */ + if (eicr & IXGBE_EICR_FLOW_DIR) { + int reinit_count = 0; + int i; + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *ring = adapter->tx_ring[i]; + if (test_and_clear_bit( + __IXGBE_TX_FDIR_INIT_DONE, + &ring->state)) + reinit_count++; + } + if (reinit_count) { + /* no more flow director interrupts until + * after init + */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, + IXGBE_EIMC_FLOW_DIR); + adapter->flags2 |= + IXGBE_FLAG2_FDIR_REQUIRES_REINIT; + ixgbe_service_event_schedule(adapter); + } + } +#endif + ixgbe_check_sfp_event(adapter, eicr); + ixgbe_check_overtemp_event(adapter, eicr); + ixgbe_check_mng_event(adapter, eicr); + break; + default: + break; + } + + ixgbe_check_fan_failure(adapter, eicr); + +#ifdef HAVE_PTP_1588_CLOCK + if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) + ixgbe_ptp_eicr_timesync(adapter); +#endif + + /* re-enable the original interrupt state, no lsc, no queues */ + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_enable(adapter, false, false); + + return IRQ_HANDLED; +} + +static irqreturn_t ixgbe_msix_clean_rings(int __always_unused irq, void *data) +{ + struct ixgbe_q_vector *q_vector = data; + + /* EIAM disabled interrupts (on this vector) for us */ + + if (q_vector->rx.ring || q_vector->tx.ring) + napi_schedule_irqoff(&q_vector->napi); + + return IRQ_HANDLED; +} + +/** + * ixgbe_poll - NAPI polling RX/TX cleanup routine + * @napi: napi struct with our devices info in it + * @budget: amount of work driver is allowed to do this pass, in packets + * + * Clean all queues associated with a q_vector. + **/ +int ixgbe_poll(struct napi_struct *napi, int budget) +{ + struct ixgbe_q_vector *q_vector = + container_of(napi, struct ixgbe_q_vector, napi); + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ixgbe_ring *ring; + int per_ring_budget, work_done = 0; + bool clean_complete = true; + +#if IS_ENABLED(CONFIG_DCA) + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_dca(q_vector); +#endif /* CONFIG_DCA */ + + ixgbe_for_each_ring(ring, q_vector->tx) { +#ifdef HAVE_AF_XDP_ZC_SUPPORT + bool wd = ring->xsk_pool ? + ixgbe_clean_xdp_tx_irq(q_vector, ring) : + ixgbe_clean_tx_irq(q_vector, ring, budget); + if (!wd) +#else + if (!ixgbe_clean_tx_irq(q_vector, ring, budget)) +#endif + clean_complete = false; + } + +#ifdef HAVE_NDO_BUSY_POLL + if (test_bit(NAPI_STATE_NPSVC, &napi->state)) + return budget; + + /* Exit if we are called by netpoll or busy polling is active */ + if ((budget <= 0) || !ixgbe_qv_lock_napi(q_vector)) + return budget; +#else + /* Exit if we are called by netpoll */ + if (budget <= 0) + return budget; +#endif + +#ifdef HAVE_PTP_1588_CLOCK + work_done += ixgbe_ptp_rx_complete_skb_e600(q_vector, &budget); + if (budget <= 0) + return budget; + +#endif /* HAVE_PTP_1588_CLOCK */ + /* attempt to distribute budget to each queue fairly, but don't allow + * the budget to go below 1 because we'll exit polling */ + if (q_vector->rx.count > 1) + per_ring_budget = max(budget/q_vector->rx.count, 1); + else + per_ring_budget = budget; + + ixgbe_for_each_ring(ring, q_vector->rx) { +#ifdef HAVE_AF_XDP_ZC_SUPPORT + int cleaned = ring->xsk_pool ? + ixgbe_clean_rx_irq_zc(q_vector, ring, + per_ring_budget) : + ixgbe_clean_rx_irq(q_vector, ring, + per_ring_budget); +#else + int cleaned = ixgbe_clean_rx_irq(q_vector, ring, + per_ring_budget); +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ + work_done += cleaned; + if (cleaned >= per_ring_budget) + clean_complete = false; + } + +#ifdef HAVE_NDO_BUSY_POLL + ixgbe_qv_unlock_napi(q_vector); + +#endif +#ifndef HAVE_NETDEV_NAPI_LIST + if (!netif_running(adapter->netdev)) + clean_complete = true; + +#endif + /* If all work not completed, return budget and keep polling */ + if (!clean_complete) + return budget; + /* all work done, exit the polling mode */ + if (likely(napi_complete_done(napi, work_done))) { + if (adapter->rx_itr_setting == 1) + ixgbe_set_itr(q_vector); + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_enable_queues(adapter, + ((u64)1 << q_vector->v_idx)); + } + return min(work_done, budget - 1); +} + +/** + * ixgbe_request_msix_irqs - Initialize MSI-X interrupts + * @adapter: board private structure + * + * ixgbe_request_msix_irqs allocates MSI-X vectors and requests + * interrupts from the kernel. + **/ +static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + unsigned int ri = 0, ti = 0; + int vector, err; + + for (vector = 0; vector < adapter->num_q_vectors; vector++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[vector]; + struct msix_entry *entry = &adapter->msix_entries[vector]; + + if (q_vector->tx.ring && q_vector->rx.ring) { + snprintf(q_vector->name, sizeof(q_vector->name), + "%s-TxRx-%u", netdev->name, ri++); + ti++; + } else if (q_vector->rx.ring) { + snprintf(q_vector->name, sizeof(q_vector->name), + "%s-rx-%u", netdev->name, ri++); + } else if (q_vector->tx.ring) { + snprintf(q_vector->name, sizeof(q_vector->name), + "%s-tx-%u", netdev->name, ti++); + } else { + /* skip this unused q_vector */ + continue; + } + err = request_irq(entry->vector, &ixgbe_msix_clean_rings, 0, + q_vector->name, q_vector); + if (err) { + e_err(probe, "request_irq failed for MSIX interrupt '%s' " + "Error: %d\n", q_vector->name, err); + goto free_queue_irqs; + } + } + + err = request_irq(adapter->msix_entries[vector].vector, + ixgbe_msix_other, 0, netdev->name, adapter); + if (err) { + e_err(probe, "request_irq for msix_other failed: %d\n", err); + goto free_queue_irqs; + } + + return IXGBE_SUCCESS; + +free_queue_irqs: + while (vector) { + vector--; + free_irq(adapter->msix_entries[vector].vector, + adapter->q_vector[vector]); + } + adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; + pci_disable_msix(adapter->pdev); + kfree(adapter->msix_entries); + adapter->msix_entries = NULL; + return err; +} + +/** + * ixgbe_intr - legacy mode Interrupt Handler + * @irq: interrupt number + * @data: pointer to a network interface device structure + **/ +static irqreturn_t ixgbe_intr(int __always_unused irq, void *data) +{ + struct ixgbe_adapter *adapter = data; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; + u32 eicr; + + /* + * Workaround for silicon errata #26 on 82598. Mask the interrupt + * before the read of EICR. + */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); + + /* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read + * therefore no explicit interrupt disable is necessary */ + eicr = IXGBE_READ_REG(hw, IXGBE_EICR); + if (!eicr) { + /* + * shared interrupt alert! + * make sure interrupts are enabled because the read will + * have disabled interrupts due to EIAM + * finish the workaround of silicon errata on 82598. Unmask + * the interrupt that we masked before the EICR read. + */ + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_enable(adapter, true, true); + return IRQ_NONE; /* Not our interrupt */ + } + + if (eicr & IXGBE_EICR_LSC) + ixgbe_check_lsc(adapter); + + if (eicr & IXGBE_EICR_FW_EVENT) + ixgbe_schedule_fw_event(adapter); + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + if (eicr & IXGBE_EICR_ECC) { + e_info(link, "Received unrecoverable ECC Err," + "initiating reset.\n"); + set_bit(__IXGBE_RESET_REQUESTED, adapter->state); + ixgbe_service_event_schedule(adapter); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); + } + ixgbe_check_sfp_event(adapter, eicr); + ixgbe_check_overtemp_event(adapter, eicr); + ixgbe_check_mng_event(adapter, eicr); + break; + default: + break; + } + + ixgbe_check_fan_failure(adapter, eicr); +#ifdef HAVE_PTP_1588_CLOCK + if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) + ixgbe_ptp_eicr_timesync(adapter); +#endif + + /* would disable interrupts here but EIAM disabled it */ + napi_schedule_irqoff(&q_vector->napi); + + /* + * re-enable link(maybe) and non-queue interrupts, no flush. + * ixgbe_poll will re-enable the queue interrupts + */ + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_enable(adapter, false, false); + + return IRQ_HANDLED; +} + +/** + * ixgbe_request_irq - initialize interrupts + * @adapter: board private structure + * + * Attempts to configure interrupts using the best available + * capabilities of the hardware and kernel. + **/ +static int ixgbe_request_irq(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int err; + + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) + err = ixgbe_request_msix_irqs(adapter); + else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) + err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0, + netdev->name, adapter); + else + err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED, + netdev->name, adapter); + + if (err) + e_err(probe, "request_irq failed, Error %d\n", err); + + return err; +} + +static void ixgbe_free_irq(struct ixgbe_adapter *adapter) +{ + int vector; + + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { + free_irq(adapter->pdev->irq, adapter); + return; + } + + if (!adapter->msix_entries) + return; + + for (vector = 0; vector < adapter->num_q_vectors; vector++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[vector]; + struct msix_entry *entry = &adapter->msix_entries[vector]; + + /* free only the irqs that were actually requested */ + if (!q_vector->rx.ring && !q_vector->tx.ring) + continue; + + free_irq(entry->vector, q_vector); + } + + free_irq(adapter->msix_entries[vector].vector, adapter); +} + +/** + * ixgbe_irq_disable - Mask off interrupt generation on the NIC + * @adapter: board private structure + **/ +static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) +{ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); + break; + default: + break; + } + IXGBE_WRITE_FLUSH(&adapter->hw); + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + int vector; + + for (vector = 0; vector < adapter->num_q_vectors; vector++) + synchronize_irq(adapter->msix_entries[vector].vector); + + synchronize_irq(adapter->msix_entries[vector++].vector); + } else { + synchronize_irq(adapter->pdev->irq); + } +} + +/** + * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts + * @adapter: board private structure + * + **/ +static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) +{ + struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; + + ixgbe_write_eitr(q_vector); + + ixgbe_set_ivar(adapter, 0, 0, 0); + ixgbe_set_ivar(adapter, 1, 0, 0); + + e_info(hw, "Legacy interrupt IVAR setup done\n"); +} + +/** + * ixgbe_configure_tx_ring - Configure 8259x Tx ring after Reset + * @adapter: board private structure + * @ring: structure containing ring specific data + * + * Configure the Tx descriptor ring after a reset. + **/ +void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 tdba = ring->dma; + int wait_loop = 10; + u32 txdctl = IXGBE_TXDCTL_ENABLE; + u8 reg_idx = ring->reg_idx; + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + ring->xsk_pool = NULL; + if (ring_is_xdp(ring)) + ring->xsk_pool = ixgbe_xsk_umem(adapter, ring); +#endif + /* disable queue to avoid issues while updating state */ + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH); + IXGBE_WRITE_FLUSH(hw); + + IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx), tdba & DMA_BIT_MASK(32)); + IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), tdba >> 32); + IXGBE_WRITE_REG(hw, IXGBE_TDLEN(reg_idx), + ring->count * sizeof(union ixgbe_adv_tx_desc)); + + /* disable head writeback */ + IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(reg_idx), 0); + + /* reset head and tail pointers */ + IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0); + ring->tail = adapter->io_addr + IXGBE_TDT(reg_idx); + + /* reset ntu and ntc to place SW in sync with hardwdare */ + ring->next_to_clean = 0; + ring->next_to_use = 0; + + /* + * set WTHRESH to encourage burst writeback, it should not be set + * higher than 1 when: + * - ITR is 0 as it could cause false TX hangs + * - ITR is set to > 100k int/sec and BQL is enabled + * + * In order to avoid issues WTHRESH + PTHRESH should always be equal + * to or less than the number of on chip descriptors, which is + * currently 40. + */ + if (!ring->q_vector || (ring->q_vector->itr < IXGBE_100K_ITR)) + txdctl |= (1 << 16); /* WTHRESH = 1 */ + else + txdctl |= (8 << 16); /* WTHRESH = 8 */ + + /* + * Setting PTHRESH to 32 both improves performance + * and avoids a TX hang with DFP enabled + */ + txdctl |= (1 << 8) | /* HTHRESH = 1 */ + 32; /* PTHRESH = 32 */ + + /* reinitialize flowdirector state */ + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { + ring->atr_sample_rate = adapter->atr_sample_rate; + ring->atr_count = 0; + set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state); + } else { + ring->atr_sample_rate = 0; + } + + /* initialize XPS */ + if (!test_and_set_bit(__IXGBE_TX_XPS_INIT_DONE, &ring->state)) { + struct ixgbe_q_vector *q_vector = ring->q_vector; + + if (q_vector) + netif_set_xps_queue(adapter->netdev, + &q_vector->affinity_mask, + ring->queue_index); + } + + clear_bit(__IXGBE_HANG_CHECK_ARMED, &ring->state); + + /* reinitialize tx_buffer_info */ + memset(ring->tx_buffer_info, 0, + sizeof(struct ixgbe_tx_buffer) * ring->count); + + /* enable queue */ + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl); + + /* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + /* poll to verify queue is enabled */ + do { + msleep(1); + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); + if (!wait_loop) + hw_dbg(hw, "Could not enable Tx Queue %d\n", reg_idx); +} + +static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rttdcs, mtqc; + u8 tcs = netdev_get_num_tc(adapter->netdev); + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + /* disable the arbiter while setting MTQC */ + rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + rttdcs |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + + /* set transmit pool layout */ + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) { + mtqc = IXGBE_MTQC_VT_ENA; + if (tcs > 4) + mtqc |= IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ; + else if (tcs > 1) + mtqc |= IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ; + else if (adapter->ring_feature[RING_F_VMDQ].mask == + IXGBE_82599_VMDQ_4Q_MASK) + mtqc |= IXGBE_MTQC_32VF; + else + mtqc |= IXGBE_MTQC_64VF; + } else { + if (tcs > 4) { + mtqc = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ; + } else if (tcs > 1) { + mtqc = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ; + } else { + u8 max_txq = adapter->num_tx_queues + + adapter->num_xdp_queues; + if (max_txq > 63) + mtqc = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ; + else + mtqc = IXGBE_MTQC_64Q_1PB; + } + } + + IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc); + + /* Enable Security TX Buffer IFG for multiple pb */ + if (tcs) { + u32 sectx = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); + sectx |= IXGBE_SECTX_DCB; + IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, sectx); + } + + /* re-enable the arbiter */ + rttdcs &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); +} + +/** + * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset + * @adapter: board private structure + * + * Configure the Tx unit of the MAC after a reset. + **/ +static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 dmatxctl; + u32 i; + +#ifdef CONFIG_NETDEVICES_MULTIQUEUE + if (adapter->num_tx_queues > 1) + adapter->netdev->features |= NETIF_F_MULTI_QUEUE; + else + adapter->netdev->features &= ~NETIF_F_MULTI_QUEUE; + +#endif + ixgbe_setup_mtqc(adapter); + + if (hw->mac.type != ixgbe_mac_82598EB) { + /* DMATXCTL.EN must be before Tx queues are enabled */ + dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + dmatxctl |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); + } + + /* Setup the HW Tx Head and Tail descriptor pointers */ + for (i = 0; i < adapter->num_tx_queues; i++) + ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); + for (i = 0; i < adapter->num_xdp_queues; i++) + ixgbe_configure_tx_ring(adapter, adapter->xdp_ring[i]); +} + +static void ixgbe_enable_rx_drop(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u8 reg_idx = ring->reg_idx; + u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx)); + + srrctl |= IXGBE_SRRCTL_DROP_EN; + + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); +} + +static void ixgbe_disable_rx_drop(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u8 reg_idx = ring->reg_idx; + u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx)); + + srrctl &= ~IXGBE_SRRCTL_DROP_EN; + + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); +} + +void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter) +{ + int i; + bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; + +#ifdef HAVE_DCBNL_IEEE + if (adapter->ixgbe_ieee_pfc) + pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); + +#endif + /* + * We should set the drop enable bit if: + * SR-IOV is enabled + * or + * Number of Rx queues > 1 and flow control is disabled + * + * This allows us to avoid head of line blocking for security + * and performance reasons. + */ + if (adapter->num_vfs || (adapter->num_rx_queues > 1 && + !(adapter->hw.fc.current_mode & ixgbe_fc_tx_pause) && !pfc_en)) { + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_enable_rx_drop(adapter, adapter->rx_ring[i]); + } else { + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_disable_rx_drop(adapter, adapter->rx_ring[i]); + } +} + +static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 srrctl; + u8 reg_idx = rx_ring->reg_idx; + + if (hw->mac.type == ixgbe_mac_82598EB) { + u16 mask = adapter->ring_feature[RING_F_RSS].mask; + + /* program one srrctl register per VMDq index */ + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) + mask = adapter->ring_feature[RING_F_VMDQ].mask; + + /* + * if VMDq is not active we must program one srrctl register + * per RSS queue since we have enabled RDRXCTL.MVMEN + */ + reg_idx &= mask; + + /* divide by the first bit of the mask to get the indices */ + if (reg_idx) + reg_idx /= ((~mask) + 1) & mask; + } + + /* configure header buffer length, needed for RSC */ + srrctl = IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT; + + /* configure the packet buffer length */ +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >> + IXGBE_SRRCTL_BSIZEPKT_SHIFT; +#else +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (rx_ring->xsk_pool) { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + u32 xsk_buf_len = rx_ring->xsk_pool->chunk_size_nohr - + XDP_PACKET_HEADROOM; +#else + u32 xsk_buf_len = xsk_pool_get_rx_frame_size(rx_ring->xsk_pool); +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + + /* If the MAC support setting RXDCTL.RLPML, the + * SRRCTL[n].BSIZEPKT is set to PAGE_SIZE and + * RXDCTL.RLPML is set to the actual UMEM buffer + * size. If not, then we are stuck with a 1k buffer + * size resolution. In this case frames larger than + * the UMEM buffer size viewed in a 1k resolution will + * be dropped. + */ + if (hw->mac.type != ixgbe_mac_82599EB) + srrctl |= PAGE_SIZE >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + else + srrctl |= xsk_buf_len >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + } else if (test_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state)) { +#else + if (test_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state)) { +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ + srrctl |= IXGBE_RXBUFFER_3K >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + } else { + srrctl |= IXGBE_RXBUFFER_2K >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + } +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + + /* configure descriptor type */ + srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; + + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); +} + +/** + * ixgbe_rss_indir_tbl_entries - Return RSS indirection table entries + * @adapter: device handle + * + * - 82598/82599/X540: 128 + * - X550(non-SRIOV mode): 512 + * - X550(SRIOV mode): 64 + */ +u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.mac.type < ixgbe_mac_X550) + return 128; + else if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + return 64; + else + return 512; +} + +/** + * ixgbe_store_key - Write the RSS key to HW + * @adapter: device handle + * + * Write the RSS key stored in adapter.rss_key to HW. + */ +void ixgbe_store_key(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + + for (i = 0; i < 10; i++) + IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), adapter->rss_key[i]); +} + +/** + * ixgbe_init_rss_key - Initialize adapter RSS key + * @adapter: device handle + * + * Allocates and initializes the RSS key if it is not allocated. + **/ +static inline int ixgbe_init_rss_key(struct ixgbe_adapter *adapter) +{ + u32 *rss_key; + + if (!adapter->rss_key) { + rss_key = kzalloc(IXGBE_RSS_KEY_SIZE, GFP_KERNEL); + if (unlikely(!rss_key)) + return -ENOMEM; + + netdev_rss_key_fill(rss_key, IXGBE_RSS_KEY_SIZE); + adapter->rss_key = rss_key; + } + + return 0; +} + +/** + * ixgbe_store_reta - Write the RETA table to HW + * @adapter: device handle + * + * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW. + */ +void ixgbe_store_reta(struct ixgbe_adapter *adapter) +{ + u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter); + struct ixgbe_hw *hw = &adapter->hw; + u32 reta = 0; + u32 indices_multi; + u8 *indir_tbl = adapter->rss_indir_tbl; + + /* Fill out the redirection table as follows: + * - 82598: 8 bit wide entries containing pair of 4 bit RSS + * indices. + * - 82599/X540: 8 bit wide entries containing 4 bit RSS index + * - X550: 8 bit wide entries containing 6 bit RSS index + */ + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + indices_multi = 0x11; + else + indices_multi = 0x1; + + /* Write redirection table to HW */ + for (i = 0; i < reta_entries; i++) { + reta |= indices_multi * indir_tbl[i] << (i & 0x3) * 8; + if ((i & 3) == 3) { + if (i < 128) + IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); + else + IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32), + reta); + reta = 0; + } + } +} + +/** + * ixgbe_store_vfreta - Write the RETA table to HW (x550 devices in SRIOV mode) + * @adapter: device handle + * + * Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW. + */ +static void ixgbe_store_vfreta(struct ixgbe_adapter *adapter) +{ + u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter); + struct ixgbe_hw *hw = &adapter->hw; + u32 vfreta = 0; + unsigned int pf_pool = adapter->num_vfs; + + /* Write redirection table to HW */ + for (i = 0; i < reta_entries; i++) { + vfreta |= (u32)adapter->rss_indir_tbl[i] << (i & 0x3) * 8; + if ((i & 3) == 3) { + IXGBE_WRITE_REG(hw, IXGBE_PFVFRETA(i >> 2, pf_pool), + vfreta); + vfreta = 0; + } + } +} + +static void ixgbe_setup_reta(struct ixgbe_adapter *adapter) +{ + u32 i, j; + u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter); + u16 rss_i = adapter->ring_feature[RING_F_RSS].indices; + + /* Program table for at least 4 queues w/ SR-IOV so that VFs can + * make full use of any rings they may have. We will use the + * PSRTYPE register to control how many rings we use within the PF. + */ + if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && (rss_i < 4)) + rss_i = 4; + + /* Fill out hash function seeds */ + ixgbe_store_key(adapter); + + /* Fill out redirection table */ + memset(adapter->rss_indir_tbl, 0, sizeof(adapter->rss_indir_tbl)); + + for (i = 0, j = 0; i < reta_entries; i++, j++) { + if (j == rss_i) + j = 0; + + adapter->rss_indir_tbl[i] = j; + } + + ixgbe_store_reta(adapter); +} + +static void ixgbe_setup_vfreta(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u16 rss_i = adapter->ring_feature[RING_F_RSS].indices; + unsigned int pf_pool = adapter->num_vfs; + int i, j; + + /* Fill out hash function seeds */ + for (i = 0; i < 10; i++) + IXGBE_WRITE_REG(hw, IXGBE_PFVFRSSRK(i, pf_pool), + *(adapter->rss_key + i)); + + /* Fill out the redirection table */ + for (i = 0, j = 0; i < 64; i++, j++) { + if (j == rss_i) + j = 0; + + adapter->rss_indir_tbl[i] = j; + } + + ixgbe_store_vfreta(adapter); +} + + +static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rxcsum; + u32 mrqc = 0, rss_field = 0; + u32 vfmrqc = 0; + + /* Disable indicating checksum in descriptor, enables RSS hash */ + rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); + rxcsum |= IXGBE_RXCSUM_PCSD; + IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + if (adapter->ring_feature[RING_F_RSS].mask) + mrqc = IXGBE_MRQC_RSSEN; + } else { + u8 tcs = netdev_get_num_tc(adapter->netdev); + + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) { + if (tcs > 4) + mrqc = IXGBE_MRQC_VMDQRT8TCEN; /* 8 TCs */ + else if (tcs > 1) + mrqc = IXGBE_MRQC_VMDQRT4TCEN; /* 4 TCs */ + else if (adapter->ring_feature[RING_F_VMDQ].mask == + IXGBE_82599_VMDQ_4Q_MASK) + mrqc = IXGBE_MRQC_VMDQRSS32EN; + else + mrqc = IXGBE_MRQC_VMDQRSS64EN; + } else { + if (tcs > 4) + mrqc = IXGBE_MRQC_RTRSS8TCEN; + else if (tcs > 1) + mrqc = IXGBE_MRQC_RTRSS4TCEN; + else + mrqc = IXGBE_MRQC_RSSEN; + } + + /* Enable L3/L4 for Tx Switched packets */ + mrqc |= IXGBE_MRQC_L3L4TXSWEN; + } + + /* Perform hash on these packet types */ + rss_field = IXGBE_MRQC_RSS_FIELD_IPV4 | + IXGBE_MRQC_RSS_FIELD_IPV4_TCP | + IXGBE_MRQC_RSS_FIELD_IPV6 | + IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + + if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP) + rss_field |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; + if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) + rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; + + if ((hw->mac.type >= ixgbe_mac_X550) && + (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) { + unsigned int pf_pool = adapter->num_vfs; + + /* Enable VF RSS mode */ + mrqc |= IXGBE_MRQC_MULTIPLE_RSS; + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + + /* Setup RSS through the VF registers */ + ixgbe_setup_vfreta(adapter); + vfmrqc = IXGBE_MRQC_RSSEN; + vfmrqc |= rss_field; + IXGBE_WRITE_REG(hw, IXGBE_PFVFMRQC(pf_pool), vfmrqc); + } else { + ixgbe_setup_reta(adapter); + mrqc |= rss_field; + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + } +} + +/** + * ixgbe_clear_rscctl - disable RSC for the indicated ring + * @adapter: address of board private structure + * @ring: structure containing ring specific data + **/ +void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rscctrl; + u8 reg_idx = ring->reg_idx; + + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); + rscctrl &= ~IXGBE_RSCCTL_RSCEN; + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); + + clear_ring_rsc_enabled(ring); +} + +/** + * ixgbe_configure_rscctl - enable RSC for the indicated ring + * @adapter: address of board private structure + * @ring: structure containing ring specific data + **/ +void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rscctrl; + u8 reg_idx = ring->reg_idx; + + if (!ring_is_rsc_enabled(ring)) + return; + + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); + rscctrl |= IXGBE_RSCCTL_RSCEN; + /* + * we must limit the number of descriptors so that the + * total size of max desc * buf_len is not greater + * than 65536 + */ +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +#if (MAX_SKB_FRAGS >= 16) + rscctrl |= IXGBE_RSCCTL_MAXDESC_16; +#elif (MAX_SKB_FRAGS >= 8) + rscctrl |= IXGBE_RSCCTL_MAXDESC_8; +#elif (MAX_SKB_FRAGS >= 4) + rscctrl |= IXGBE_RSCCTL_MAXDESC_4; +#else + rscctrl |= IXGBE_RSCCTL_MAXDESC_1; +#endif +#else /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + if (ring->rx_buf_len <= IXGBE_RXBUFFER_4K) + rscctrl |= IXGBE_RSCCTL_MAXDESC_16; + else if (ring->rx_buf_len <= IXGBE_RXBUFFER_8K) + rscctrl |= IXGBE_RSCCTL_MAXDESC_8; + else + rscctrl |= IXGBE_RSCCTL_MAXDESC_4; +#endif /* !CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); +} + +static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + int wait_loop = IXGBE_MAX_RX_DESC_POLL; + u32 rxdctl; + u8 reg_idx = ring->reg_idx; + + if (IXGBE_REMOVED(hw->hw_addr)) + return; + /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + do { + msleep(1); + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE)); + + if (!wait_loop) { + e_err(drv, "RXDCTL.ENABLE on Rx queue %d " + "not set within the polling period\n", reg_idx); + } +} + +void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + union ixgbe_adv_rx_desc *rx_desc; + u64 rdba = ring->dma; + u32 rxdctl; + u8 reg_idx = ring->reg_idx; + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); + ring->xsk_pool = ixgbe_xsk_umem(adapter, ring); + if (ring->xsk_pool) { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + ring->zca.free = ixgbe_zca_free; +#endif + WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + MEM_TYPE_ZERO_COPY, + &ring->zca)); +#else + MEM_TYPE_XSK_BUFF_POOL, + NULL)); + xsk_pool_set_rxq_info(ring->xsk_pool, &ring->xdp_rxq); +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + + } else { + WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, + MEM_TYPE_PAGE_SHARED, NULL)); + } + +#endif + /* disable queue to avoid use of these values while updating state */ + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + rxdctl &= ~IXGBE_RXDCTL_ENABLE; + + /* write value back with RXDCTL.ENABLE bit cleared */ + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); + IXGBE_WRITE_FLUSH(hw); + + IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), rdba & DMA_BIT_MASK(32)); + IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), rdba >> 32); + IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx), + ring->count * sizeof(union ixgbe_adv_rx_desc)); + /* Force flushing of IXGBE_RDLEN to prevent MDD */ + IXGBE_WRITE_FLUSH(hw); + + /* reset head and tail pointers */ + IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0); + ring->tail = adapter->io_addr + IXGBE_RDT(reg_idx); + + /* reset ntu and ntc to place SW in sync with hardwdare */ + ring->next_to_clean = 0; + ring->next_to_use = 0; +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + ring->next_to_alloc = 0; +#endif + + ixgbe_configure_srrctl(adapter, ring); + ixgbe_configure_rscctl(adapter, ring); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + /* + * enable cache line friendly hardware writes: + * PTHRESH=32 descriptors (half the internal cache), + * this also removes ugly rx_no_buffer_count increment + * HTHRESH=4 descriptors (to minimize latency on fetch) + * WTHRESH=8 burst writeback up to two cache lines + */ + rxdctl &= ~0x3FFFFF; + rxdctl |= 0x080420; + break; + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +#if (PAGE_SIZE < 8192) + rxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK | + IXGBE_RXDCTL_RLPML_EN); + + /* Limit the maximum frame size so we don't overrun the skb */ + if (ring_uses_build_skb(ring) && + !test_bit(__IXGBE_RX_3K_BUFFER, &ring->state)) + rxdctl |= IXGBE_MAX_2K_FRAME_BUILD_SKB | + IXGBE_RXDCTL_RLPML_EN; +#endif +#else /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + /* If operating in IOV mode set RLPML */ + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + break; + rxdctl |= ring->rx_buf_len | IXGBE_RXDCTL_RLPML_EN; +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + break; + default: + break; + } + + ring->rx_offset = ixgbe_rx_offset(ring); +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (ring->xsk_pool && hw->mac.type != ixgbe_mac_82599EB) { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + u32 xsk_buf_len = ring->xsk_pool->chunk_size_nohr - + XDP_PACKET_HEADROOM; +#else + u32 xsk_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + + rxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK | + IXGBE_RXDCTL_RLPML_EN); + rxdctl |= xsk_buf_len | IXGBE_RXDCTL_RLPML_EN; + + ring->rx_buf_len = xsk_buf_len; + } + +#endif + /* initialize rx_buffer_info */ + memset(ring->rx_buffer_info, 0, + sizeof(struct ixgbe_rx_buffer) * ring->count); + + /* initialize Rx descriptor 0 */ + rx_desc = IXGBE_RX_DESC(ring, 0); + rx_desc->wb.upper.length = 0; + + /* enable receive descriptor ring */ + rxdctl |= IXGBE_RXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); + + ixgbe_rx_desc_queue_enable(adapter, ring); +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (ring->xsk_pool) + ixgbe_alloc_rx_buffers_zc(ring, ixgbe_desc_unused(ring)); + else + ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring)); +#else + ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring)); +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +} + +static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int rss_i = adapter->ring_feature[RING_F_RSS].indices; + int p; + + /* PSRTYPE must be initialized in non 82598 adapters */ + u32 psrtype = IXGBE_PSRTYPE_TCPHDR | + IXGBE_PSRTYPE_UDPHDR | + IXGBE_PSRTYPE_IPV4HDR | + IXGBE_PSRTYPE_L2HDR | + IXGBE_PSRTYPE_IPV6HDR; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + if (rss_i > 3) + psrtype |= 2u << 29; + else if (rss_i > 1) + psrtype |= 1u << 29; + + for (p = 0; p < adapter->num_rx_pools; p++) + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(VMDQ_P(p)), psrtype); +} + +/** + * ixgbe_configure_bridge_mode - common settings for configuring bridge mode + * @adapter: the private structure + * + * This function's purpose is to remove code duplication and configure some + * settings require to switch bridge modes. + **/ +static void ixgbe_configure_bridge_mode(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw * hw = &adapter->hw; + unsigned int p; + u32 vmdctl; + + if (adapter->flags & IXGBE_FLAG_SRIOV_VEPA_BRIDGE_MODE) { + /* disable Tx loopback, rely on switch hairpin mode */ + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, 0); + + /* must enable Rx switching replication to allow multicast + * packet reception on all VFs, and to enable source address + * pruning. + */ + vmdctl = IXGBE_READ_REG(hw, IXGBE_VMD_CTL); + vmdctl |= IXGBE_VT_CTL_REPLEN; + IXGBE_WRITE_REG(hw, IXGBE_VMD_CTL, vmdctl); + + /* enable Rx source address pruning. Note, this requires + * replication to be enabled or else it does nothing. + */ + for (p = 0; p < (adapter->num_vfs + adapter->num_rx_pools); p++) { + if (hw->mac.ops.set_source_address_pruning) + hw->mac.ops.set_source_address_pruning(hw, + true, + p); + } + } else { + /* enable Tx loopback for internal VF/PF communication */ + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); + + /* disable Rx switching replication unless we have SR-IOV + * virtual functions + */ + vmdctl = IXGBE_READ_REG(hw, IXGBE_VMD_CTL); + if (!adapter->num_vfs) + vmdctl &= ~IXGBE_VT_CTL_REPLEN; + IXGBE_WRITE_REG(hw, IXGBE_VMD_CTL, vmdctl); + + /* disable Rx source address pruning, since we don't expect to + * be receiving external loopback of our transmitted frames. + */ + for (p = 0; p < (adapter->num_vfs + adapter->num_rx_pools); p++) { + if (hw->mac.ops.set_source_address_pruning) + hw->mac.ops.set_source_address_pruning(hw, + false, + p); + } + } + +} + +static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reg_offset, vf_shift, vmolr; + u32 gcr_ext, vmdctl; + int i; + + if (!(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)) + return; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + vmdctl = IXGBE_READ_REG(hw, IXGBE_VMD_CTL); + vmdctl |= IXGBE_VMD_CTL_VMDQ_EN; + IXGBE_WRITE_REG(hw, IXGBE_VMD_CTL, vmdctl); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); + vmdctl |= IXGBE_VT_CTL_VT_ENABLE; + vmdctl &= ~IXGBE_VT_CTL_POOL_MASK; + vmdctl |= VMDQ_P(0) << IXGBE_VT_CTL_POOL_SHIFT; + if (adapter->num_vfs) + vmdctl |= IXGBE_VT_CTL_REPLEN; + IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl); + + for (i = 1; i < adapter->num_rx_pools; i++) { + int pool = VMDQ_P(i); + + /* accept untagged packets until a vlan tag is + * specifically set for the VMDQ queue/pool + */ + vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(pool)); + vmolr |= IXGBE_VMOLR_AUPE; + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(pool), vmolr); + } + + vf_shift = VMDQ_P(0) % 32; + reg_offset = (VMDQ_P(0) >= 32) ? 1 : 0; + + /* Enable only the PF pools for Tx/Rx */ + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (~0) << vf_shift); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), reg_offset - 1); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (~0) << vf_shift); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), reg_offset - 1); + + /* clear VLAN promisc flag so VFTA + * will be updated if necessary + */ + adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC; + break; + default: + break; + } + + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return; + + /* + * Set up VF register offsets for selected VT Mode, + * i.e. 32 or 64 VFs for SR-IOV + */ + switch (adapter->ring_feature[RING_F_VMDQ].mask) { + case IXGBE_82599_VMDQ_8Q_MASK: + gcr_ext = IXGBE_GCR_EXT_VT_MODE_16; + break; + case IXGBE_82599_VMDQ_4Q_MASK: + gcr_ext = IXGBE_GCR_EXT_VT_MODE_32; + break; + default: + gcr_ext = IXGBE_GCR_EXT_VT_MODE_64; + break; + } + + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); + + /* configure default bridge settings */ + ixgbe_configure_bridge_mode(adapter); +#if IS_ENABLED(CONFIG_PCI_IOV) + for (i = 0; i < adapter->num_vfs; i++) { + /* configure spoof checking */ + ixgbe_ndo_set_vf_spoofchk(adapter->netdev, i, + adapter->vfinfo[i].spoofchk_enabled); + +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN + /* Enable/Disable RSS query feature */ + ixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i, + adapter->vfinfo[i].rss_query_enabled); +#endif /* HAVE_NDO_SET_VF_RSS_QUERY_EN */ + } +#endif /* CONFIG_PCI_IOV */ +} + +static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + struct ixgbe_ring *rx_ring; + int i; + u32 mhadd, hlreg0; +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + int rx_buf_len; +#endif + + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + max_frame += IXGBE_TS_HDR_LEN; + default: + break; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* adjust max frame to be able to do baby jumbo for FCoE */ + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE)) + max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; +#endif /* CONFIG_FCOE */ + + /* adjust max frame to be at least the size of a standard frame */ + if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN)) + max_frame = (ETH_FRAME_LEN + ETH_FCS_LEN); + + mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); + if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { + mhadd &= ~IXGBE_MHADD_MFS_MASK; + mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT; + + IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); + } + +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + /* MHADD will allow an extra 4 bytes past for vlan tagged frames */ + max_frame += VLAN_HLEN; + + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && + (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE)) { + rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; + /* + * Make best use of allocation by using all but 1K of a + * power of 2 allocation that will be used for skb->head. + */ + } else if (max_frame <= IXGBE_RXBUFFER_3K) { + rx_buf_len = IXGBE_RXBUFFER_3K; + } else if (max_frame <= IXGBE_RXBUFFER_7K) { + rx_buf_len = IXGBE_RXBUFFER_7K; + } else if (max_frame <= IXGBE_RXBUFFER_15K) { + rx_buf_len = IXGBE_RXBUFFER_15K; + } else { + rx_buf_len = IXGBE_MAX_RXBUFFER; + } + +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + /* set jumbo enable since MHADD.MFS is keeping size locked at + * max_frame + */ + hlreg0 |= IXGBE_HLREG0_JUMBOEN; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + + /* + * Setup the HW Rx Head and Tail Descriptor Pointers and + * the Base and Length of the Rx Descriptor Ring + */ + for (i = 0; i < adapter->num_rx_queues; i++) { + rx_ring = adapter->rx_ring[i]; + + clear_ring_rsc_enabled(rx_ring); + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + set_ring_rsc_enabled(rx_ring); + +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + clear_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state); + clear_bit(__IXGBE_RX_BUILD_SKB_ENABLED, &rx_ring->state); +#if IS_ENABLED(CONFIG_FCOE) + + if (test_bit(__IXGBE_RX_FCOE, &rx_ring->state)) + set_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state); +#endif +#ifdef HAVE_SWIOTLB_SKIP_CPU_SYNC + + if (adapter->flags2 & IXGBE_FLAG2_RX_LEGACY) + continue; + + set_bit(__IXGBE_RX_BUILD_SKB_ENABLED, &rx_ring->state); + +#if (PAGE_SIZE < 8192) + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + set_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state); + + if (IXGBE_2K_TOO_SMALL_WITH_PADDING || + (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN))) + set_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state); +#endif +#else /* !HAVE_SWIOTLB_SKIP_CPU_SYNC */ + + adapter->flags2 |= IXGBE_FLAG2_RX_LEGACY; +#endif /* !HAVE_SWIOTLB_SKIP_CPU_SYNC */ +#else /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + + rx_ring->rx_buf_len = rx_buf_len; +#if IS_ENABLED(CONFIG_FCOE) + + if (test_bit(__IXGBE_RX_FCOE, &rx_ring->state) && + (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE)) + rx_ring->rx_buf_len = IXGBE_FCOE_JUMBO_FRAME_SIZE; +#endif /* CONFIG_FCOE */ +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + } +} + +static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + if (adapter->num_vfs) + rdrxctl |= IXGBE_RDRXCTL_PSP; + fallthrough; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + /* Disable RSC for ACK packets */ + IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, + (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); + rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; + /* hardware requires some bits to be set by default */ + rdrxctl |= (IXGBE_RDRXCTL_RSCACKC | IXGBE_RDRXCTL_FCOE_WRFIX); + rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; + break; + case ixgbe_mac_82598EB: + /* + * For VMDq support of different descriptor types or + * buffer sizes through the use of multiple SRRCTL + * registers, RDRXCTL.MVMEN must be set to 1 + * + * also, the manual doesn't mention it clearly but DCA hints + * will only use queue 0's tags unless this bit is set. Side + * effects of setting this bit are only that SRRCTL must be + * fully programmed [0..15] + */ + rdrxctl |= IXGBE_RDRXCTL_MVMEN; + break; + default: + /* We should do nothing since we don't know this hardware */ + return; + } + + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); +} + +/** + * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset + * @adapter: board private structure + * + * Configure the Rx unit of the MAC after a reset. + **/ +static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + u32 rxctrl, rfctl; + + /* disable receives while setting up the descriptors */ + ixgbe_disable_rx(hw); + + ixgbe_setup_psrtype(adapter); + ixgbe_setup_rdrxctl(adapter); + + /* RSC Setup */ + rfctl = IXGBE_READ_REG(hw, IXGBE_RFCTL); + rfctl &= ~IXGBE_RFCTL_RSC_DIS; + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) + rfctl |= IXGBE_RFCTL_RSC_DIS; + + /* disable NFS filtering */ + rfctl |= (IXGBE_RFCTL_NFSW_DIS | IXGBE_RFCTL_NFSR_DIS); + IXGBE_WRITE_REG(hw, IXGBE_RFCTL, rfctl); + + /* Program registers for the distribution of queues */ + ixgbe_setup_mrqc(adapter); + + /* set_rx_buffer_len must be called before ring initialization */ + ixgbe_set_rx_buffer_len(adapter); + + /* + * Setup the HW Rx Head and Tail Descriptor Pointers and + * the Base and Length of the Rx Descriptor Ring + */ + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]); + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + /* disable drop enable for 82598 parts */ + if (hw->mac.type == ixgbe_mac_82598EB) + rxctrl |= IXGBE_RXCTRL_DMBYPS; + + /* enable all receives */ + rxctrl |= IXGBE_RXCTRL_RXEN; + hw->mac.ops.enable_rx_dma(hw, rxctrl); +} + +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) +/** + * ixgbe_vlan_rx_add_vid - Add a VLAN ID to the ixgbe device's filter table + * @netdev: Network device structure pointer + * @proto: Protocol identifier (used if NETIF_F_HW_VLAN_CTAG_TX is defined) + * @vid: VLAN ID to be added + * + * This function adds a specified VLAN ID to the ixgbe network adapter's + * VLAN filter table. It configures the hardware to recognize the VLAN ID + * and, if applicable, enables it for all receive pools. The function also + * updates the VLAN device's features to match those of the main network + * device, allowing features like TSO to be applied to VLAN traffic. + * + * Return: 0 on success (if HAVE_INT_NDO_VLAN_RX_ADD_VID is defined). + */ +#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID +#ifdef NETIF_F_HW_VLAN_CTAG_TX +static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, + __always_unused __be16 proto, u16 vid) +#else /* !NETIF_F_HW_VLAN_CTAG_TX */ +static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +#endif /* NETIF_F_HW_VLAN_CTAG_TX */ +#else /* !HAVE_INT_NDO_VLAN_RX_ADD_VID */ +static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +#endif /* HAVE_INT_NDO_VLAN_RX_ADD_VID */ +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + int pool_ndx = VMDQ_P(0); + + /* add VID to filter table */ + if (hw->mac.ops.set_vfta) { +#ifndef HAVE_VLAN_RX_REGISTER + if (vid < VLAN_N_VID) + set_bit(vid, adapter->active_vlans); +#endif + + if (!vid || !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)) + hw->mac.ops.set_vfta(hw, vid, pool_ndx, true, !!vid); + + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED && + adapter->hw.mac.type != ixgbe_mac_82598EB) { + int i; + + /* enable vlan id for all pools */ + for (i = 1; i < adapter->num_rx_pools; i++) + hw->mac.ops.set_vfta(hw, vid, VMDQ_P(i), true, +#ifdef HAVE_VLAN_RX_REGISTER + false); +#else + true); +#endif + } + } +#ifndef HAVE_NETDEV_VLAN_FEATURES + + /* + * Copy feature flags from netdev to the vlan netdev for this vid. + * This allows things like TSO to bubble down to our vlan device. + * Some vlans, such as VLAN 0 for DCB will not have a v_netdev so + * we will not have a netdev that needs updating. + */ + if (adapter->vlgrp) { + struct vlan_group *vlgrp = adapter->vlgrp; + struct net_device *v_netdev = vlan_group_get_device(vlgrp, vid); + if (v_netdev) { + v_netdev->features |= netdev->features; + vlan_group_set_device(vlgrp, vid, v_netdev); + } + } +#endif /* HAVE_NETDEV_VLAN_FEATURES */ +#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID + return 0; +#endif +} + +#if defined(HAVE_VLAN_RX_REGISTER) && defined(CONFIG_PCI_IOV) +int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan) +#else +static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan) +#endif +{ + u32 vlvf; + int idx; + + /* short cut the special case */ + if (vlan == 0) + return 0; + + /* Search for the vlan id in the VLVF entries */ + for (idx = IXGBE_VLVF_ENTRIES; --idx;) { + vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(idx)); + if ((vlvf & VLAN_VID_MASK) == vlan) + break; + } + + return idx; +} + +void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 bits, word; + int idx; + + idx = ixgbe_find_vlvf_entry(hw, vid); + if (!idx) + return; + + /* See if any other pools are set for this VLAN filter + * entry other than the PF. + */ + word = idx * 2 + (VMDQ_P(0) / 32); + bits = ~(1 << (VMDQ_P(0)) % 32); + bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word)); + + /* Disable the filter so this falls into the default pool. */ + if (!bits && !IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1))) { + if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)) + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), 0); + IXGBE_WRITE_REG(hw, IXGBE_VLVF(idx), 0); + } +} + +/** + * ixgbe_vlan_rx_kill_vid - Remove a VLAN ID from the ixgbe device's filter table + * @netdev: Network device structure pointer + * @proto: Protocol identifier (used if NETIF_F_HW_VLAN_CTAG_RX is defined) + * @vid: VLAN ID to be removed + * + * This function removes a specified VLAN ID from the ixgbe network adapter's + * VLAN filter table. It ensures that VLAN ID 0 is not removed, as it is reserved. + * The function also updates the VLAN group and clears the VLAN ID from all + * receive pools if applicable. Interrupts are managed to ensure consistent + * state during the operation. + * + * Return: 0 on success (if HAVE_INT_NDO_VLAN_RX_ADD_VID is defined). + */ +#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID +#ifdef NETIF_F_HW_VLAN_CTAG_RX +static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, + __always_unused __be16 proto, u16 vid) +#else /* !NETIF_F_HW_VLAN_CTAG_RX */ +static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +#endif /* NETIF_F_HW_VLAN_CTAG_RX */ +#else +static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + int pool_ndx = VMDQ_P(0); + + /* User is not allowed to remove vlan ID 0 */ + if (!vid) +#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID + return 0; +#else + return; +#endif + +#ifdef HAVE_VLAN_RX_REGISTER + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_disable(adapter); + + vlan_group_set_device(adapter->vlgrp, vid, NULL); + + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_enable(adapter, true, true); + +#endif /* HAVE_VLAN_RX_REGISTER */ + /* remove VID from filter table */ + if (hw->mac.ops.set_vfta) { + if (vid && !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)) + hw->mac.ops.set_vfta(hw, vid, pool_ndx, false, true); + + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED && + adapter->hw.mac.type != ixgbe_mac_82598EB) { + int i; + + /* remove vlan id from all pools */ + for (i = 1; i < adapter->num_rx_pools; i++) + hw->mac.ops.set_vfta(hw, vid, VMDQ_P(i), false, + true); + } + } +#ifndef HAVE_VLAN_RX_REGISTER + + clear_bit(vid, adapter->active_vlans); +#endif +#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID + return 0; +#endif +} + +#ifdef HAVE_8021P_SUPPORT +/** + * ixgbe_vlan_strip_disable - helper to disable vlan tag stripping + * @adapter: driver data + */ +void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl; + int i, j; + + /* leave vlan tag stripping enabled for DCB */ + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + return; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl &= ~IXGBE_VLNCTRL_VME; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + + j = ring->reg_idx; + vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); + vlnctrl &= ~IXGBE_RXDCTL_VME; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl); + } +#ifdef HAVE_PTP_1588_CLOCK + if (ixgbe_is_mac_E6xx(hw->mac.type) && + hw->dev_caps.common_cap.ptp_by_phy_ll) + ixgbe_ptp_cfg_phy_vlan_e600(adapter, true); +#endif /* HAVE_PTP_1588_CLOCK */ + break; + default: + break; + } +} + +#endif /* HAVE_8021P_SUPPORT */ +/** + * ixgbe_vlan_strip_enable - helper to enable vlan tag stripping + * @adapter: driver data + */ +void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl; + int i, j; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl |= IXGBE_VLNCTRL_VME; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + + j = ring->reg_idx; + vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); + vlnctrl |= IXGBE_RXDCTL_VME; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl); + } +#ifdef HAVE_PTP_1588_CLOCK + if (ixgbe_is_mac_E6xx(hw->mac.type) && + hw->dev_caps.common_cap.ptp_by_phy_ll) + ixgbe_ptp_cfg_phy_vlan_e600(adapter, false); +#endif /* HAVE_PTP_1588_CLOCK */ + break; + default: + break; + } +} + +#ifndef HAVE_VLAN_RX_REGISTER +static void ixgbe_vlan_promisc_enable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl, i; + + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) { + /* we need to keep the VLAN filter on in SRIOV */ + vlnctrl |= IXGBE_VLNCTRL_VFE; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + } else { + vlnctrl &= ~IXGBE_VLNCTRL_VFE; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + return; + } + + /* Nothing to do for 82598 */ + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + /* We are already in VLAN promisc, nothing to do */ + if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) + return; + + /* Set flag so we don't redo unnecessary work */ + adapter->flags2 |= IXGBE_FLAG2_VLAN_PROMISC; + + /* Add PF to all active pools */ + for (i = IXGBE_VLVF_ENTRIES; --i;) { + u32 reg_offset = IXGBE_VLVFB(i * 2 + VMDQ_P(0) / 32); + u32 vlvfb = IXGBE_READ_REG(hw, reg_offset); + + vlvfb |= 1 << (VMDQ_P(0) % 32); + IXGBE_WRITE_REG(hw, reg_offset, vlvfb); + } + + /* Set all bits in the VLAN filter table array */ + for (i = hw->mac.vft_size; i--;) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), ~0U); +} + +#define VFTA_BLOCK_SIZE 8 +static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vfta[VFTA_BLOCK_SIZE] = { 0 }; + u32 vid_start = vfta_offset * 32; + u32 vid_end = vid_start + (VFTA_BLOCK_SIZE * 32); + u32 i, vid, word, bits; + + for (i = IXGBE_VLVF_ENTRIES; --i;) { + u32 vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i)); + + /* pull VLAN ID from VLVF */ + vid = vlvf & VLAN_VID_MASK; + + /* only concern outselves with a certain range */ + if (vid < vid_start || vid >= vid_end) + continue; + + if (vlvf) { + /* record VLAN ID in VFTA */ + vfta[(vid - vid_start) / 32] |= 1 << (vid % 32); + + /* if PF is part of this then continue */ + if (test_bit(vid, adapter->active_vlans)) + continue; + } + + /* remove PF from the pool */ + word = i * 2 + VMDQ_P(0) / 32; + bits = ~(1 << (VMDQ_P(0) % 32)); + bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word)); + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), bits); + } + + /* extract values from active_vlans and write back to VFTA */ + for (i = VFTA_BLOCK_SIZE; i--;) { + vid = (vfta_offset + i) * 32; + word = vid / BITS_PER_LONG; + bits = vid % BITS_PER_LONG; + + vfta[i] |= adapter->active_vlans[word] >> bits; + + IXGBE_WRITE_REG(hw, IXGBE_VFTA(vfta_offset + i), vfta[i]); + } +} + +static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl, i; + + /* configure vlan filtering */ + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl |= IXGBE_VLNCTRL_VFE; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + + if (!(adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) || + hw->mac.type == ixgbe_mac_82598EB) + return; + + /* We are not in VLAN promisc, nothing to do */ + if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)) + return; + + /* Set flag so we don't redo unnecessary work */ + adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC; + + for (i = 0; i < hw->mac.vft_size; i += VFTA_BLOCK_SIZE) + ixgbe_scrub_vfta(adapter, i); +} +#endif /* HAVE_VLAN_RX_REGISTER */ + +#ifdef HAVE_VLAN_RX_REGISTER +static void ixgbe_vlan_mode(struct net_device *netdev, struct vlan_group *grp) +#else +void ixgbe_vlan_mode(struct net_device *netdev, u32 features) +#endif +{ +#if defined(HAVE_VLAN_RX_REGISTER) || defined(HAVE_8021P_SUPPORT) + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#endif +#ifdef HAVE_8021P_SUPPORT + bool enable; +#endif + +#ifdef HAVE_VLAN_RX_REGISTER + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_disable(adapter); + + adapter->vlgrp = grp; + + if (!test_bit(__IXGBE_DOWN, adapter->state)) + ixgbe_irq_enable(adapter, true, true); +#endif +#ifdef HAVE_8021P_SUPPORT +#ifdef HAVE_VLAN_RX_REGISTER + enable = (grp || (adapter->flags & IXGBE_FLAG_DCB_ENABLED)); +#else +#ifdef NETIF_F_HW_VLAN_CTAG_RX + enable = !!(features & NETIF_F_HW_VLAN_CTAG_RX); +#else + enable = !!(features & NETIF_F_HW_VLAN_RX); +#endif /* NETIF_F_HW_VLAN_CTAG_RX */ +#endif /* HAVE_VLAN_RX_REGISTER */ + if (enable) + /* enable VLAN tag insert/strip */ + ixgbe_vlan_strip_enable(adapter); + else + /* disable VLAN tag insert/strip */ + ixgbe_vlan_strip_disable(adapter); + +#endif /* HAVE_8021P_SUPPORT */ +} + +static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) +{ + u16 vid = 1; +#ifdef HAVE_VLAN_RX_REGISTER + + ixgbe_vlan_mode(adapter->netdev, adapter->vlgrp); + + /* + * add vlan ID 0 and enable vlan tag stripping so we + * always accept priority-tagged traffic + */ +#ifdef NETIF_F_HW_VLAN_CTAG_RX + ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0); +#else + ixgbe_vlan_rx_add_vid(adapter->netdev, 0); +#endif +#ifndef HAVE_8021P_SUPPORT + ixgbe_vlan_strip_enable(adapter); +#endif + + if (adapter->vlgrp) { + for (; vid < VLAN_N_VID; vid++) { + if (!vlan_group_get_device(adapter->vlgrp, vid)) + continue; +#ifdef NETIF_F_HW_VLAN_CTAG_RX + ixgbe_vlan_rx_add_vid(adapter->netdev, + htons(ETH_P_8021Q), vid); +#else + ixgbe_vlan_rx_add_vid(adapter->netdev, vid); +#endif + } + } +#else /* !HAVE_VLAN_RX_REGISTER */ + +#ifdef NETIF_F_HW_VLAN_CTAG_RX + ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0); +#else + ixgbe_vlan_rx_add_vid(adapter->netdev, 0); +#endif + + for_each_set_bit_from(vid, adapter->active_vlans, VLAN_N_VID) +#ifdef NETIF_F_HW_VLAN_CTAG_RX + ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid); +#else + ixgbe_vlan_rx_add_vid(adapter->netdev, vid); +#endif +#endif /* HAVE_VLAN_RX_REGISTER */ +} + +#endif +static u8 *ixgbe_addr_list_itr(struct ixgbe_hw __maybe_unused *hw, u8 **mc_addr_ptr, u32 *vmdq) +{ +#ifdef NETDEV_HW_ADDR_T_MULTICAST + struct netdev_hw_addr *mc_ptr; +#else + struct dev_mc_list *mc_ptr; +#endif +#ifdef CONFIG_PCI_IOV + struct ixgbe_adapter *adapter = hw->back; +#endif /* CONFIG_PCI_IOV */ + u8 *addr = *mc_addr_ptr; + + /* VMDQ_P implicitely uses the adapter struct when CONFIG_PCI_IOV is + * defined, so we have to wrap the pointer above correctly to prevent + * a warning. + */ + *vmdq = VMDQ_P(0); + +#ifdef NETDEV_HW_ADDR_T_MULTICAST + mc_ptr = container_of(addr, struct netdev_hw_addr, addr[0]); + if (mc_ptr->list.next) { + struct netdev_hw_addr *ha; + + ha = list_entry(mc_ptr->list.next, struct netdev_hw_addr, list); + *mc_addr_ptr = ha->addr; + } +#else + mc_ptr = container_of(addr, struct dev_mc_list, dmi_addr[0]); + if (mc_ptr->next) + *mc_addr_ptr = mc_ptr->next->dmi_addr; +#endif + else + *mc_addr_ptr = NULL; + + return addr; +} + +/** + * ixgbe_write_mc_addr_list - write multicast addresses to MTA + * @netdev: network interface device structure + * + * Writes multicast address list to the MTA hash table. + * Returns: -ENOMEM on failure + * 0 on no addresses written + * X on writing X addresses to MTA + **/ +int ixgbe_write_mc_addr_list(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; +#ifdef NETDEV_HW_ADDR_T_MULTICAST + struct netdev_hw_addr *ha; +#endif + u8 *addr_list = NULL; + int addr_count = 0; + + if (!hw->mac.ops.update_mc_addr_list) + return -ENOMEM; + + if (!netif_running(netdev)) + return 0; + +#ifdef CONFIG_PCI_IOV + ixgbe_restore_vf_multicasts(adapter); +#endif + + if (netdev_mc_empty(netdev)) { + hw->mac.ops.update_mc_addr_list(hw, NULL, 0, + ixgbe_addr_list_itr, false); + } else { +#ifdef NETDEV_HW_ADDR_T_MULTICAST + ha = list_first_entry(&netdev->mc.list, + struct netdev_hw_addr, list); + addr_list = ha->addr; +#else + addr_list = netdev->mc_list->dmi_addr; +#endif + addr_count = netdev_mc_count(netdev); + + hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count, + ixgbe_addr_list_itr, false); + } + + return addr_count; +} + +#ifdef CONFIG_PCI_IOV +void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + int i; + + for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { + mac_table->state &= ~IXGBE_MAC_STATE_MODIFIED; + + if (mac_table->state & IXGBE_MAC_STATE_IN_USE) + hw->mac.ops.set_rar(hw, i, + mac_table->addr, + mac_table->pool, + IXGBE_RAH_AV); + else + hw->mac.ops.clear_rar(hw, i); + } +} +#endif + +static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + int i; + + for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { + if (!(mac_table->state & IXGBE_MAC_STATE_MODIFIED)) + continue; + + mac_table->state &= ~IXGBE_MAC_STATE_MODIFIED; + + if (mac_table->state & IXGBE_MAC_STATE_IN_USE) + hw->mac.ops.set_rar(hw, i, + mac_table->addr, + mac_table->pool, + IXGBE_RAH_AV); + else + hw->mac.ops.clear_rar(hw, i); + } +} + +int ixgbe_available_rars(struct ixgbe_adapter *adapter, u16 pool) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + int i, count = 0; + + for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { + /* do not count default RAR as available */ + if (mac_table->state & IXGBE_MAC_STATE_DEFAULT) + continue; + + /* only count unused and addresses that belong to us */ + if (mac_table->state & IXGBE_MAC_STATE_IN_USE) { + if (mac_table->pool != pool) + continue; + } + + count++; + } + + return count; +} + +/* this function destroys the first RAR entry */ +static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + + ether_addr_copy(mac_table->addr, hw->mac.addr); + mac_table->pool = VMDQ_P(0); + + mac_table->state = IXGBE_MAC_STATE_DEFAULT | IXGBE_MAC_STATE_IN_USE; + + hw->mac.ops.set_rar(hw, 0, mac_table->addr, mac_table->pool, + IXGBE_RAH_AV); +} + +int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, + const u8 *addr, u16 pool) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + int i; + + if (is_zero_ether_addr(addr)) + return -EINVAL; + + for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { + if (mac_table->state & IXGBE_MAC_STATE_IN_USE) { + continue; + } + + ether_addr_copy(mac_table->addr, addr); + mac_table->pool = pool; + + mac_table->state |= IXGBE_MAC_STATE_MODIFIED | + IXGBE_MAC_STATE_IN_USE; + + ixgbe_sync_mac_table(adapter); + + return i; + } + + return -ENOMEM; +} + +static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + int i; + + for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { + mac_table->state |= IXGBE_MAC_STATE_MODIFIED; + mac_table->state &= ~IXGBE_MAC_STATE_IN_USE; + } + + ixgbe_sync_mac_table(adapter); +} + + +int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, + const u8 *addr, u16 pool) +{ + struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; + struct ixgbe_hw *hw = &adapter->hw; + int i; + + if (is_zero_ether_addr(addr)) + return -EINVAL; + + /* search table for addr, if found clear IN USE flag and sync */ + for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { + /* we can only delete an entry if it is in use */ + if (!(mac_table->state & IXGBE_MAC_STATE_IN_USE)) + continue; + /* we only care about entries that belong to the given pool */ + if (mac_table->pool != pool) + continue; + /* we only care about a specific MAC address */ + if (!ether_addr_equal(addr, mac_table->addr)) + continue; + + mac_table->state |= IXGBE_MAC_STATE_MODIFIED; + mac_table->state &= ~IXGBE_MAC_STATE_IN_USE; + + ixgbe_sync_mac_table(adapter); + + return 0; + } + + return -ENOMEM; +} + +#ifdef HAVE_SET_RX_MODE +static int ixgbe_uc_sync(struct net_device *netdev, const unsigned char *addr) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int ret; + + ret = ixgbe_add_mac_filter(adapter, addr, VMDQ_P(0)); + + return min_t(int, ret, 0); +} + +static int ixgbe_uc_unsync(struct net_device *netdev, const unsigned char *addr) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + ixgbe_del_mac_filter(adapter, addr, VMDQ_P(0)); + + return 0; +} + +#endif +/** + * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set + * @netdev: network interface device structure + * + * The set_rx_method entry point is called whenever the unicast/multicast + * address list or the network interface flags are updated. This routine is + * responsible for configuring the hardware for proper unicast, multicast and + * promiscuous mode. + **/ +void ixgbe_set_rx_mode(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE; +#if defined(HAVE_VLAN_RX_REGISTER) + u32 vlnctrl; +#endif +#if defined(NETIF_F_HW_VLAN_CTAG_FILTER) || defined(NETIF_F_HW_VLAN_FILTER) + netdev_features_t features = netdev->features; +#endif + int count; + + /* Check for Promiscuous and All Multicast modes */ + fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); +#if defined(HAVE_VLAN_RX_REGISTER) + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); +#endif + + /* set all bits that we expect to always be set */ + fctrl |= IXGBE_FCTRL_BAM; + fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */ + fctrl |= IXGBE_FCTRL_PMCF; + + /* clear the bits we are changing the status of */ + fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); +#if defined(HAVE_VLAN_RX_REGISTER) + vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); +#endif + if (netdev->flags & IFF_PROMISC) { + hw->addr_ctrl.user_set_promisc = true; + fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); + vmolr |= IXGBE_VMOLR_MPE; +#ifdef HAVE_VLAN_RX_REGISTER + /* Only disable hardware filter vlans in promiscuous mode + * if SR-IOV and VMDQ are disabled - otherwise ensure + * that hardware VLAN filters remain enabled. + */ + if ((adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED | + IXGBE_FLAG_SRIOV_ENABLED))) + vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); +#endif +#ifdef NETIF_F_HW_VLAN_CTAG_FILTER + features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; +#endif +#ifdef NETIF_F_HW_VLAN_FILTER + features &= ~NETIF_F_HW_VLAN_FILTER; +#endif + } else { + if (netdev->flags & IFF_ALLMULTI) { + fctrl |= IXGBE_FCTRL_MPE; + vmolr |= IXGBE_VMOLR_MPE; + } + hw->addr_ctrl.user_set_promisc = false; +#if defined(HAVE_VLAN_RX_REGISTER) + /* enable hardware vlan filtering */ + vlnctrl |= IXGBE_VLNCTRL_VFE; +#endif + } + +#ifdef HAVE_SET_RX_MODE + /* + * Write addresses to available RAR registers, if there is not + * sufficient space to store all the addresses then enable + * unicast promiscuous mode + */ + if (__dev_uc_sync(netdev, ixgbe_uc_sync, ixgbe_uc_unsync)) { + fctrl |= IXGBE_FCTRL_UPE; + vmolr |= IXGBE_VMOLR_ROPE; + } + +#endif + /* + * Write addresses to the MTA, if the attempt fails + * then we should just turn on promiscuous mode so + * that we can at least receive multicast traffic + */ + count = ixgbe_write_mc_addr_list(netdev); + if (count < 0) { + fctrl |= IXGBE_FCTRL_MPE; + vmolr |= IXGBE_VMOLR_MPE; + } else if (count) { + vmolr |= IXGBE_VMOLR_ROMPE; + } + + if (hw->mac.type != ixgbe_mac_82598EB) { + vmolr |= IXGBE_READ_REG(hw, IXGBE_VMOLR(VMDQ_P(0))) & + ~(IXGBE_VMOLR_MPE | IXGBE_VMOLR_ROMPE | + IXGBE_VMOLR_ROPE); + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(VMDQ_P(0)), vmolr); + } + + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + +#ifdef HAVE_8021P_SUPPORT +#ifdef NETIF_F_HW_VLAN_CTAG_RX + if (features & NETIF_F_HW_VLAN_CTAG_RX) +#else + if (features & NETIF_F_HW_VLAN_RX) +#endif + ixgbe_vlan_strip_enable(adapter); + else + ixgbe_vlan_strip_disable(adapter); +#endif /* HAVE_8021P_SUPPORT */ + +#if defined(NETIF_F_HW_VLAN_CTAG_FILTER) + if (features & NETIF_F_HW_VLAN_CTAG_FILTER) + ixgbe_vlan_promisc_disable(adapter); + else + ixgbe_vlan_promisc_enable(adapter); +#elif defined(NETIF_F_HW_VLAN_FILTER) && !defined(HAVE_VLAN_RX_REGISTER) + if (features & NETIF_F_HW_VLAN_FILTER) + ixgbe_vlan_promisc_disable(adapter); + else + ixgbe_vlan_promisc_enable(adapter); +#elif defined(HAVE_VLAN_RX_REGISTER) + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); +#endif /* NETIF_F_HW_VLAN_CTAG_FILTER */ +} + +static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) +{ + struct ixgbe_q_vector *q_vector; + int q_idx; + + for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++) { + q_vector = adapter->q_vector[q_idx]; +#ifdef HAVE_NDO_BUSY_POLL + ixgbe_qv_init_lock(adapter->q_vector[q_idx]); +#endif + napi_enable(&q_vector->napi); + } +} + +static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter) +{ + struct ixgbe_q_vector *q_vector; + int q_idx; + + for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++) { + q_vector = adapter->q_vector[q_idx]; + napi_disable(&q_vector->napi); +#ifdef HAVE_NDO_BUSY_POLL + while(!ixgbe_qv_disable(adapter->q_vector[q_idx])) { + pr_info("QV %d locked\n", q_idx); + usleep_range(1000, 20000); + } +#endif + } +} + +#ifdef HAVE_DCBNL_IEEE +s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame) +{ + __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS]; + __u8 prio_type[IEEE_8021QAZ_MAX_TCS]; + int i; + + /* naively give each TC a bwg to map onto CEE hardware */ + __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; + + /* Map TSA onto CEE prio type */ + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + switch (ets->tc_tsa[i]) { + case IEEE_8021QAZ_TSA_STRICT: + prio_type[i] = 2; + break; + case IEEE_8021QAZ_TSA_ETS: + prio_type[i] = 0; + break; + default: + /* Hardware only supports priority strict or + * ETS transmission selection algorithms if + * we receive some other value from dcbnl + * throw an error + */ + return -EINVAL; + } + } + + ixgbe_dcb_calculate_tc_credits(ets->tc_tx_bw, refill, max, max_frame); + return ixgbe_dcb_hw_config(hw, refill, max, + bwg_id, prio_type, ets->prio_tc); +} +#endif /* HAVE_DCBNL_IEEE */ + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) +void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vxlanctrl; + + if (!(adapter->flags & (IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE | + IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))) + return; + + vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) & ~mask; + IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl); + + if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK) + adapter->vxlan_port = 0; +#ifdef HAVE_UDP_ENC_RX_OFFLOAD + if (mask & IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK) + adapter->geneve_port = 0; +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ +} +#endif /* HAVE_UDP_ENC_RX_OFFLOAD || HAVE_VXLAN_RX_OFFLOAD */ + +#ifdef NETIF_F_GSO_PARTIAL +/* NETIF_F_GSO_IPXIP4/6 may not be defined in all distributions */ +#ifndef NETIF_F_GSO_IPXIP4 +#define NETIF_F_GSO_IPXIP4 0 +#endif +#ifndef NETIF_F_GSO_IPXIP6 +#define NETIF_F_GSO_IPXIP6 0 +#endif +#define IXGBE_GSO_PARTIAL_FEATURES (NETIF_F_GSO_GRE | \ + NETIF_F_GSO_GRE_CSUM | \ + NETIF_F_GSO_IPXIP4 | \ + NETIF_F_GSO_IPXIP6 | \ + NETIF_F_GSO_UDP_TUNNEL | \ + NETIF_F_GSO_UDP_TUNNEL_CSUM) +#endif /* NETIF_F_GSO_PARTIAL */ + +static inline unsigned long ixgbe_tso_features(void) +{ + unsigned long features = 0; + +#ifdef NETIF_F_TSO + features |= NETIF_F_TSO; +#endif /* NETIF_F_TSO */ +#ifdef NETIF_F_TSO6 + features |= NETIF_F_TSO6; +#endif /* NETIF_F_TSO6 */ +#ifdef NETIF_F_GSO_PARTIAL + features |= NETIF_F_GSO_PARTIAL | IXGBE_GSO_PARTIAL_FEATURES; +#endif + + return features; +} + +/* + * ixgbe_configure_dcb - Configure DCB hardware support + * @adapter: ixgbe adapter struct + * + * Called when the driver opens or needs to reconfigure DCB related bits. + */ +static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + + int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + + /* The following workaround for 82598EB was originaly hidden inside a + * kcompat definition of netif_set_gso_max_size. This workaround is + * necessary as the 82598EB hardware does not support TSO and DCB + * unless the stack TSO maximum segment size can be reduced. Older + * kernels do not support the requisite interface, and thus need TSO + * disabled if we want to support DCB. + */ + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) { + if (hw->mac.type == ixgbe_mac_82598EB) { +#ifdef HAVE_NETIF_SET_TSO_MAX + netif_set_tso_max_size(netdev, 65536); +#else +#ifdef NETDEV_CAN_SET_GSO_MAX_SIZE + netif_set_gso_max_size(netdev, 65536); +#else + /* We previously disabled TSO, so we should enable it + * now. */ + netdev->features |= ixgbe_tso_features(); +#ifdef NETIF_F_GSO_PARTIAL + netdev->gso_partial_features = + IXGBE_GSO_PARTIAL_FEATURES; +#endif +#endif /* NETDEV_CAN_SET_GSO_MAX_SIZE */ +#endif /* HAVE_NETIF_SET_TSO_MAX */ + } + return; + } + + if (hw->mac.type == ixgbe_mac_82598EB) { +#ifdef HAVE_NETIF_SET_TSO_MAX + netif_set_tso_max_size(netdev, 32768); +#else +#ifdef NETDEV_CAN_SET_GSO_MAX_SIZE + netif_set_gso_max_size(netdev, 32768); +#else + /* Simply disable TSO since we cannot change the maximum + * segment size. */ + netdev->features &= ~ixgbe_tso_features(); +#ifdef NETIF_F_GSO_PARTIAL + netdev->gso_partial_features = 0; +#endif +#endif /* NETDEV_CAN_SET_GSO_MAX_SIZE */ +#endif /* HAVE_NETIF_SET_TSO_MAX */ + } + +#if IS_ENABLED(CONFIG_FCOE) +#ifdef HAVE_NETDEV_FCOE_MTU + if (netdev->fcoe_mtu) +#else + if (netdev->features & NETIF_F_FCOE_MTU) +#endif + max_frame = max_t(int, max_frame, + IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif /* CONFIG_FCOE */ + +#ifdef HAVE_DCBNL_IEEE + if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) { + if (adapter->ixgbe_ieee_ets) + ixgbe_dcb_hw_ets(&adapter->hw, + adapter->ixgbe_ieee_ets, + max_frame); + + if (adapter->ixgbe_ieee_pfc && adapter->ixgbe_ieee_ets) { + struct ieee_pfc *pfc = adapter->ixgbe_ieee_pfc; + u8 *tc = adapter->ixgbe_ieee_ets->prio_tc; + + ixgbe_dcb_config_pfc(&adapter->hw, pfc->pfc_en, tc); + } + } else +#endif /* HAVE_DCBNL_IEEE */ + { + ixgbe_dcb_calculate_tc_credits_cee(hw, + &adapter->dcb_cfg, + max_frame, + IXGBE_DCB_TX_CONFIG); + ixgbe_dcb_calculate_tc_credits_cee(hw, + &adapter->dcb_cfg, + max_frame, + IXGBE_DCB_RX_CONFIG); + ixgbe_dcb_hw_config_cee(hw, &adapter->dcb_cfg); + } + + /* Enable RSS Hash per TC */ + if (hw->mac.type != ixgbe_mac_82598EB) { + u32 msb = 0; + u16 rss_i = adapter->ring_feature[RING_F_RSS].indices - 1; + + while (rss_i) { + msb++; + rss_i >>= 1; + } + + /* write msb to all 8 TCs in one write */ + IXGBE_WRITE_REG(hw, IXGBE_RQTC, msb * 0x11111111); + } +} + +#ifndef IXGBE_NO_LLI +static void ixgbe_configure_lli_82599(struct ixgbe_adapter *adapter) +{ + u16 port; + + if (adapter->lli_etype) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_L34T_IMIR(0), + (IXGBE_IMIR_LLI_EN_82599 | + IXGBE_IMIR_SIZE_BP_82599 | + IXGBE_IMIR_CTRL_BP_82599)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_ETQS(0), IXGBE_ETQS_LLI); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_ETQF(0), + (adapter->lli_etype | IXGBE_ETQF_FILTER_EN)); + } + + if (adapter->lli_port) { + port = swab16(adapter->lli_port); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_L34T_IMIR(0), + (IXGBE_IMIR_LLI_EN_82599 | + IXGBE_IMIR_SIZE_BP_82599 | + IXGBE_IMIR_CTRL_BP_82599)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FTQF(0), + (IXGBE_FTQF_POOL_MASK_EN | + (IXGBE_FTQF_PRIORITY_MASK << + IXGBE_FTQF_PRIORITY_SHIFT) | + (IXGBE_FTQF_DEST_PORT_MASK << + IXGBE_FTQF_5TUPLE_MASK_SHIFT))); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_SDPQF(0), (port << 16)); + } + + if (adapter->flags & IXGBE_FLAG_LLI_PUSH) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_L34T_IMIR(0), + (IXGBE_IMIR_LLI_EN_82599 | + IXGBE_IMIR_SIZE_BP_82599 | + IXGBE_IMIR_CTRL_PSH_82599 | + IXGBE_IMIR_CTRL_SYN_82599 | + IXGBE_IMIR_CTRL_URG_82599 | + IXGBE_IMIR_CTRL_ACK_82599 | + IXGBE_IMIR_CTRL_RST_82599 | + IXGBE_IMIR_CTRL_FIN_82599)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_LLITHRESH, + 0xfc000000); + break; + case ixgbe_mac_X540: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_L34T_IMIR(0), + (IXGBE_IMIR_LLI_EN_82599 | + IXGBE_IMIR_SIZE_BP_82599 | + IXGBE_IMIR_CTRL_PSH_82599)); + break; + default: + break; + } + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FTQF(0), + (IXGBE_FTQF_POOL_MASK_EN | + (IXGBE_FTQF_PRIORITY_MASK << + IXGBE_FTQF_PRIORITY_SHIFT) | + (IXGBE_FTQF_5TUPLE_MASK_MASK << + IXGBE_FTQF_5TUPLE_MASK_SHIFT))); + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_SYNQF, 0x80000100); + } + + if (adapter->lli_size) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_L34T_IMIR(0), + (IXGBE_IMIR_LLI_EN_82599 | + IXGBE_IMIR_CTRL_BP_82599)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_LLITHRESH, + adapter->lli_size); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FTQF(0), + (IXGBE_FTQF_POOL_MASK_EN | + (IXGBE_FTQF_PRIORITY_MASK << + IXGBE_FTQF_PRIORITY_SHIFT) | + (IXGBE_FTQF_5TUPLE_MASK_MASK << + IXGBE_FTQF_5TUPLE_MASK_SHIFT))); + } + + if (adapter->lli_vlan_pri) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIRVP, + (IXGBE_IMIRVP_PRIORITY_EN | + adapter->lli_vlan_pri)); + } +} + +static void ixgbe_configure_lli(struct ixgbe_adapter *adapter) +{ + u16 port; + + /* lli should only be enabled with MSI-X and MSI */ + if (!(adapter->flags & IXGBE_FLAG_MSI_ENABLED) && + !(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) + return; + /* LLI not supported on X550 and X550EM_x*/ + if ((adapter->hw.mac.type == ixgbe_mac_X550) || + (adapter->hw.mac.type == ixgbe_mac_X550EM_x)) + return; + /* LLI not supported on X550EM_a */ + if (adapter->hw.mac.type == ixgbe_mac_X550EM_a) + return; + /* LLI not supported on X550 and E610 */ + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + return; + + if (adapter->hw.mac.type != ixgbe_mac_82598EB) { + ixgbe_configure_lli_82599(adapter); + return; + } + + if (adapter->lli_port) { + /* use filter 0 for port */ + port = swab16(adapter->lli_port); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIR(0), + (port | IXGBE_IMIR_PORT_IM_EN)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIREXT(0), + (IXGBE_IMIREXT_SIZE_BP | + IXGBE_IMIREXT_CTRL_BP)); + } + + if (adapter->flags & IXGBE_FLAG_LLI_PUSH) { + /* use filter 1 for push flag */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIR(1), + (IXGBE_IMIR_PORT_BP | IXGBE_IMIR_PORT_IM_EN)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIREXT(1), + (IXGBE_IMIREXT_SIZE_BP | + IXGBE_IMIREXT_CTRL_PSH)); + } + + if (adapter->lli_size) { + /* use filter 2 for size */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIR(2), + (IXGBE_IMIR_PORT_BP | IXGBE_IMIR_PORT_IM_EN)); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_IMIREXT(2), + (adapter->lli_size | IXGBE_IMIREXT_CTRL_BP)); + } +} + +#endif /* IXGBE_NO_LLI */ +/* Additional bittime to account for IXGBE framing */ +#define IXGBE_ETH_FRAMING 20 + +/* + * ixgbe_hpbthresh - calculate high water mark for flow control + * + * @adapter: board private structure to calculate for + * @pb - packet buffer to calculate + */ +static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct net_device *dev = adapter->netdev; + int link, tc, kb, marker; + u32 dv_id, rx_pba; + + /* Calculate max LAN frame size */ + tc = link = dev->mtu + ETH_HLEN + ETH_FCS_LEN + IXGBE_ETH_FRAMING; + +#if IS_ENABLED(CONFIG_FCOE) + /* FCoE traffic class uses FCOE jumbo frames */ +#ifdef HAVE_NETDEV_FCOE_MTU + if (dev->fcoe_mtu && tc < IXGBE_FCOE_JUMBO_FRAME_SIZE && + (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up))) +#else + if ((dev->features & NETIF_F_FCOE_MTU) && + (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) && + (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up))) +#endif + tc = IXGBE_FCOE_JUMBO_FRAME_SIZE; +#endif /* CONFIG_FCOE */ + + /* Calculate delay value for device */ + switch (hw->mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + dv_id = IXGBE_DV_X540(link, tc); + break; + default: + dv_id = IXGBE_DV(link, tc); + break; + } + + /* Loopback switch introduces additional latency */ + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + dv_id += IXGBE_B2BT(tc); + + /* Delay value is calculated in bit times convert to KB */ + kb = IXGBE_BT2KB(dv_id); + rx_pba = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(pb)) >> 10; + + marker = rx_pba - kb; + + /* It is possible that the packet buffer is not large enough + * to provide required headroom. In this case throw an error + * to user and a do the best we can. + */ + if (marker < 0) { + e_warn(drv, "Packet Buffer(%i) can not provide enough" + "headroom to suppport flow control." + "Decrease MTU or number of traffic classes\n", pb); + marker = tc + 1; + } + + return marker; +} + +/* + * ixgbe_lpbthresh - calculate low water mark for for flow control + * + * @adapter: board private structure to calculate for + * @pb - packet buffer to calculate + */ +static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int __maybe_unused pb) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct net_device *dev = adapter->netdev; + int tc; + u32 dv_id; + + /* Calculate max LAN frame size */ + tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN; + +#if IS_ENABLED(CONFIG_FCOE) + /* FCoE traffic class uses FCOE jumbo frames */ +#ifdef HAVE_NETDEV_FCOE_MTU + if (dev->fcoe_mtu && tc < IXGBE_FCOE_JUMBO_FRAME_SIZE && + (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up))) +#else + if ((dev->features & NETIF_F_FCOE_MTU) && + (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) && + (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up))) +#endif /* HAVE_NETDEV_FCOE_MTU */ + tc = IXGBE_FCOE_JUMBO_FRAME_SIZE; +#endif /* CONFIG_FCOE */ + + /* Calculate delay value for device */ + switch (hw->mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + dv_id = IXGBE_LOW_DV_X540(tc); + break; + default: + dv_id = IXGBE_LOW_DV(tc); + break; + } + + /* Delay value is calculated in bit times convert to KB */ + return IXGBE_BT2KB(dv_id); +} + +/* + * ixgbe_pbthresh_setup - calculate and setup high low water marks + */ +static void ixgbe_pbthresh_setup(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int num_tc = netdev_get_num_tc(adapter->netdev); + int i; + + if (!num_tc) + num_tc = 1; + + + for (i = 0; i < num_tc; i++) { + hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i); + hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i); + + /* Low water marks must not be larger than high water marks */ + if (hw->fc.low_water[i] > hw->fc.high_water[i]) + hw->fc.low_water[i] = 0; + } + + for (; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) + hw->fc.high_water[i] = 0; +} + +static void ixgbe_configure_pb(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int hdrm; + u8 tc = netdev_get_num_tc(adapter->netdev); + + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || + adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) + hdrm = 32 << adapter->fdir_pballoc; + else + hdrm = 0; + + hw->mac.ops.setup_rxpba(hw, tc, hdrm, PBA_STRATEGY_EQUAL); + ixgbe_pbthresh_setup(adapter); +} + +static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct hlist_node *node2; + struct ixgbe_fdir_filter *filter; + u8 queue = 0; + + spin_lock(&adapter->fdir_perfect_lock); + + if (!hlist_empty(&adapter->fdir_filter_list)) + ixgbe_fdir_set_input_mask_82599(hw, &adapter->fdir_mask, + adapter->cloud_mode); + + hlist_for_each_entry_safe(filter, node2, + &adapter->fdir_filter_list, fdir_node) { + if (filter->action == IXGBE_FDIR_DROP_QUEUE) { + queue = IXGBE_FDIR_DROP_QUEUE; + } else { + u32 ring = ethtool_get_flow_spec_ring(filter->action); + u8 vf = ethtool_get_flow_spec_ring_vf(filter->action); + + if (!vf && ring >= adapter->num_rx_queues) { + e_err(drv, + "FDIR restore failed w/o vf, ring:%u\n", + ring); + continue; + } else if (vf && + ((vf > adapter->num_vfs) || + ring >= adapter->num_rx_queues_per_pool)) { + e_err(drv, + "FDIR restore failed vf:%hhu, ring:%u\n", + vf, ring); + continue; + } + + /* Map the ring onto the absolute queue index */ + if (!vf) + queue = adapter->rx_ring[ring]->reg_idx; + else + queue = ((vf - 1) * + adapter->num_rx_queues_per_pool) + ring; + } + + ixgbe_fdir_write_perfect_filter_82599(hw, + &filter->filter, + filter->sw_idx, + queue, + adapter->cloud_mode); + } + + spin_unlock(&adapter->fdir_perfect_lock); +} + +/** + * ixgbe_clean_rx_ring - Free Rx Buffers per Queue + * @rx_ring: ring to free buffers from + **/ +static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) +{ + u16 i = rx_ring->next_to_clean; + struct ixgbe_rx_buffer *rx_buffer = &rx_ring->rx_buffer_info[i]; +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); + dma_set_attr(DMA_ATTR_WEAK_ORDERING, &attrs); +#endif + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (rx_ring->xsk_pool) { + ixgbe_xsk_clean_rx_ring(rx_ring); + goto skip_free; + } + +#endif + /* Free all the Rx ring sk_buffs */ +#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + while (i != rx_ring->next_to_use) { +#else + while (i != rx_ring->next_to_alloc) { +#endif + if (rx_buffer->skb) { + struct sk_buff *skb = rx_buffer->skb; +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + if (IXGBE_CB(skb)->page_released) + dma_unmap_page_attrs(rx_ring->dev, + IXGBE_CB(skb)->dma, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE, +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + &attrs); +#else + IXGBE_RX_DMA_ATTR); +#endif +#else + /* We need to clean up RSC frag lists */ + skb = ixgbe_merge_active_tail(skb); + if (ixgbe_close_active_frag_list(skb)) + dma_unmap_single(rx_ring->dev, + IXGBE_CB(skb)->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + IXGBE_CB(skb)->dma = 0; +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + dev_kfree_skb(skb); + rx_buffer->skb = NULL; + } + +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + /* Invalidate cache lines that may have been written to by + * device so that we avoid corrupting memory. + */ + dma_sync_single_range_for_cpu(rx_ring->dev, + rx_buffer->dma, + rx_buffer->page_offset, + ixgbe_rx_bufsz(rx_ring), + DMA_FROM_DEVICE); + + /* free resources associated with mapping */ + dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE, +#if defined(HAVE_STRUCT_DMA_ATTRS) && defined(HAVE_SWIOTLB_SKIP_CPU_SYNC) + &attrs); +#else + IXGBE_RX_DMA_ATTR); +#endif + + __page_frag_cache_drain(rx_buffer->page, + rx_buffer->pagecnt_bias); +#else /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + if (rx_buffer->dma) { + dma_unmap_single(rx_ring->dev, + rx_buffer->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + rx_buffer->dma = 0; + } +#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */ + i++; + rx_buffer++; + if (i == rx_ring->count) { + i = 0; + rx_buffer = rx_ring->rx_buffer_info; + } + } + +#ifdef HAVE_AF_XDP_ZC_SUPPORT +skip_free: +#endif +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT + rx_ring->next_to_alloc = 0; + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; +#endif +} + +static inline bool ixgbe_is_eee_enabled(struct ixgbe_adapter *adapter) +{ + return (adapter->eee_state == IXGBE_EEE_ENABLED); +} + +static void ixgbe_configure(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + ixgbe_configure_pb(adapter); + ixgbe_configure_dcb(adapter); + + /* + * We must restore virtualization before VLANs or else + * the VLVF registers will not be populated + */ + ixgbe_configure_virtualization(adapter); + + ixgbe_set_rx_mode(adapter->netdev); +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) + ixgbe_restore_vlan(adapter); +#endif + + if (adapter->hw.mac.type == ixgbe_mac_82599EB || + adapter->hw.mac.type == ixgbe_mac_X540) + hw->mac.ops.disable_sec_rx_path(hw); + + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { + ixgbe_init_fdir_signature_82599(&adapter->hw, + adapter->fdir_pballoc); + } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { + ixgbe_init_fdir_perfect_82599(&adapter->hw, + adapter->fdir_pballoc, adapter->cloud_mode); + ixgbe_fdir_filter_restore(adapter); + } + + if (adapter->hw.mac.type == ixgbe_mac_82599EB || + adapter->hw.mac.type == ixgbe_mac_X540) + hw->mac.ops.enable_sec_rx_path(hw); + + /* Enable EEE only when supported and enabled */ + if (hw->mac.ops.setup_eee && + (adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE)) { + bool eee_enable = ixgbe_is_eee_enabled(adapter); + + hw->mac.ops.setup_eee(hw, eee_enable); + } + +#if IS_ENABLED(CONFIG_DCA) + /* configure DCA */ + if (adapter->flags & IXGBE_FLAG_DCA_CAPABLE) + ixgbe_setup_dca(adapter); +#endif + +#if IS_ENABLED(CONFIG_FCOE) + /* configure FCoE L2 filters, redirection table, and Rx control */ + ixgbe_configure_fcoe(adapter); +#endif /* CONFIG_FCOE */ + + ixgbe_configure_tx(adapter); + ixgbe_configure_rx(adapter); +} + +/** + * ixgbe_enable_link_status_events - enable link status events + * @adapter: pointer to the adapter structure + * @mask: event mask to be set + * + * Enables link status events by invoking ixgbe_configure_lse() + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_enable_link_status_events(struct ixgbe_adapter *adapter, + u16 mask) +{ + s32 rc; + + rc = ixgbe_configure_lse(&adapter->hw, true, mask); + if (rc) + return rc; + + adapter->lse_mask = mask; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_disable_link_status_events - disable link status events + * @adapter: pointer to the adapter structure + * + * Disables link status events by invoking ixgbe_configure_lse() + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_disable_link_status_events(struct ixgbe_adapter *adapter) +{ + s32 rc; + + rc = ixgbe_configure_lse(&adapter->hw, false, adapter->lse_mask); + if (rc) + return rc; + + adapter->lse_mask = 0; + return IXGBE_SUCCESS; +} + +static bool ixgbe_is_sfp(struct ixgbe_hw *hw) +{ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + if (hw->phy.type == ixgbe_phy_nl) + return true; + return false; + case ixgbe_mac_82599EB: + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_fiber_qsfp: + return true; + default: + return false; + } + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) + return true; + return false; + default: + return false; + } +} + +/** + * ixgbe_sfp_link_config - set up SFP+ link + * @adapter: pointer to private adapter struct + **/ +static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) +{ + /* + * We are assuming the worst case scenerio here, and that + * is that an SFP was inserted/removed after the reset + * but before SFP detection was enabled. As such the best + * solution is to just start searching as soon as we start + */ + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; + + adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; + adapter->sfp_poll_time = 0; +} + +/** + * ixgbe_non_sfp_link_config - set up non-SFP+ link + * @hw: pointer to private hardware struct + * + * Returns 0 on success, negative on failure + **/ +static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) +{ + u16 mask = ~((u16)(IXGBE_ACI_LINK_EVENT_UPDOWN | + IXGBE_ACI_LINK_EVENT_MEDIA_NA | + IXGBE_ACI_LINK_EVENT_MODULE_QUAL_FAIL | + IXGBE_ACI_LINK_EVENT_PHY_FW_LOAD_FAIL)); + struct ixgbe_adapter *adapter = container_of(hw, struct ixgbe_adapter, + hw); + int ret = IXGBE_ERR_LINK_SETUP; + bool autoneg, link_up = false; + u32 speed; + + if (hw->mac.ops.check_link) + ret = hw->mac.ops.check_link(hw, &speed, &link_up, false); + + if (ret) + goto link_cfg_out; + + speed = hw->phy.autoneg_advertised; + if (!speed && hw->mac.ops.get_link_capabilities) { + ret = hw->mac.ops.get_link_capabilities(hw, &speed, + &autoneg); + speed &= ~(IXGBE_LINK_SPEED_5GB_FULL | + IXGBE_LINK_SPEED_2_5GB_FULL); + } + + if (ret) + goto link_cfg_out; + + if (hw->mac.ops.setup_link) { + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + ret = ixgbe_enable_link_status_events(adapter, mask); + if (ret) + goto link_cfg_out; + } + ret = hw->mac.ops.setup_link(hw, speed, link_up); + } +link_cfg_out: + return ret; +} + +/** + * ixgbe_check_media_subtask - Check for media + * @adapter: pointer to adapter structure + * + * If media is available, then initialize PHY user configuration if it is not + * been, and configure the PHY if the interface is up. + */ +static void ixgbe_check_media_subtask(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + /* No need to check for media if it's already present */ + if (!(adapter->flags2 & IXGBE_FLAG2_NO_MEDIA)) + return; + + /* Refresh link info and check if media is present */ + if (ixgbe_update_link_info(hw)) + return; + + ixgbe_check_link_cfg_err(adapter, hw->link.link_info.link_cfg_err); + + if (hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE) { + /* PHY settings are reset on media insertion, reconfigure + * PHY to preserve settings. + */ + if (!(ixgbe_non_sfp_link_config(&adapter->hw))) + adapter->flags2 &= ~IXGBE_FLAG2_NO_MEDIA; + + /* A Link Status Event will be generated; the event handler + * will complete bringing the interface up + */ + } +} +/** + * ixgbe_clear_vf_stats_counters - Clear out VF stats after reset + * @adapter: board private structure + * + * On a reset we need to clear out the VF stats or accounting gets + * messed up because they're not clear on read. + **/ +static void ixgbe_clear_vf_stats_counters(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + + for (i = 0; i < adapter->num_vfs; i++) { + adapter->vfinfo[i].last_vfstats.gprc = + IXGBE_READ_REG(hw, IXGBE_PVFGPRC(i)); + adapter->vfinfo[i].saved_rst_vfstats.gprc += + adapter->vfinfo[i].vfstats.gprc; + adapter->vfinfo[i].vfstats.gprc = 0; + adapter->vfinfo[i].last_vfstats.gptc = + IXGBE_READ_REG(hw, IXGBE_PVFGPTC(i)); + adapter->vfinfo[i].saved_rst_vfstats.gptc += + adapter->vfinfo[i].vfstats.gptc; + adapter->vfinfo[i].vfstats.gptc = 0; + adapter->vfinfo[i].last_vfstats.gorc = + IXGBE_READ_REG(hw, IXGBE_PVFGORC_LSB(i)); + adapter->vfinfo[i].saved_rst_vfstats.gorc += + adapter->vfinfo[i].vfstats.gorc; + adapter->vfinfo[i].vfstats.gorc = 0; + adapter->vfinfo[i].last_vfstats.gotc = + IXGBE_READ_REG(hw, IXGBE_PVFGOTC_LSB(i)); + adapter->vfinfo[i].saved_rst_vfstats.gotc += + adapter->vfinfo[i].vfstats.gotc; + adapter->vfinfo[i].vfstats.gotc = 0; + adapter->vfinfo[i].last_vfstats.mprc = + IXGBE_READ_REG(hw, IXGBE_PVFMPRC(i)); + adapter->vfinfo[i].saved_rst_vfstats.mprc += + adapter->vfinfo[i].vfstats.mprc; + adapter->vfinfo[i].vfstats.mprc = 0; + } +} + +static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 gpie = 0; + + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + gpie = IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT | + IXGBE_GPIE_OCD; + gpie |= IXGBE_GPIE_EIAME; + /* + * use EIAM to auto-mask when MSI-X interrupt is asserted + * this saves a register write for every interrupt + */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + default: + IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF); + IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF); + break; + } + } else { + /* legacy interrupts, use EIAM to auto-mask when reading EICR, + * specifically only auto mask tx and rx interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); + } + + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + gpie &= ~IXGBE_GPIE_VTMODE_MASK; + + switch (adapter->ring_feature[RING_F_VMDQ].mask) { + case IXGBE_82599_VMDQ_8Q_MASK: + gpie |= IXGBE_GPIE_VTMODE_16; + break; + case IXGBE_82599_VMDQ_4Q_MASK: + gpie |= IXGBE_GPIE_VTMODE_32; + break; + default: + gpie |= IXGBE_GPIE_VTMODE_64; + break; + } + } + + /* Enable Thermal over heat sensor interrupt */ + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + gpie |= IXGBE_SDP0_GPIEN; + break; + default: + break; + } + + /* Enable fan failure interrupt */ + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) + gpie |= IXGBE_SDP1_GPIEN; + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + gpie |= IXGBE_SDP1_GPIEN | IXGBE_SDP2_GPIEN; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + gpie |= IXGBE_SDP0_GPIEN_X540; + break; + default: + break; + } + + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); +} + +static void ixgbe_up_complete(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + u32 ctrl_ext; + + ixgbe_get_hw_control(adapter); + ixgbe_setup_gpie(adapter); + + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) + ixgbe_configure_msix(adapter); + else + ixgbe_configure_msi_and_legacy(adapter); + + /* enable the optics for 82599 SFP+ fiber */ + if (hw->mac.ops.enable_tx_laser) + hw->mac.ops.enable_tx_laser(hw); + ixgbe_set_phy_power(hw, true); + + smp_mb__before_atomic(); + clear_bit(__IXGBE_DOWN, adapter->state); + ixgbe_napi_enable_all(adapter); +#ifndef IXGBE_NO_LLI + ixgbe_configure_lli(adapter); +#endif + + if (ixgbe_is_sfp(hw)) { + ixgbe_sfp_link_config(adapter); + } else if (!hw->phy.reset_disable) { + err = ixgbe_non_sfp_link_config(hw); + if (err) + e_err(probe, "link_config FAILED %d\n", err); + } + + /* clear any pending interrupts, may auto mask */ + IXGBE_READ_REG(hw, IXGBE_EICR); + ixgbe_irq_enable(adapter, true, true); + + /* + * If this adapter has a fan, check to see if we had a failure + * before we enabled the interrupt. + */ + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) { + u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (esdp & IXGBE_ESDP_SDP1) + e_crit(drv, "Fan has stopped, replace the adapter\n"); + } + + /* enable transmits */ + netif_tx_start_all_queues(adapter->netdev); + + /* bring the link up in the watchdog, this could race with our first + * link up interrupt but shouldn't be a problem */ + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; + mod_timer(&adapter->service_timer, jiffies); + + ixgbe_clear_vf_stats_counters(adapter); + /* Set PF Reset Done bit so PF/VF Mail Ops can work */ + ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); + ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + + /* update setting rx tx for all active vfs */ + ixgbe_set_all_vfs(adapter); +} + +void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) +{ + WARN_ON(in_interrupt()); + /* put off any impending NetWatchDogTimeout */ +#ifdef HAVE_NETIF_TRANS_UPDATE + netif_trans_update(adapter->netdev); +#else + adapter->netdev->trans_start = jiffies; +#endif + + while (test_and_set_bit(__IXGBE_RESETTING, adapter->state)) + usleep_range(1000, 2000); + if (adapter->hw.phy.type == ixgbe_phy_fw) + ixgbe_watchdog_link_is_down(adapter); + ixgbe_down(adapter); + /* + * If SR-IOV enabled then wait a bit before bringing the adapter + * back up to give the VFs time to respond to the reset. The + * two second wait is based upon the watchdog timer cycle in + * the VF driver. + */ + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + msleep(2000); + ixgbe_up(adapter); + clear_bit(__IXGBE_RESETTING, adapter->state); +} + +void ixgbe_up(struct ixgbe_adapter *adapter) +{ + /* hardware has been reset, we need to reload some things */ + ixgbe_configure(adapter); + + ixgbe_up_complete(adapter); +} + +static unsigned long ixgbe_get_completion_timeout(struct ixgbe_adapter *adapter) +{ + u16 devctl2; + + pcie_capability_read_word(adapter->pdev, PCI_EXP_DEVCTL2, &devctl2); + + switch (devctl2 & IXGBE_PCIDEVCTRL2_TIMEO_MASK) { + case IXGBE_PCIDEVCTRL2_17_34s: + case IXGBE_PCIDEVCTRL2_4_8s: + /* For now we cap the upper limit on delay to 2 seconds + * as we end up going up to 34 seconds of delay in worst + * case timeout value. + */ + case IXGBE_PCIDEVCTRL2_1_2s: + return 2000000ul; /* 2.0 s */ + case IXGBE_PCIDEVCTRL2_260_520ms: + return 520000ul; /* 520 ms */ + case IXGBE_PCIDEVCTRL2_65_130ms: + return 130000ul; /* 130 ms */ + case IXGBE_PCIDEVCTRL2_16_32ms: + return 32000ul; /* 32 ms */ + case IXGBE_PCIDEVCTRL2_1_2ms: + return 2000ul; /* 2 ms */ + case IXGBE_PCIDEVCTRL2_50_100us: + return 100ul; /* 100 us */ + case IXGBE_PCIDEVCTRL2_16_32ms_def: + return 32000ul; /* 32 ms */ + default: + break; + } + + /* We shouldn't need to hit this path, but just in case default as + * though completion timeout is not supported and support 32ms. + */ + return 32000ul; +} + +void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter) +{ + unsigned long wait_delay, delay_interval; + struct ixgbe_hw *hw = &adapter->hw; + int i, wait_loop; + u32 rxdctl; + + /* disable receives */ + hw->mac.ops.disable_rx(hw); + + if (IXGBE_REMOVED(hw->hw_addr)) + return; + + /* disable all enabled Rx queues */ + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + u8 reg_idx = ring->reg_idx; + + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + rxdctl &= ~IXGBE_RXDCTL_ENABLE; + rxdctl |= IXGBE_RXDCTL_SWFLSH; + + /* write value back with RXDCTL.ENABLE bit cleared */ + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); + } + + /* RXDCTL.EN may not change on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + /* Determine our minimum delay interval. We will increase this value + * with each subsequent test. This way if the device returns quickly + * we should spend as little time as possible waiting, however as + * the time increases we will wait for larger periods of time. + * + * The trick here is that we increase the interval using the + * following pattern: 1x 3x 5x 7x 9x 11x 13x 15x 17x 19x. The result + * of that wait is that it totals up to 100x whatever interval we + * choose. Since our minimum wait is 100us we can just divide the + * total timeout by 100 to get our minimum delay interval. + */ + delay_interval = ixgbe_get_completion_timeout(adapter) / 100; + + wait_loop = IXGBE_MAX_RX_DESC_POLL; + wait_delay = delay_interval; + + while (wait_loop--) { + usleep_range(wait_delay, wait_delay + 10); + wait_delay += delay_interval * 2; + rxdctl = 0; + + /* OR together the reading of all the active RXDCTL registers, + * and then test the result. We need the disable to complete + * before we start freeing the memory and invalidating the + * DMA mappings. + */ + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + u8 reg_idx = ring->reg_idx; + + rxdctl |= IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + } + + if (!(rxdctl & IXGBE_RXDCTL_ENABLE)) + return; + } + + e_err(drv, + "RXDCTL.ENABLE for one or more queues not cleared within the polling period\n"); +} + +void ixgbe_disable_tx_queue(struct ixgbe_adapter *adapter) +{ + unsigned long wait_delay, delay_interval; + struct ixgbe_hw *hw = &adapter->hw; + int i, wait_loop; + u32 txdctl; + + if (IXGBE_REMOVED(hw->hw_addr)) + return; + + /* disable all enabled Tx queues */ + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *ring = adapter->tx_ring[i]; + u8 reg_idx = ring->reg_idx; + + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH); + } + + /* disable all enabled XDP Tx queues */ + for (i = 0; i < adapter->num_xdp_queues; i++) { + struct ixgbe_ring *ring = adapter->xdp_ring[i]; + u8 reg_idx = ring->reg_idx; + + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH); + } + + /* If the link is not up there shouldn't be much in the way of + * pending transactions. Those that are left will be flushed out + * when the reset logic goes through the flush sequence to clean out + * the pending Tx transactions. + */ + if (!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + goto dma_engine_disable; + + /* Determine our minimum delay interval. We will increase this value + * with each subsequent test. This way if the device returns quickly + * we should spend as little time as possible waiting, however as + * the time increases we will wait for larger periods of time. + * + * The trick here is that we increase the interval using the + * following pattern: 1x 3x 5x 7x 9x 11x 13x 15x 17x 19x. The result + * of that wait is that it totals up to 100x whatever interval we + * choose. Since our minimum wait is 100us we can just divide the + * total timeout by 100 to get our minimum delay interval. + */ + delay_interval = ixgbe_get_completion_timeout(adapter) / 100; + + wait_loop = IXGBE_MAX_RX_DESC_POLL; + wait_delay = delay_interval; + + while (wait_loop--) { + usleep_range(wait_delay, wait_delay + 10); + wait_delay += delay_interval * 2; + txdctl = 0; + + /* OR together the reading of all the active TXDCTL registers, + * and then test the result. We need the disable to complete + * before we start freeing the memory and invalidating the + * DMA mappings. + */ + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *ring = adapter->tx_ring[i]; + u8 reg_idx = ring->reg_idx; + + txdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + } + for (i = 0; i < adapter->num_xdp_queues; i++) { + struct ixgbe_ring *ring = adapter->xdp_ring[i]; + u8 reg_idx = ring->reg_idx; + + txdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + } + + if (!(txdctl & IXGBE_TXDCTL_ENABLE)) + goto dma_engine_disable; + } + + e_err(drv, + "TXDCTL.ENABLE for one or more queues not cleared within the polling period\n"); + +dma_engine_disable: + /* Disable the Tx DMA engine on 82599 and later MAC */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, + (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & + ~IXGBE_DMATXCTL_TE)); + /* fall through */ + default: + break; + } +} + +bool ixgbe_fwlog_ring_full(struct ixgbe_fwlog_ring *rings) +{ + u16 head, tail; + + head = rings->head; + tail = rings->tail; + + if ((head < tail && (tail - head == (rings->size - 1))) || + (head > tail && (tail == (head - 1)))) + return true; + + return false; +} + +bool ixgbe_fwlog_ring_empty(struct ixgbe_fwlog_ring *rings) +{ + return rings->head == rings->tail; +} + +void ixgbe_fwlog_ring_increment(u16 *item, u16 size) +{ + *item = (*item + 1) & (size - 1); +} + +static int ixgbe_fwlog_alloc_ring_buffs(struct ixgbe_fwlog_ring *rings) +{ + int i, ret = 0; + + for (i = 0; i < rings->size; i++) { + struct ixgbe_fwlog_data *ring = &rings->rings[i]; + + ring->data_size = PAGE_SIZE; + ring->data = vzalloc(ring->data_size); + if (!ring->data) { + ret = -ENOMEM; + break; + } + } + + return ret; +} + +static void ixgbe_fwlog_free_ring_buffs(struct ixgbe_fwlog_ring *rings) +{ + int i; + + for (i = 0; i < rings->size; i++) { + struct ixgbe_fwlog_data *ring = &rings->rings[i]; + + vfree(ring->data); + + ring->data_size = 0; + } +} + +void ixgbe_fwlog_realloc_rings(struct ixgbe_hw *hw, int ring_size) +{ + struct ixgbe_fwlog_ring ring; + struct ixgbe_adapter *adapter = hw->back; + struct device *dev = ixgbe_pf_to_dev(adapter); + int status; + + if (ring_size == hw->fwlog_ring.size) + return; + + /* allocate space for the new rings and buffers then release the + * old rings and buffers. that way if we don't have enough + * memory then we at least have what we had before + */ + ring.rings = kcalloc(IXGBE_FWLOG_RING_SIZE_DFLT, + sizeof(*ring.rings), GFP_KERNEL); + if (!ring.rings) { + dev_warn(dev, "Unable to allocate memory for FW log ring\n"); + return; + } + + ring.size = ring_size; + + status = ixgbe_fwlog_alloc_ring_buffs(&ring); + if (status) { + dev_warn(dev, "Unable to allocate memory for FW log ring data buffers\n"); + ixgbe_fwlog_free_ring_buffs(&ring); + kfree(ring.rings); + return; + } + + ixgbe_fwlog_free_ring_buffs(&hw->fwlog_ring); + kfree(hw->fwlog_ring.rings); + + hw->fwlog_ring.rings = ring.rings; + hw->fwlog_ring.size = ring.size; + hw->fwlog_ring.head = 0; + hw->fwlog_ring.tail = 0; +} + +/** + * ixgbe_pf_fwlog_is_input_valid - validate user input level/events + * @adapter: pointer to the adapter struct + * @user_input: input parameters to validate + * + * Check if user input level or events are valid. + * If the validation fails, the corresponding message is printed. + * + * Return: true if the user input level/events are valid. + */ +static bool +ixgbe_pf_fwlog_is_input_valid(struct ixgbe_adapter *adapter, + struct ixgbe_fwlog_user_input *user_input) +{ + unsigned long events = user_input->events; + u8 log_level = user_input->log_level; + + if (log_level >= IXGBE_FWLOG_LEVEL_INVALID) { + dev_err(ixgbe_pf_to_dev(adapter), + "Invalid FW log level %u, all level(s) >= %u are invalid\n", + log_level, IXGBE_FWLOG_LEVEL_INVALID); + return false; + } + + if (events >= BIT(IXGBE_ACI_FW_LOG_ID_MAX)) { + dev_err(ixgbe_pf_to_dev(adapter), + "Invalid FW log events 0x%lx, all FW log event bits >= 0x%lx are invalid\n", + events, BIT(IXGBE_ACI_FW_LOG_ID_MAX)); + return false; + } + + if (user_input->log_method > IXGBE_FWLOG_METHOD_UART) { + dev_err(ixgbe_pf_to_dev(adapter), + "Invalid FW log method %u, all FW log methods > %u are invalid\n", + user_input->log_method, IXGBE_FWLOG_METHOD_UART); + return false; + } + + return true; +} + +/** + * ixgbe_pf_fwlog_update_modules - update 1 or more modules via debugfs + * @adapter: pointer to the adapter struct + * @log_level: log_level to use for the @events + * @events: events to update + * + * Take all the present modules and + * use ixgbe_fwlog_update_modules to update them. + * + * Return: the exit code of the operation. + */ +int ixgbe_pf_fwlog_update_modules(struct ixgbe_adapter *adapter, u8 log_level, + unsigned long events) +{ + struct ixgbe_fwlog_user_input user_input = { 0 }; + u16 num_entries, module_id, max_bits, i = 0; + struct ixgbe_fwlog_module_entry *entries; + int status; + + user_input.log_level = log_level; + user_input.events = events; + if (!ixgbe_pf_fwlog_is_input_valid(adapter, &user_input)) + return -EINVAL; + + num_entries = hweight_long(events); + entries = (struct ixgbe_fwlog_module_entry *) + kcalloc(num_entries, sizeof(*entries), GFP_KERNEL); + if (!entries) + return -ENOMEM; + + max_bits = min_t(u16, BITS_PER_TYPE(unsigned long), + IXGBE_ACI_FW_LOG_ID_MAX); + + for_each_set_bit(module_id, &events, max_bits) { + entries[i].module_id = module_id; + entries[i].log_level = log_level; + i++; + } + + status = ixgbe_fwlog_update_modules(&adapter->hw, entries, + num_entries); + + kfree(entries); + return status; +} + +s32 ixgbe_fwlog_init(struct ixgbe_hw *hw) +{ + struct ixgbe_adapter *adapter = hw->back; + struct device *dev = ixgbe_pf_to_dev(adapter); + int status; + + ixgbe_fwlog_set_support_ena(hw); + + if (ixgbe_fwlog_supported(hw)) { + /* read the current config from the FW and store it */ + status = ixgbe_fwlog_get(hw, &hw->fwlog_cfg); + if (status) + return status; + + hw->fwlog_ring.rings = kcalloc(IXGBE_FWLOG_RING_SIZE_DFLT, + sizeof(*hw->fwlog_ring.rings), + GFP_KERNEL); + if (!hw->fwlog_ring.rings) { + dev_warn(dev, "Unable to allocate memory for FW log ring\n"); + return -ENOMEM; + } + + hw->fwlog_ring.size = IXGBE_FWLOG_RING_SIZE_DFLT; + + status = ixgbe_fwlog_alloc_ring_buffs(&hw->fwlog_ring); + if (status) { + dev_warn(dev, "Unable to allocate memory for FW log ring data buffers\n"); + ixgbe_fwlog_free_ring_buffs(&hw->fwlog_ring); + kfree(hw->fwlog_ring.rings); + return status; + } + } else { + dev_warn(dev, "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n"); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_pf_fwlog_init - initialize FW logging + * @adapter: pointer to the adapter struct + * + * Initialize Firmware logging configuration on device init. + * + * Return: the exit code of the operation. + */ +static s32 +ixgbe_pf_fwlog_init(struct ixgbe_adapter *adapter) +{ + s32 status; + + if (!adapter->hw.fwlog_support_ena) + return -EOPNOTSUPP; + + adapter->hw.fwlog_cfg.options |= IXGBE_FWLOG_OPTION_REGISTER_ON_INIT; + + status = ixgbe_fwlog_init(&adapter->hw); + if (status) { + dev_err(ixgbe_pf_to_dev(adapter), "Failed to init FW log configuration."); + return status; + } + + if ((adapter->hw.fwlog_cfg.options & IXGBE_FWLOG_OPTION_REGISTER_ON_INIT) && + ixgbe_fwlog_register(&adapter->hw)) + dev_dbg(ixgbe_pf_to_dev(adapter), "Failed to register for FW logging events\n"); + else + dev_dbg(ixgbe_pf_to_dev(adapter), "Failed to re-enable FW logging\n"); + + return 0; +} + +/** + * ixgbe_pf_fwlog_deinit - de-initialize FW logging + * @adapter: pointer to the adapter struct + * + * Cleanup Firmware logging configuration on device de-init. + * + * Return: nothing, just message in dmesg + */ +static void +ixgbe_pf_fwlog_deinit(struct ixgbe_adapter *adapter) +{ + if (ixgbe_fwlog_unregister(&adapter->hw)) { + struct device *dev = ixgbe_pf_to_dev(adapter); + + dev_dbg(dev, + "failed to unregister from FW logging\n"); + } + + ixgbe_fwlog_free_ring_buffs(&adapter->hw.fwlog_ring); + kfree(adapter->hw.fwlog_ring.rings); +} + +void ixgbe_reset(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; +#ifdef HAVE_SET_RX_MODE + struct net_device *netdev = adapter->netdev; +#endif + int err; + + if (IXGBE_REMOVED(hw->hw_addr)) + return; + /* lock SFP init bit to prevent race conditions with the watchdog */ + while (test_and_set_bit(__IXGBE_IN_SFP_INIT, adapter->state)) + usleep_range(1000, 2000); + + /* clear all SFP and link config related flags while holding SFP_INIT */ + adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP | + IXGBE_FLAG2_SFP_NEEDS_RESET); + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; + + err = hw->mac.ops.init_hw(hw); + switch (err) { + case IXGBE_SUCCESS: + case IXGBE_ERR_SFP_NOT_PRESENT: + case IXGBE_ERR_SFP_NOT_SUPPORTED: + break; + case IXGBE_ERR_PRIMARY_REQUESTS_PENDING: + e_dev_err("primary disable timed out\n"); + break; + case IXGBE_ERR_EEPROM_VERSION: + /* We are running on a pre-production device, log a warning */ + e_dev_warn("This device is a pre-production adapter/LOM. " + "Please be aware there may be issues associated " + "with your hardware. If you are experiencing " + "problems please contact your Intel or hardware " + "representative who provided you with this " + "hardware.\n"); + break; + case IXGBE_ERR_OVERTEMP: + e_crit(drv, "%s\n", ixgbe_overheat_msg); + break; + default: + e_dev_err("Hardware Error: %d\n", err); + } + + clear_bit(__IXGBE_IN_SFP_INIT, adapter->state); + + /* flush entries out of MAC table */ + ixgbe_flush_sw_mac_table(adapter); +#ifdef HAVE_SET_RX_MODE + __dev_uc_unsync(netdev, NULL); +#endif + + /* do not flush user set addresses */ + ixgbe_mac_set_default_filter(adapter); + + /* update SAN MAC vmdq pool selection */ + if (hw->mac.san_mac_rar_index) + hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0)); + + /* Clear saved DMA coalescing values except for watchdog_timer */ + hw->mac.dmac_config.fcoe_en = false; + hw->mac.dmac_config.link_speed = 0; + hw->mac.dmac_config.fcoe_tc = 0; + hw->mac.dmac_config.num_tcs = 0; + +#ifdef HAVE_PTP_1588_CLOCK + if (test_bit(__IXGBE_PTP_RUNNING, adapter->state)) { + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_ptp_reset_e600(adapter); + else + ixgbe_ptp_reset(adapter); + } +#endif + + if (!netif_running(adapter->netdev) && !adapter->wol) + ixgbe_set_phy_power(hw, false); + else + ixgbe_set_phy_power(hw, true); +} + +/** + * ixgbe_clean_tx_ring - Free Tx Buffers + * @tx_ring: ring to be cleaned + **/ +static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring) +{ + u16 i = tx_ring->next_to_clean; + struct ixgbe_tx_buffer *tx_buffer = &tx_ring->tx_buffer_info[i]; + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (tx_ring->xsk_pool) { + ixgbe_xsk_clean_tx_ring(tx_ring); + goto out; + } + +#endif + while (i != tx_ring->next_to_use) { + union ixgbe_adv_tx_desc *eop_desc, *tx_desc; + + /* Free all the Tx ring sk_buffs */ +#ifdef HAVE_XDP_SUPPORT + if (ring_is_xdp(tx_ring)) +#ifdef HAVE_XDP_FRAME_STRUCT + xdp_return_frame(tx_buffer->xdpf); +#else + page_frag_free(tx_buffer->data); +#endif + else + dev_kfree_skb_any(tx_buffer->skb); +#else + dev_kfree_skb_any(tx_buffer->skb); +#endif + + /* unmap skb header data */ + dma_unmap_single(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + + /* check for eop_desc to determine the end of the packet */ + eop_desc = tx_buffer->next_to_watch; + tx_desc = IXGBE_TX_DESC(tx_ring, i); + + /* unmap remaining buffers */ + while (tx_desc != eop_desc) { + tx_buffer++; + tx_desc++; + i++; + if (unlikely(i == tx_ring->count)) { + i = 0; + tx_buffer = tx_ring->tx_buffer_info; + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + } + + /* unmap any remaining paged data */ + if (dma_unmap_len(tx_buffer, len)) + dma_unmap_page(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + } + + /* move us one more past the eop_desc for start of next pkt */ + tx_buffer++; + i++; + if (unlikely(i == tx_ring->count)) { + i = 0; + tx_buffer = tx_ring->tx_buffer_info; + } + } + + /* reset BQL for queue */ + if (!ring_is_xdp(tx_ring)) + netdev_tx_reset_queue(txring_txq(tx_ring)); + +#ifdef HAVE_AF_XDP_ZC_SUPPORT +out: +#endif + + /* reset next_to_use and next_to_clean */ + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; +} + +/** + * ixgbe_clean_all_rx_rings - Free Rx Buffers for all queues + * @adapter: board private structure + **/ +static void ixgbe_clean_all_rx_rings(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_clean_rx_ring(adapter->rx_ring[i]); +} + +/** + * ixgbe_clean_all_tx_rings - Free Tx Buffers for all queues + * @adapter: board private structure + **/ +static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) + ixgbe_clean_tx_ring(adapter->tx_ring[i]); + for (i = 0; i < adapter->num_xdp_queues; i++) + ixgbe_clean_tx_ring(adapter->xdp_ring[i]); +} + +static void ixgbe_fdir_filter_exit(struct ixgbe_adapter *adapter) +{ + struct hlist_node *node2; + struct ixgbe_fdir_filter *filter; + + spin_lock(&adapter->fdir_perfect_lock); + + hlist_for_each_entry_safe(filter, node2, + &adapter->fdir_filter_list, fdir_node) { + hlist_del(&filter->fdir_node); + kfree(filter); + } + adapter->fdir_filter_count = 0; + + spin_unlock(&adapter->fdir_perfect_lock); +} + +void ixgbe_down(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + int i; + + /* signal that we are down to the interrupt handler */ + if (test_and_set_bit(__IXGBE_DOWN, adapter->state)) + return; /* do nothing if already down */ + + /* Shut off incoming Tx traffic */ + netif_tx_stop_all_queues(netdev); + + /* call carrier off first to avoid false dev_watchdog timeouts */ + netif_carrier_off(netdev); + netif_tx_disable(netdev); + + + /* Disable Rx */ + ixgbe_disable_rx_queue(adapter); + + /* synchronize_rcu() needed for pending XDP buffers to drain */ + if (adapter->xdp_ring[0]) + synchronize_rcu(); + + ixgbe_irq_disable(adapter); + + ixgbe_napi_disable_all(adapter); + + adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT); + clear_bit(__IXGBE_RESET_REQUESTED, adapter->state); + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; + + timer_delete_sync(&adapter->service_timer); + + if (adapter->num_vfs) { + /* Clear EITR Select mapping */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0); + + /* Mark all the VFs as inactive */ + for (i = 0 ; i < adapter->num_vfs; i++) + adapter->vfinfo[i].clear_to_send = 0; + + /* update setting rx tx for all active vfs */ + ixgbe_set_all_vfs(adapter); + } + + /* disable transmits in the hardware now that interrupts are off */ + ixgbe_disable_tx_queue(adapter); + +#ifdef HAVE_PCI_ERS + if (!pci_channel_offline(adapter->pdev)) +#endif + ixgbe_reset(adapter); + + /* power down the optics for 82599 SFP+ fiber */ + if (hw->mac.ops.disable_tx_laser) + hw->mac.ops.disable_tx_laser(hw); + + ixgbe_clean_all_tx_rings(adapter); + ixgbe_clean_all_rx_rings(adapter); + + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_disable_link_status_events(adapter); +} + +/** + * ixgbe_set_eee_capable - helper function to determine EEE support on X550 + * @adapter: board private structure to initialize + **/ +static inline void ixgbe_set_eee_capable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + case IXGBE_DEV_ID_E610_BACKPLANE: + case IXGBE_DEV_ID_E610_SFP: + case IXGBE_DEV_ID_E610_10G_T: + case IXGBE_DEV_ID_E610_2_5G_T: + if (!hw->phy.eee_speeds_supported) + break; + adapter->flags2 |= IXGBE_FLAG2_EEE_CAPABLE; + if (!hw->phy.eee_speeds_advertised) + break; + adapter->eee_state = IXGBE_EEE_ENABLED; + break; + default: + adapter->flags2 &= ~IXGBE_FLAG2_EEE_CAPABLE; + adapter->eee_state = IXGBE_EEE_DISABLED; + break; + } +} + +#if IS_ENABLED(CONFIG_DCB) +static void ixgbe_init_dcb(struct ixgbe_adapter *adapter) +{ + struct ixgbe_dcb_tc_config *tc; + int j, bwg_pct; + + /* Configure DCB traffic classes */ + bwg_pct = 100 / adapter->dcb_cfg.num_tcs.pg_tcs; + for (j = 0; j < adapter->dcb_cfg.num_tcs.pg_tcs; j++) { + tc = &adapter->dcb_cfg.tc_config[j]; + tc->path[IXGBE_DCB_TX_CONFIG].bwg_id = 0; + tc->path[IXGBE_DCB_TX_CONFIG].bwg_percent = bwg_pct; + tc->path[IXGBE_DCB_RX_CONFIG].bwg_id = 0; + tc->path[IXGBE_DCB_RX_CONFIG].bwg_percent = bwg_pct; + tc->pfc = ixgbe_dcb_pfc_disabled; + } + + /* reset back to TC 0 */ + tc = &adapter->dcb_cfg.tc_config[0]; + + /* total of all TCs bandwidth needs to be 100 */ + bwg_pct += 100 % adapter->dcb_cfg.num_tcs.pg_tcs; + tc->path[IXGBE_DCB_TX_CONFIG].bwg_percent = bwg_pct; + tc->path[IXGBE_DCB_RX_CONFIG].bwg_percent = bwg_pct; + + /* Initialize default user to priority mapping, UPx->TC0 */ + tc->path[IXGBE_DCB_TX_CONFIG].up_to_tc_bitmap = 0xFF; + tc->path[IXGBE_DCB_RX_CONFIG].up_to_tc_bitmap = 0xFF; + + adapter->dcb_cfg.bw_percentage[IXGBE_DCB_TX_CONFIG][0] = 100; + adapter->dcb_cfg.bw_percentage[IXGBE_DCB_RX_CONFIG][0] = 100; + adapter->dcb_cfg.rx_pba_cfg = ixgbe_dcb_pba_equal; + adapter->dcb_cfg.pfc_mode_enable = false; + adapter->dcb_cfg.round_robin_enable = false; + adapter->dcb_set_bitmap = 0x00; + if (adapter->flags & IXGBE_FLAG_DCB_CAPABLE) + adapter->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE; + memcpy(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, + sizeof(adapter->temp_dcb_cfg)); +} +#endif /*CONFIG_DCB*/ + +/** + * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter) + * @adapter: board private structure to initialize + * + * ixgbe_sw_init initializes the Adapter private data structure. + * Fields are initialized based on PCI device information and + * OS network device settings (MTU size). + **/ +#ifdef HAVE_CONFIG_HOTPLUG +static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) +#else +static int ixgbe_sw_init(struct ixgbe_adapter *adapter) +#endif +{ + struct ixgbe_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + int err; + unsigned int fdir; + u32 fwsm; +#ifdef HAVE_TC_SETUP_CLSU32 + int i; +#endif + + /* PCI config space info */ + + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); + if (hw->revision_id == IXGBE_FAILED_READ_CFG_BYTE && + ixgbe_check_cfg_remove(hw, pdev)) { + e_err(probe, "read of revision id failed\n"); + err = -ENODEV; + goto out; + } + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_device_id = pdev->subsystem_device; + + err = ixgbe_init_shared_code(hw); + if (err) { + e_err(probe, "init_shared_code failed: %d\n", err); + goto out; + } + + ixgbe_set_ethtool_ops(adapter->netdev); + +#ifdef HAVE_TC_SETUP_CLSU32 + /* initialize static ixgbe jump table entries */ + adapter->jump_tables[0] = kzalloc(sizeof(*adapter->jump_tables[0]), + GFP_KERNEL); + if (!adapter->jump_tables[0]) + return -ENOMEM; + adapter->jump_tables[0]->mat = ixgbe_ipv4_fields; + + for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) + adapter->jump_tables[i] = NULL; +#endif /* HAVE_TC_SETUP_CLSU32 */ + adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) * + hw->mac.num_rar_entries, + GFP_KERNEL); + if (!adapter->mac_table) { + err = IXGBE_ERR_OUT_OF_MEM; + e_err(probe, "mac_table allocation failed: %d\n", err); + goto out; + } + + if (ixgbe_init_rss_key(adapter)) { + err = IXGBE_ERR_OUT_OF_MEM; + e_err(probe, "rss_key allocation failed: %d\n", err); + goto out; + } + + adapter->af_xdp_zc_qps = bitmap_zalloc(IXGBE_MAX_XDP_QS, GFP_KERNEL); + if (!adapter->af_xdp_zc_qps) + return -ENOMEM; + + /* Set common capability flags and settings */ +#if IS_ENABLED(CONFIG_DCA) + adapter->flags |= IXGBE_FLAG_DCA_CAPABLE; +#endif +#if IS_ENABLED(CONFIG_DCB) + adapter->flags |= IXGBE_FLAG_DCB_CAPABLE; + adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; +#endif +#if IS_ENABLED(CONFIG_FCOE) + adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; + adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; +#if IS_ENABLED(CONFIG_DCB) + /* Default traffic class to use for FCoE */ + adapter->fcoe.up = IXGBE_FCOE_DEFUP; + adapter->fcoe.up_set = IXGBE_FCOE_DEFUP; +#endif /* CONFIG_DCB */ +#endif /* CONFIG_FCOE */ + adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; + fdir = min_t(int, IXGBE_MAX_FDIR_INDICES, num_online_cpus()); + adapter->ring_feature[RING_F_FDIR].limit = fdir; + adapter->max_q_vectors = IXGBE_MAX_MSIX_Q_VECTORS_82599; + + /* Set MAC specific capability flags and exceptions */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + adapter->flags |= IXGBE_FLAGS_82598_INIT; + adapter->flags2 &= ~IXGBE_FLAG2_RSC_CAPABLE; + + if (hw->device_id == IXGBE_DEV_ID_82598AT) + adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE; + + adapter->max_q_vectors = IXGBE_MAX_MSIX_Q_VECTORS_82598; + adapter->ring_feature[RING_F_FDIR].limit = 0; +#if IS_ENABLED(CONFIG_FCOE) + adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE; +#if IS_ENABLED(CONFIG_DCB) + adapter->fcoe.up = 0; + adapter->fcoe.up_set = 0; +#endif /* IXGBE_DCB */ +#endif /* CONFIG_FCOE */ + break; + case ixgbe_mac_82599EB: + adapter->flags |= IXGBE_FLAGS_82599_INIT; + if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM) + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; +#ifndef IXGBE_NO_SMART_SPEED + hw->phy.smart_speed = ixgbe_smart_speed_on; +#else + hw->phy.smart_speed = ixgbe_smart_speed_off; +#endif + break; + case ixgbe_mac_X540: + adapter->flags |= IXGBE_FLAGS_X540_INIT; + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM); + if (fwsm & IXGBE_FWSM_TS_ENABLED) + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; + break; + case ixgbe_mac_X550EM_a: + adapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE; + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; + break; + default: + break; + } + fallthrough; + case ixgbe_mac_X550EM_x: + fallthrough; + case ixgbe_mac_E610: + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_X550EM_a); + if ((fwsm & IXGBE_FWSM_TS_ENABLED) && + ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; + adapter->flags2 &= ~IXGBE_FLAG2_FWLOG_CAPABLE; + hw->fwlog_support_ena = false; +#if IS_ENABLED(CONFIG_DCB) + adapter->flags &= ~IXGBE_FLAG_DCB_CAPABLE; +#endif +#if IS_ENABLED(CONFIG_FCOE) + adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE; +#if IS_ENABLED(CONFIG_DCB) + adapter->fcoe.up = 0; + adapter->fcoe.up_set = 0; +#endif /* CONFIG_DCB */ +#endif /* CONFIG_FCOE */ + if (ixgbe_is_mac_E6xx(hw->mac.type)) { + adapter->flags2 |= IXGBE_FLAG2_FWLOG_CAPABLE; + } + fallthrough; + case ixgbe_mac_X550: + if (hw->mac.type == ixgbe_mac_X550) + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; + ixgbe_set_eee_capable(adapter); + adapter->flags |= IXGBE_FLAGS_X550_INIT; +#if IS_ENABLED(CONFIG_DCA) + adapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE; +#endif /* CONFIG_DCA */ + fallthrough; + default: + break; + } + +#if IS_ENABLED(CONFIG_FCOE) + /* FCoE support exists, always init the FCoE lock */ + spin_lock_init(&adapter->fcoe.lock); +#endif /* CONFIG_FCOE */ + + /* n-tuple support exists, always init our spinlock */ + spin_lock_init(&adapter->fdir_perfect_lock); + +#if IS_ENABLED(CONFIG_DCB) + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + case ixgbe_mac_82599EB: + adapter->dcb_cfg.num_tcs.pg_tcs = 8; + adapter->dcb_cfg.num_tcs.pfc_tcs = 8; + break; + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_E610: + adapter->dcb_cfg.num_tcs.pg_tcs = 4; + adapter->dcb_cfg.num_tcs.pfc_tcs = 4; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + default: + adapter->dcb_cfg.num_tcs.pg_tcs = 1; + adapter->dcb_cfg.num_tcs.pfc_tcs = 1; + break; + } + ixgbe_init_dcb(adapter); + +#endif /* CONFIG_DCB */ + + if (hw->mac.type == ixgbe_mac_82599EB || + hw->mac.type == ixgbe_mac_X550 || + hw->mac.type == ixgbe_mac_X550EM_x || + hw->mac.type == ixgbe_mac_X550EM_a || + hw->mac.type == ixgbe_mac_X540 || + ixgbe_is_mac_E6xx(hw->mac.type)) + ixgbe_init_mbx_params_pf(hw); + + /* default flow control settings */ + hw->fc.requested_mode = ixgbe_fc_full; + hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */ + + adapter->last_lfc_mode = hw->fc.current_mode; + ixgbe_pbthresh_setup(adapter); + hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; + hw->fc.send_xon = true; + hw->fc.disable_fc_autoneg = false; + + /* set default ring sizes */ + adapter->tx_ring_count = IXGBE_DEFAULT_TXD; + adapter->rx_ring_count = IXGBE_DEFAULT_RXD; + + /* set default work limits */ + adapter->tx_work_limit = IXGBE_DEFAULT_TX_WORK; + + set_bit(__IXGBE_DOWN, adapter->state); + +#ifdef HAVE_XDP_SUPPORT + /* enable locking for XDP_TX if we have more CPUs than queues */ + if (nr_cpu_ids > IXGBE_MAX_XDP_QS) + static_branch_enable(&ixgbe_xdp_locking_key); +#endif +out: + return err; +} + +/** + * ixgbe_setup_tx_resources - allocate Tx resources (Descriptors) + * @tx_ring: tx descriptor ring (for a specific queue) to setup + * + * Return 0 on success, negative on failure + **/ +int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) +{ + struct device *dev = tx_ring->dev; + int orig_node = dev_to_node(dev); + int node = -1; + int size; + + size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; + + if (tx_ring->q_vector) + node = tx_ring->q_vector->node; + + tx_ring->tx_buffer_info = vmalloc_node(size, node); + if (!tx_ring->tx_buffer_info) + tx_ring->tx_buffer_info = vmalloc(size); + if (!tx_ring->tx_buffer_info) + goto err; + + /* round up to nearest 4K */ + tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); + tx_ring->size = ALIGN(tx_ring->size, 4096); + + set_dev_node(dev, node); + tx_ring->desc = dma_alloc_coherent(dev, + tx_ring->size, + &tx_ring->dma, + GFP_KERNEL); + set_dev_node(dev, orig_node); + if (!tx_ring->desc) + tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size, + &tx_ring->dma, GFP_KERNEL); + if (!tx_ring->desc) + goto err; + + return 0; + +err: + vfree(tx_ring->tx_buffer_info); + tx_ring->tx_buffer_info = NULL; + dev_err(dev, "Unable to allocate memory for the Tx descriptor ring\n"); + return -ENOMEM; +} + +/** + * ixgbe_setup_all_tx_resources - allocate all queues Tx resources + * @adapter: board private structure + * + * If this function returns with an error, then it's possible one or + * more of the rings is populated (while the rest are not). It is the + * callers duty to clean those orphaned rings. + * + * Return 0 on success, negative on failure + **/ +static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) +{ + int i, j = 0, err = 0; + + for (i = 0; i < adapter->num_tx_queues; i++) { + + + err = ixgbe_setup_tx_resources(adapter->tx_ring[i]); + if (!err) + continue; + + e_err(probe, "Allocation for Tx Queue %u failed\n", i); + goto err_setup_tx; + } + for (j = 0; j < adapter->num_xdp_queues; j++) { + err = ixgbe_setup_tx_resources(adapter->xdp_ring[j]); + if (!err) + continue; + + e_err(probe, "Allocation for Tx Queue %u failed\n", j); + goto err_setup_tx; + } + + return 0; +err_setup_tx: + /* rewind the index freeing the rings as we go */ + while (j--) + ixgbe_free_tx_resources(adapter->xdp_ring[j]); + while (i--) + ixgbe_free_tx_resources(adapter->tx_ring[i]); + return err; +} + +#ifdef HAVE_XDP_BUFF_RXQ +static int ixgbe_rx_napi_id(struct ixgbe_ring *rx_ring) +{ + struct ixgbe_q_vector *q_vector = rx_ring->q_vector; + + return q_vector ? q_vector->napi.napi_id : 0; +} +#endif + +/** + * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors) + * @adapter: board private structure + * @rx_ring: rx descriptor ring (for a specific queue) to setup + * + * Returns 0 on success, negative on failure + **/ +int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) +{ + struct device *dev = rx_ring->dev; + int orig_node = dev_to_node(dev); + int node = -1; + int size; +#ifdef HAVE_XDP_BUFF_RXQ +#ifdef HAVE_XDP_FRAME_STRUCT +#ifndef HAVE_AF_XDP_ZC_SUPPORT + int err; +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif /* HAVE_XDP_FRAME_STRUCT */ +#endif /* HAVE_XDP_BUFF_RXQ */ + + size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; + + if (rx_ring->q_vector) + node = rx_ring->q_vector->node; + + rx_ring->rx_buffer_info = vmalloc_node(size, node); + if (!rx_ring->rx_buffer_info) + rx_ring->rx_buffer_info = vmalloc(size); + if (!rx_ring->rx_buffer_info) + goto err; + + /* Round up to nearest 4K */ + rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); + rx_ring->size = ALIGN(rx_ring->size, 4096); + + set_dev_node(dev, node); + rx_ring->desc = dma_alloc_coherent(dev, + rx_ring->size, + &rx_ring->dma, + GFP_KERNEL); + set_dev_node(dev, orig_node); + if (!rx_ring->desc) + rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size, + &rx_ring->dma, GFP_KERNEL); + if (!rx_ring->desc) + goto err; + +#ifdef HAVE_XDP_BUFF_RXQ + /* XDP RX-queue info */ + if (xdp_rxq_info_reg(&rx_ring->xdp_rxq, adapter->netdev, + rx_ring->queue_index, + ixgbe_rx_napi_id(rx_ring)) < 0) + goto err; + +#ifndef HAVE_AF_XDP_ZC_SUPPORT +#ifdef HAVE_XDP_FRAME_STRUCT + err = xdp_rxq_info_reg_mem_model(&rx_ring->xdp_rxq, + MEM_TYPE_PAGE_SHARED, NULL); + if (err) { + xdp_rxq_info_unreg(&rx_ring->xdp_rxq); + goto err; + } +#endif /* HAVE_XDP_FRAME_STRUCT */ +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif /* HAVE_XDP_BUFF_RXQ */ + + rx_ring->xdp_prog = adapter->xdp_prog; + + return 0; +err: + vfree(rx_ring->rx_buffer_info); + rx_ring->rx_buffer_info = NULL; + dev_err(dev, "Unable to allocate memory for the Rx descriptor ring\n"); + return -ENOMEM; +} + +/** + * ixgbe_setup_all_rx_resources - allocate all queues Rx resources + * @adapter: board private structure + * + * If this function returns with an error, then it's possible one or + * more of the rings is populated (while the rest are not). It is the + * callers duty to clean those orphaned rings. + * + * Return 0 on success, negative on failure + **/ +static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) +{ + int i, err = 0; + + for (i = 0; i < adapter->num_rx_queues; i++) { + err = ixgbe_setup_rx_resources(adapter, adapter->rx_ring[i]); + if (!err) + continue; + + e_err(probe, "Allocation for Rx Queue %u failed\n", i); + goto err_setup_rx; + } + +#if IS_ENABLED(CONFIG_FCOE) + err = ixgbe_setup_fcoe_ddp_resources(adapter); + if (!err) +#endif + return 0; +err_setup_rx: + /* rewind the index freeing the rings as we go */ + while (i--) + ixgbe_free_rx_resources(adapter->rx_ring[i]); + return err; +} + +/** + * ixgbe_free_tx_resources - Free Tx Resources per Queue + * @tx_ring: Tx descriptor ring for a specific queue + * + * Free all transmit software resources + **/ +void ixgbe_free_tx_resources(struct ixgbe_ring *tx_ring) +{ + ixgbe_clean_tx_ring(tx_ring); + + vfree(tx_ring->tx_buffer_info); + tx_ring->tx_buffer_info = NULL; + + /* if not set, then don't free */ + if (!tx_ring->desc) + return; + + dma_free_coherent(tx_ring->dev, tx_ring->size, + tx_ring->desc, tx_ring->dma); + tx_ring->desc = NULL; +} + +/** + * ixgbe_free_all_tx_resources - Free Tx Resources for All Queues + * @adapter: board private structure + * + * Free all transmit software resources + **/ +static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) + ixgbe_free_tx_resources(adapter->tx_ring[i]); + for (i = 0; i < adapter->num_xdp_queues; i++) + if (adapter->xdp_ring[i]->desc) + ixgbe_free_tx_resources(adapter->xdp_ring[i]); +} + +/** + * ixgbe_free_rx_resources - Free Rx Resources + * @rx_ring: ring to clean the resources from + * + * Free all receive software resources + **/ +void ixgbe_free_rx_resources(struct ixgbe_ring *rx_ring) +{ + ixgbe_clean_rx_ring(rx_ring); + + rx_ring->xdp_prog = NULL; +#ifdef HAVE_XDP_BUFF_RXQ + xdp_rxq_info_unreg(&rx_ring->xdp_rxq); +#endif + vfree(rx_ring->rx_buffer_info); + rx_ring->rx_buffer_info = NULL; + + /* if not set, then don't free */ + if (!rx_ring->desc) + return; + + dma_free_coherent(rx_ring->dev, rx_ring->size, + rx_ring->desc, rx_ring->dma); + + rx_ring->desc = NULL; +} + +/** + * ixgbe_free_all_rx_resources - Free Rx Resources for All Queues + * @adapter: board private structure + * + * Free all receive software resources + **/ +static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) +{ + int i; + +#if IS_ENABLED(CONFIG_FCOE) + ixgbe_free_fcoe_ddp_resources(adapter); +#endif + + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_free_rx_resources(adapter->rx_ring[i]); +} + +/** + * ixgbe_change_mtu - Change the Maximum Transfer Unit + * @netdev: network interface device structure + * @new_mtu: new value for maximum frame size + * + * Returns 0 on success, negative on failure + **/ +static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#ifndef HAVE_NETDEVICE_MIN_MAX_MTU + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; +#endif + + if (adapter->xdp_prog) { + int new_frame_size = new_mtu + IXGBE_PKT_HDR_PAD; + int i; + + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + + if (new_frame_size > ixgbe_rx_bufsz(ring)) { + e_warn(probe, "Requested MTU size is not supported with XDP\n"); + return -EINVAL; + } + } + } + +#ifndef HAVE_NETDEVICE_MIN_MAX_MTU + /* MTU < 68 is an error and causes problems on some kernels */ + if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) + return -EINVAL; + +#endif + /* + * For 82599EB we cannot allow legacy VFs to enable their receive + * paths when MTU greater than 1500 is configured. So display a + * warning that legacy VFs will be disabled. + */ + if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && + (adapter->hw.mac.type == ixgbe_mac_82599EB) && +#ifndef HAVE_NETDEVICE_MIN_MAX_MTU + (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN))) +#else + (new_mtu > ETH_DATA_LEN)) +#endif + e_warn(probe, "Setting MTU > 1500 will disable legacy VFs\n"); + + e_info(probe, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); + + /* must set new MTU before calling down or up */ + netdev->mtu = new_mtu; + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + + return 0; +} + +/** + * ixgbe_open - Called when a network interface is made active + * @netdev: network interface device structure + * + * Returns 0 on success, negative value on failure + * + * The open entry point is called when a network interface is made + * active by the system (IFF_UP). At this point all resources needed + * for transmit and receive operations are allocated, the interrupt + * handler is registered with the OS, the watchdog timer is started, + * and the stack is notified that the interface is ready. + **/ +int ixgbe_open(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int err; + + /* disallow open during test */ + if (test_bit(__IXGBE_TESTING, adapter->state)) + return -EBUSY; + + netif_carrier_off(netdev); + + /* allocate transmit descriptors */ + err = ixgbe_setup_all_tx_resources(adapter); + if (err) + goto err_setup_tx; + + /* allocate receive descriptors */ + err = ixgbe_setup_all_rx_resources(adapter); + if (err) + goto err_setup_rx; + + ixgbe_configure(adapter); + + err = ixgbe_request_irq(adapter); + if (err) + goto err_req_irq; + + /* Notify the stack of the actual queue counts. */ + err = netif_set_real_num_tx_queues(netdev, + adapter->num_rx_pools > 1 ? 1 : + adapter->num_tx_queues); + if (err) + goto err_set_queues; + + err = netif_set_real_num_rx_queues(netdev, + adapter->num_rx_pools > 1 ? 1 : + adapter->num_rx_queues); + if (err) + goto err_set_queues; + +#ifdef HAVE_PTP_1588_CLOCK + if (!ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_ptp_init(adapter); +#endif /* HAVE_PTP_1588_CLOCK*/ + + ixgbe_up_complete(adapter); + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) && defined(HAVE_UDP_TUNNEL_NIC_INFO) + udp_tunnel_nic_reset_ntf(netdev); +#else +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) + ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK); +#endif +#ifdef HAVE_UDP_ENC_RX_OFFLOAD + udp_tunnel_get_rx_info(netdev); +#elif defined(HAVE_VXLAN_RX_OFFLOAD) + vxlan_get_rx_port(netdev); +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ +#endif /* HAVE_UDP_ENC_RX_OFFLOAD && HAVE_UDP_TUNNEL_NIC_INFO */ + if (!ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + goto out; + + if (ixgbe_update_link_info(&adapter->hw)) + e_dev_warn("ixgbe_update_link_info failed\n"); + + ixgbe_check_link_cfg_err(adapter, + adapter->hw.link.link_info.link_cfg_err); + + if (ixgbe_non_sfp_link_config(&adapter->hw)) + e_dev_warn("link setup failed\n"); +out: + return IXGBE_SUCCESS; + +err_set_queues: + ixgbe_free_irq(adapter); +err_req_irq: + ixgbe_free_all_rx_resources(adapter); + if (!adapter->wol) + ixgbe_set_phy_power(&adapter->hw, false); +err_setup_rx: + ixgbe_free_all_tx_resources(adapter); +err_setup_tx: + ixgbe_reset(adapter); + + return err; +} + +/** + * ixgbe_close_suspend - actions necessary to both suspend and close flows + * @adapter: the private adapter struct + * + * This function should contain the necessary work common to both suspending + * and closing of the device. + */ +static void ixgbe_close_suspend(struct ixgbe_adapter *adapter) +{ +#ifdef HAVE_PTP_1588_CLOCK + if (!ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_ptp_suspend(adapter); +#endif + + if (adapter->hw.phy.ops.enter_lplu) { + adapter->hw.phy.reset_disable = true; + ixgbe_down(adapter); + ixgbe_enter_lplu(&adapter->hw); + adapter->hw.phy.reset_disable = false; + } else { + ixgbe_down(adapter); + } + ixgbe_free_irq(adapter); + + ixgbe_free_all_rx_resources(adapter); + ixgbe_free_all_tx_resources(adapter); +} + +/** + * ixgbe_close - Disables a network interface + * @netdev: network interface device structure + * + * Returns 0, this is not allowed to fail + * + * The close entry point is called when an interface is de-activated + * by the OS. The hardware is still under the drivers control, but + * needs to be disabled. A global MAC reset is issued to stop the + * hardware, and all transmit and receive resources are freed. + **/ +int ixgbe_close(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +#ifdef HAVE_PTP_1588_CLOCK + if (!ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_ptp_stop(adapter); +#endif + + if (netif_device_present(netdev)) + ixgbe_close_suspend(adapter); + + ixgbe_fdir_filter_exit(adapter); + + ixgbe_release_hw_control(adapter); + + return 0; +} + +#ifdef CONFIG_PM +/** + * ixgbe_resume - Resume the network device from a suspended state + * @dev: Device structure (or PCI device structure if using legacy PM support) + * + * This function resumes the network device from a suspended state. It restores + * the PCI device state, reinitializes the device, and reattaches the network + * interface if it was running before suspension. The function handles both + * legacy and non-legacy power management support. + * + * Return: 0 on success, or a negative error code if the device cannot be enabled. + */ +#ifndef USE_LEGACY_PM_SUPPORT +static int ixgbe_resume(struct device *dev) +#else +static int ixgbe_resume(struct pci_dev *pdev) +#endif /* USE_LEGACY_PM_SUPPORT */ +{ + struct ixgbe_adapter *adapter; + struct net_device *netdev; + int err; +#ifndef USE_LEGACY_PM_SUPPORT + struct pci_dev *pdev = to_pci_dev(dev); +#endif + + adapter = pci_get_drvdata(pdev); + netdev = adapter->netdev; + adapter->hw.hw_addr = adapter->io_addr; + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + /* + * pci_restore_state clears dev->state_saved so call + * pci_save_state to restore it. + */ + pci_save_state(pdev); + + err = pci_enable_device_mem(pdev); + if (err) { + e_dev_err("Cannot enable PCI device from suspend\n"); + return err; + } + smp_mb__before_atomic(); + clear_bit(__IXGBE_DISABLED, adapter->state); + pci_set_master(pdev); + + pci_wake_from_d3(pdev, false); + + ixgbe_reset(adapter); + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); + + rtnl_lock(); + + err = ixgbe_init_interrupt_scheme(adapter); + if (!err && netif_running(netdev)) + err = ixgbe_open(netdev); + + + if (!err) + netif_device_attach(netdev); + + rtnl_unlock(); + + return err; +} + +#ifndef USE_LEGACY_PM_SUPPORT +/** + * ixgbe_freeze - Quiesce the device (disable IRQs and DMA) + * @dev: The port's network device + * + * This function quiesces the ixgbe network adapter by detaching the network + * device and disabling interrupts and DMA operations. It stops the network + * interface if it is running and handles specific hardware configurations, + * such as low power link up (LPLU) mode, if applicable. The function ensures + * that the device is in a safe state for operations like power management. + * + * Return: Always returns 0. + */ +static int ixgbe_freeze(struct device *dev) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(to_pci_dev(dev)); + struct net_device *netdev = adapter->netdev; + bool lplu_enabled = !!adapter->hw.phy.ops.enter_lplu; + + rtnl_lock(); + netif_device_detach(netdev); + + if (netif_running(netdev)) { + if (lplu_enabled) { + adapter->hw.phy.reset_disable = true; + ixgbe_down(adapter); + adapter->hw.phy.reset_disable = false; + } else { + ixgbe_down(adapter); + } + ixgbe_free_irq(adapter); + } + + ixgbe_reset_interrupt_capability(adapter); + rtnl_unlock(); + + return 0; +} + +/** + * ixgbe_thaw - Un-quiesce the device and resume operations + * @dev: The port's net device structure + * + * This function resumes operations for the ixgbe network adapter after it + * has been quiesced. It sets up interrupt capabilities and, if the network + * interface is running, requests IRQs and brings the device up. The function + * also handles specific hardware configurations, such as low power link up + * (LPLU) mode, if applicable. Finally, it reattaches the network device to + * the system. + * + * Return: 0 on success, or a negative error code if IRQ request fails. + */ +static int ixgbe_thaw(struct device *dev) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(to_pci_dev(dev)); + struct net_device *netdev = adapter->netdev; + bool lplu_enabled = !!adapter->hw.phy.ops.enter_lplu; + + ixgbe_set_interrupt_capability(adapter); + + if (netif_running(netdev)) { + u32 err = ixgbe_request_irq(adapter); + if (err) + return err; + + if (lplu_enabled) { + adapter->hw.phy.reset_disable = true; + ixgbe_up(adapter); + adapter->hw.phy.reset_disable = false; + } else { + ixgbe_up(adapter); + } + } + + netif_device_attach(netdev); + + return 0; +} +#endif /* USE_LEGACY_PM_SUPPORT */ +#endif /* CONFIG_PM */ + +/* + * __ixgbe_shutdown is not used when power management + * is disabled on older kernels (<2.6.12). causes a compile + * warning/error, because it is defined and not used. + */ +#if defined(CONFIG_PM) || !defined(USE_REBOOT_NOTIFIER) +static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + u32 ctrl; + u32 wufc = adapter->wol; +#ifdef CONFIG_PM + int retval = 0; +#endif + + rtnl_lock(); + netif_device_detach(netdev); + + if (netif_running(netdev)) + ixgbe_close_suspend(adapter); + + ixgbe_clear_interrupt_scheme(adapter); + rtnl_unlock(); + +#ifdef CONFIG_PM + retval = pci_save_state(pdev); + if (retval) + return retval; + +#endif + + /* this won't stop link of managebility or WoL is enabled */ + if (hw->mac.type == ixgbe_mac_82599EB) + ixgbe_stop_mac_link_on_d3_82599(hw); + + if (wufc) { + u32 fctrl; + + ixgbe_set_rx_mode(netdev); + + /* enable the optics for 82599 SFP+ fiber as we can WoL */ + if (hw->mac.ops.enable_tx_laser) + hw->mac.ops.enable_tx_laser(hw); + + /* enable the reception of multicast packets */ + fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + fctrl |= IXGBE_FCTRL_MPE; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + ctrl |= IXGBE_CTRL_GIO_DIS; + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + + IXGBE_WRITE_REG(hw, IXGBE_WUFC, wufc); + } else { + IXGBE_WRITE_REG(hw, IXGBE_WUC, 0); + IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); + } + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + pci_wake_from_d3(pdev, false); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + pci_wake_from_d3(pdev, !!wufc); + break; + default: + break; + } + + *enable_wake = !!wufc; + if (!*enable_wake) + ixgbe_set_phy_power(hw, false); + + ixgbe_release_hw_control(adapter); + + if (!test_and_set_bit(__IXGBE_DISABLED, adapter->state)) + pci_disable_device(pdev); + + return 0; +} +#endif /* defined(CONFIG_PM) || !defined(USE_REBOOT_NOTIFIER) */ + +#ifdef CONFIG_PM +/** + * ixgbe_suspend - Suspend the ixgbe network device + * @dev: Device structure pointer (for non-legacy PM support) + * @pdev: PCI device structure pointer (for legacy PM support) + * @state: Power management state (unused in legacy PM support) + * + * This function suspends the ixgbe network adapter, preparing it for low-power + * states. It calls `__ixgbe_shutdown` to handle device-specific shutdown tasks + * and checks if wake-on-LAN is enabled. If WoL is enabled, the device is prepared + * for sleep; otherwise, it is set to a low-power state. + * + * Return: 0 on success, or a negative error code on failure. + */ +#ifndef USE_LEGACY_PM_SUPPORT +static int ixgbe_suspend(struct device *dev) +#else +static int ixgbe_suspend(struct pci_dev *pdev, + pm_message_t __always_unused state) +#endif /* USE_LEGACY_PM_SUPPORT */ +{ + int retval; + bool wake; +#ifndef USE_LEGACY_PM_SUPPORT + struct pci_dev *pdev = to_pci_dev(dev); +#endif + + retval = __ixgbe_shutdown(pdev, &wake); + if (retval) + return retval; + + if (wake) { + pci_prepare_to_sleep(pdev); + } else { + pci_wake_from_d3(pdev, false); + pci_set_power_state(pdev, PCI_D3hot); + } + + return 0; +} +#endif /* CONFIG_PM */ + +#ifndef USE_REBOOT_NOTIFIER +/** + * ixgbe_shutdown - Perform shutdown operations for the ixgbe device + * @pdev: PCI device structure pointer + * + * This function handles the shutdown process for the ixgbe network adapter. + * It calls the internal `__ixgbe_shutdown` function to manage device-specific + * shutdown tasks and determines if the device should be configured for wake-on-LAN. + * If the system is powering off, it sets the device to a low-power state. + */ +static void ixgbe_shutdown(struct pci_dev *pdev) +{ + bool wake; + + __ixgbe_shutdown(pdev, &wake); + + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, wake); + pci_set_power_state(pdev, PCI_D3hot); + } +} +#endif /* USE_REBOOT_NOTIFIER */ + +#ifdef HAVE_NDO_GET_STATS64 +static void ixgbe_get_ring_stats64(struct rtnl_link_stats64 *stats, + struct ixgbe_ring *ring) +{ + u64 bytes, packets; + unsigned int start; + + if (ring) { + do { + start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->tx_packets += packets; + stats->tx_bytes += bytes; + } +} + +/** + * ixgbe_get_stats64 - Get System Network Statistics + * @netdev: network interface device structure + * @stats: storage space for 64bit statistics + * + * Returns 64bit statistics, for use in the ndo_get_stats64 callback. This + * function replaces ixgbe_get_stats for kernels which support it. + */ +#ifdef HAVE_VOID_NDO_GET_STATS64 +static void ixgbe_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +#else +static struct rtnl_link_stats64 * +ixgbe_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i; + + rcu_read_lock(); + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = READ_ONCE(adapter->rx_ring[i]); + u64 bytes, packets; + unsigned int start; + + if (ring) { + do { + start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } + } + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *ring = READ_ONCE(adapter->tx_ring[i]); + + ixgbe_get_ring_stats64(stats, ring); + } + + for (i = 0; i < adapter->num_xdp_queues; i++) { + struct ixgbe_ring *ring = READ_ONCE(adapter->xdp_ring[i]); + + ixgbe_get_ring_stats64(stats, ring); + } + rcu_read_unlock(); + + /* following stats updated by ixgbe_watchdog_task() */ + stats->multicast = netdev->stats.multicast; + stats->rx_errors = netdev->stats.rx_errors; + stats->rx_length_errors = netdev->stats.rx_length_errors; + stats->rx_crc_errors = netdev->stats.rx_crc_errors; + stats->rx_missed_errors = netdev->stats.rx_missed_errors; +#ifndef HAVE_VOID_NDO_GET_STATS64 + + return stats; +#endif +} +#else /* !HAVE_NDO_GET_STATS64 */ +/** + * ixgbe_get_stats - Get System Network Statistics + * @netdev: network interface device structure + * + * Returns the address of the device statistics structure. + * The statistics are actually updated from the timer callback. + **/ +static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + /* update the stats data */ + ixgbe_update_stats(adapter); + +#ifdef HAVE_NETDEV_STATS_IN_NETDEV + /* only return the current stats */ + return &netdev->stats; +#else + /* only return the current stats */ + return &adapter->net_stats; +#endif /* HAVE_NETDEV_STATS_IN_NETDEV */ +} +#endif /* HAVE_NDO_GET_STATS64 */ + +#ifdef HAVE_VF_STATS +/** + * ixgbe_ndo_get_vf_stats - Retrieve statistics for a virtual function (VF) + * @netdev: Network device structure + * @vf: VF index + * @vf_stats: Pointer to ifla_vf_stats structure to be filled with VF statistics + * + * This function retrieves the statistics for a specified virtual function (VF) + * on the network device. It populates the `ifla_vf_stats` structure with + * details such as the VF's received and transmitted packets and bytes, as well + * as multicast packet count. + * + * Return: 0 on success, or -EINVAL if the VF index is out of range. + */ +static int ixgbe_ndo_get_vf_stats(struct net_device *netdev, int vf, + struct ifla_vf_stats *vf_stats) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + vf_stats->rx_packets = adapter->vfinfo[vf].vfstats.gprc; + vf_stats->rx_bytes = adapter->vfinfo[vf].vfstats.gorc; + vf_stats->tx_packets = adapter->vfinfo[vf].vfstats.gptc; + vf_stats->tx_bytes = adapter->vfinfo[vf].vfstats.gotc; + vf_stats->multicast = adapter->vfinfo[vf].vfstats.mprc; + + return 0; +} +#endif /* HAVE_VF_STATS */ + +/** + * ixgbe_update_stats - Update the board statistics counters. + * @adapter: board private structure + **/ +void ixgbe_update_stats(struct ixgbe_adapter *adapter) +{ +#ifdef HAVE_NETDEV_STATS_IN_NETDEV + struct net_device_stats *net_stats = &adapter->netdev->stats; +#else + struct net_device_stats *net_stats = &adapter->net_stats; +#endif /* HAVE_NETDEV_STATS_IN_NETDEV */ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_hw_stats *hwstats = &adapter->stats; + u64 total_mpc = 0; + u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; + u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0; + u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0; + u64 alloc_rx_page = 0; + u64 bytes = 0, packets = 0, hw_csum_rx_error = 0; + + if (test_bit(__IXGBE_DOWN, adapter->state) || + test_bit(__IXGBE_RESETTING, adapter->state)) + return; + + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + u64 rsc_count = 0; + u64 rsc_flush = 0; + for (i = 0; i < adapter->num_rx_queues; i++) { + rsc_count += adapter->rx_ring[i]->rx_stats.rsc_count; + rsc_flush += adapter->rx_ring[i]->rx_stats.rsc_flush; + } + adapter->rsc_total_count = rsc_count; + adapter->rsc_total_flush = rsc_flush; + } + + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *rx_ring = adapter->rx_ring[i]; + non_eop_descs += rx_ring->rx_stats.non_eop_descs; + alloc_rx_page += rx_ring->rx_stats.alloc_rx_page; + alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed; + alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed; + hw_csum_rx_error += rx_ring->rx_stats.csum_err; + bytes += rx_ring->stats.bytes; + packets += rx_ring->stats.packets; + + } + adapter->non_eop_descs = non_eop_descs; + adapter->alloc_rx_page = alloc_rx_page; + adapter->alloc_rx_page_failed = alloc_rx_page_failed; + adapter->alloc_rx_buff_failed = alloc_rx_buff_failed; + adapter->hw_csum_rx_error = hw_csum_rx_error; + net_stats->rx_bytes = bytes; + net_stats->rx_packets = packets; + + bytes = 0; + packets = 0; + /* gather some stats to the adapter struct that are per queue */ + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + restart_queue += tx_ring->tx_stats.restart_queue; + tx_busy += tx_ring->tx_stats.tx_busy; + bytes += tx_ring->stats.bytes; + packets += tx_ring->stats.packets; + } + for (i = 0; i < adapter->num_xdp_queues; i++) { + struct ixgbe_ring *xdp_ring = adapter->xdp_ring[i]; + + restart_queue += xdp_ring->tx_stats.restart_queue; + tx_busy += xdp_ring->tx_stats.tx_busy; + bytes += xdp_ring->stats.bytes; + packets += xdp_ring->stats.packets; + } + adapter->restart_queue = restart_queue; + adapter->tx_busy = tx_busy; + net_stats->tx_bytes = bytes; + net_stats->tx_packets = packets; + + hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); + + /* 8 register reads */ + for (i = 0; i < 8; i++) { + /* for packet buffers not used, the register should read 0 */ + mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i)); + missed_rx += mpc; + hwstats->mpc[i] += mpc; + total_mpc += hwstats->mpc[i]; + hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); + hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + hwstats->rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); + hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + break; + default: + break; + } + } + + /*16 register reads */ + for (i = 0; i < 16; i++) { + hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); + hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); + if (hw->mac.type == ixgbe_mac_82599EB || + hw->mac.type == ixgbe_mac_X550 || + hw->mac.type == ixgbe_mac_X550EM_x || + hw->mac.type == ixgbe_mac_X550EM_a || + hw->mac.type == ixgbe_mac_X540 || + ixgbe_is_mac_E6xx(hw->mac.type)) { + hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); /* to clear */ + hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); + IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); /* to clear */ + } + } + + hwstats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); + /* work around hardware counting issue */ + hwstats->gprc -= missed_rx; + + ixgbe_update_xoff_received(adapter); + + /* 82598 hardware only has a 32 bit counter in the high register */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); + break; + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + /* OS2BMC stats are X540 only*/ + hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC); + hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC); + hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC); + hwstats->b2ogprc += IXGBE_READ_REG(hw, IXGBE_B2OGPRC); + fallthrough; + case ixgbe_mac_82599EB: + for (i = 0; i < 16; i++) + adapter->hw_rx_no_dma_resources += + IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); + IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */ + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); + IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */ + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL); + IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); +#ifdef HAVE_TX_MQ + hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); + hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); +#endif /* HAVE_TX_MQ */ +#if IS_ENABLED(CONFIG_FCOE) + hwstats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); + hwstats->fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST); + hwstats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); + hwstats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); + hwstats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); + hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); + hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); + /* Add up per cpu counters for total ddp alloc fail */ + if (adapter->fcoe.ddp_pool) { + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + struct ixgbe_fcoe_ddp_pool *ddp_pool; + unsigned int cpu; + u64 noddp = 0, noddp_ext_buff = 0; + for_each_possible_cpu(cpu) { + ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu); + noddp += ddp_pool->noddp; + noddp_ext_buff += ddp_pool->noddp_ext_buff; + } + hwstats->fcoe_noddp = noddp; + hwstats->fcoe_noddp_ext_buff = noddp_ext_buff; + } + +#endif /* CONFIG_FCOE */ + break; + default: + break; + } + bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); + hwstats->bprc += bprc; + hwstats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); + if (hw->mac.type == ixgbe_mac_82598EB) + hwstats->mprc -= bprc; + hwstats->roc += IXGBE_READ_REG(hw, IXGBE_ROC); + hwstats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); + hwstats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); + hwstats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); + hwstats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); + hwstats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); + hwstats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); + hwstats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); + lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); + hwstats->lxontxc += lxon; + lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); + hwstats->lxofftxc += lxoff; + hwstats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); + hwstats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); + /* + * 82598 errata - tx of flow control packets is included in tx counters + */ + xon_off_tot = lxon + lxoff; + hwstats->gptc -= xon_off_tot; + hwstats->mptc -= xon_off_tot; + hwstats->gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN)); + hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC); + hwstats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC); + hwstats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC); + hwstats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR); + hwstats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); + hwstats->ptc64 -= xon_off_tot; + hwstats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); + hwstats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); + hwstats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); + hwstats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); + hwstats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); + hwstats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); + hwstats->illerrc += IXGBE_READ_REG(hw, IXGBE_ILLERRC); + /* Fill out the OS statistics structure */ + net_stats->multicast = hwstats->mprc; + + /* Rx Errors */ + net_stats->rx_errors = hwstats->crcerrs + + hwstats->illerrc + + hwstats->rlec + + hwstats->rfc + + hwstats->roc + + hwstats->ruc + + hw_csum_rx_error; + + net_stats->rx_dropped = 0; + net_stats->rx_length_errors = hwstats->rlec; + net_stats->rx_crc_errors = hwstats->crcerrs; + net_stats->rx_missed_errors = total_mpc; + + /* VF Stats Collection - skip while resetting because these + * are not clear on read and otherwise you'll sometimes get + * crazy values. + */ + if (!test_bit(__IXGBE_RESETTING, adapter->state)) { + for (i = 0; i < adapter->num_vfs; i++) { + UPDATE_VF_COUNTER_32bit(IXGBE_PVFGPRC(i), \ + adapter->vfinfo[i].last_vfstats.gprc, \ + adapter->vfinfo[i].vfstats.gprc); + UPDATE_VF_COUNTER_32bit(IXGBE_PVFGPTC(i), \ + adapter->vfinfo[i].last_vfstats.gptc, \ + adapter->vfinfo[i].vfstats.gptc); + UPDATE_VF_COUNTER_36bit(IXGBE_PVFGORC_LSB(i), \ + IXGBE_PVFGORC_MSB(i), \ + adapter->vfinfo[i].last_vfstats.gorc, \ + adapter->vfinfo[i].vfstats.gorc); + UPDATE_VF_COUNTER_36bit(IXGBE_PVFGOTC_LSB(i), \ + IXGBE_PVFGOTC_MSB(i), \ + adapter->vfinfo[i].last_vfstats.gotc, \ + adapter->vfinfo[i].vfstats.gotc); + UPDATE_VF_COUNTER_32bit(IXGBE_PVFMPRC(i), \ + adapter->vfinfo[i].last_vfstats.mprc, \ + adapter->vfinfo[i].vfstats.mprc); + } + } +} + +#ifdef HAVE_TX_MQ +/** + * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table + * @adapter: pointer to the device adapter structure + **/ +static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + + if (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) + return; + + adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT; + + /* if interface is down do nothing */ + if (test_bit(__IXGBE_DOWN, adapter->state)) + return; + + /* do nothing if we are not using signature filters */ + if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)) + return; + + adapter->fdir_overflow++; + + if (ixgbe_reinit_fdir_tables_82599(hw) == IXGBE_SUCCESS) { + for (i = 0; i < adapter->num_tx_queues; i++) + set_bit(__IXGBE_TX_FDIR_INIT_DONE, + &(adapter->tx_ring[i]->state)); + for (i = 0; i < adapter->num_xdp_queues; i++) + set_bit(__IXGBE_TX_FDIR_INIT_DONE, + &adapter->xdp_ring[i]->state); + /* re-enable flow director interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR); + } else { + e_err(probe, "failed to finish FDIR re-initialization, " + "ignored adding FDIR ATR filters\n"); + } +} + +#endif /* HAVE_TX_MQ */ +/** + * ixgbe_check_hang_subtask - check for hung queues and dropped interrupts + * @adapter: pointer to the device adapter structure + * + * This function serves two purposes. First it strobes the interrupt lines + * in order to make certain interrupts are occurring. Secondly it sets the + * bits needed to check for TX hangs. As a result we should immediately + * determine if a hang has occurred. + */ +static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 eics = 0; + int i; + + /* If we're down, removing or resetting, just bail */ + if (test_bit(__IXGBE_DOWN, adapter->state) || + test_bit(__IXGBE_REMOVING, adapter->state) || + test_bit(__IXGBE_RESETTING, adapter->state)) + return; + + /* Force detection of hung controller */ + if (netif_carrier_ok(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + set_check_for_tx_hang(adapter->tx_ring[i]); + for (i = 0; i < adapter->num_xdp_queues; i++) + set_check_for_tx_hang(adapter->xdp_ring[i]); + } + + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { + /* + * for legacy and MSI interrupts don't set any bits + * that are enabled for EIAM, because this operation + * would set *both* EIMS and EICS for any bit in EIAM + */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + } else { + /* get one bit for every active tx/rx interrupt vector */ + for (i = 0; i < adapter->num_q_vectors; i++) { + struct ixgbe_q_vector *qv = adapter->q_vector[i]; + if (qv->rx.ring || qv->tx.ring) + eics |= ((u64)1 << i); + } + } + + /* Cause software interrupt to ensure rings are cleaned */ + ixgbe_irq_rearm_queues(adapter, eics); +} + +/** + * ixgbe_watchdog_update_link - update the link status + * @adapter: pointer to the device adapter structure + **/ +static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 link_speed = adapter->link_speed; + bool link_up = adapter->link_up; + bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; + + if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)) + return; + + if (hw->mac.ops.check_link) { + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + } else { + /* always assume link is up, if no check link function */ + link_speed = IXGBE_LINK_SPEED_10GB_FULL; + link_up = true; + } + +#ifdef HAVE_DCBNL_IEEE + if (adapter->ixgbe_ieee_pfc) + pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); + +#endif + if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) { + if (hw->mac.type == ixgbe_mac_X550 || + ixgbe_is_mac_E6xx(hw->mac.type)) + ixgbe_setup_fc(hw); + hw->mac.ops.fc_enable(hw); + + /* This is known driver so disable MDD before updating SRRCTL */ + if (hw->mac.ops.disable_mdd && + (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.disable_mdd(hw); + + ixgbe_set_rx_drop_en(adapter); + + if (hw->mac.ops.enable_mdd && + (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.enable_mdd(hw); + } + + if (link_up || + time_after(jiffies, (adapter->link_check_timeout + + IXGBE_TRY_LINK_TIMEOUT))) { + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); + IXGBE_WRITE_FLUSH(hw); + } + + adapter->link_up = link_up; + adapter->link_speed = link_speed; + + if (hw->mac.ops.dmac_config && hw->mac.dmac_config.watchdog_timer) { + u8 num_tcs = netdev_get_num_tc(adapter->netdev); +#if IS_ENABLED(CONFIG_FCOE) + u8 fcoe_tc = ixgbe_fcoe_get_tc(adapter); + bool fcoe_en = !!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED); +#endif /* CONFIG_FCOE */ + + if (hw->mac.dmac_config.link_speed != link_speed || +#if IS_ENABLED(CONFIG_FCOE) + hw->mac.dmac_config.fcoe_tc != fcoe_tc || + hw->mac.dmac_config.fcoe_en != fcoe_en || +#endif /* CONFIG_FCOE */ + hw->mac.dmac_config.num_tcs != num_tcs) { + hw->mac.dmac_config.link_speed = link_speed; + hw->mac.dmac_config.num_tcs = num_tcs; +#if IS_ENABLED(CONFIG_FCOE) + hw->mac.dmac_config.fcoe_en = fcoe_en; + hw->mac.dmac_config.fcoe_tc = fcoe_tc; +#endif /* CONFIG_FCOE */ + hw->mac.ops.dmac_config(hw); + } + } +} + +static void ixgbe_update_default_up(struct ixgbe_adapter *adapter) +{ + u8 up = 0; +#ifdef HAVE_DCBNL_IEEE + struct net_device *netdev = adapter->netdev; + struct dcb_app app = { + .selector = DCB_APP_IDTYPE_ETHTYPE, + .protocol = 0, + }; + up = dcb_getapp(netdev, &app); +#endif + +#if IS_ENABLED(CONFIG_FCOE) + adapter->default_up = (up > 1) ? (ffs(up) - 1) : 0; +#else + adapter->default_up = up; +#endif +} + +/** + * ixgbe_watchdog_link_is_up - update netif_carrier status and + * print link up message + * @adapter: pointer to the device adapter structure + **/ +static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + u32 link_speed = adapter->link_speed; + bool flow_rx, flow_tx; + const char *speed_str; + + adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: { + u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); + flow_rx = !!(frctl & IXGBE_FCTRL_RFCE); + flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); + } + break; + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: { + u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); + u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); + flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); + flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X); + } + break; + default: + flow_tx = false; + flow_rx = false; + break; + } + +#ifdef HAVE_PTP_1588_CLOCK + adapter->last_rx_ptp_check = jiffies; + +#endif + /* + * Only continue if link was previously down in running state. + * Note that although the flag __IXGBE_DOWN was already checked from + * the beginning of ixgbe_watchdog_subtask, it is not protected by + * any mutex, so it can be changed in the middle of the watchdog + * execution. + * Make the __IXGBE_DOWN flag work as a semaphore and do not allow + * for changing the carrier state if it has been intentionally set + * to "off" for performing the adapter setup. + * TODO: Review the existing flag synchronization mechanism in the driver + * to identify potential race conditions and introduce appropriate + * mutexes and/or semaphores. + */ + if (test_bit(__IXGBE_DOWN, adapter->state) || netif_carrier_ok(netdev)) + return; + +#if defined(HAVE_PTP_1588_CLOCK) + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type) && + test_bit(__IXGBE_PTP_RUNNING, adapter->state)) + ixgbe_ptp_link_up_e600(adapter); + +#endif /* HAVE_PTP_1588_CLOCK */ + switch (link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + speed_str = "10 Gbps"; + break; + case IXGBE_LINK_SPEED_5GB_FULL: + speed_str = "5 Gbps"; + break; + case IXGBE_LINK_SPEED_2_5GB_FULL: + speed_str = "2.5 Gbps"; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + speed_str = "1 Gbps"; + break; + case IXGBE_LINK_SPEED_100_FULL: + speed_str = "100 Mbps"; + break; + case IXGBE_LINK_SPEED_10_FULL: + speed_str = "10 Mbps"; + break; + default: + speed_str = "unknown speed"; + break; + } + e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", speed_str, + ((flow_rx && flow_tx) ? "RX/TX" : + (flow_rx ? "RX" : + (flow_tx ? "TX" : "None")))); + + /* Check if link state change forces changing EEE state */ + if (adapter->hw.mac.type == ixgbe_mac_E610) { + if (ixgbe_is_eee_enabled(adapter) && + !(ixgbe_check_link_for_eee_e610(adapter, true))) { + hw->mac.ops.setup_eee(hw, false); + adapter->eee_state = IXGBE_EEE_FORCED_DOWN; + } else if (adapter->eee_state == IXGBE_EEE_FORCED_DOWN && + ixgbe_check_link_for_eee_e610(adapter, false)) { + hw->mac.ops.setup_eee(hw, true); + adapter->eee_state = IXGBE_EEE_ENABLED; + } + } + + netif_carrier_on(netdev); +#ifdef HAVE_PTP_1588_CLOCK + if (test_bit(__IXGBE_PTP_RUNNING, adapter->state) && + !ixgbe_is_mac_E6xx(hw->mac.type)) + ixgbe_ptp_start_cyclecounter(adapter); + +#endif /* HAVE_PTP_1588_CLOCK */ +#ifdef IFLA_VF_MAX + ixgbe_check_vf_rate_limit(adapter); +#endif /* IFLA_VF_MAX */ + /* Turn on malicious driver detection */ + if (hw->mac.ops.enable_mdd && (adapter->flags & IXGBE_FLAG_MDD_ENABLED)) + hw->mac.ops.enable_mdd(hw); + + netif_tx_wake_all_queues(netdev); + /* update the default user priority for VFs */ + ixgbe_update_default_up(adapter); + /* ping all the active vfs to let them know link has changed */ + ixgbe_ping_all_vfs(adapter); +} + +/** + * ixgbe_watchdog_link_is_down - update netif_carrier status and + * print link down message + * @adapter: pointer to the adapter structure + **/ +static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + + adapter->link_up = false; + adapter->link_speed = 0; + + /* only continue if link was up previously */ + if (!netif_carrier_ok(netdev)) + return; + + /* poll for SFP+ cable when link is down */ + if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB) + adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; + +#ifdef HAVE_PTP_1588_CLOCK + if (test_bit(__IXGBE_PTP_RUNNING, adapter->state) && + !ixgbe_is_mac_E6xx(hw->mac.type)) + ixgbe_ptp_start_cyclecounter(adapter); + +#endif + e_info(drv, "NIC Link is Down\n"); + netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); + /* ping all the active vfs to let them know link has changed */ + ixgbe_ping_all_vfs(adapter); +} + +static bool ixgbe_ring_tx_pending(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + + if (tx_ring->next_to_use != tx_ring->next_to_clean) + return true; + } + + for (i = 0; i < adapter->num_xdp_queues; i++) { + struct ixgbe_ring *ring = adapter->xdp_ring[i]; + + if (ring->next_to_use != ring->next_to_clean) + return true; + } + + return false; +} + +static bool ixgbe_vf_tx_pending(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + + int i, j; + + if (!adapter->num_vfs) + return false; + + /* resetting the PF is only needed for MACs < X550 */ + if (hw->mac.type >= ixgbe_mac_X550) + return false; + for (i = 0; i < adapter->num_vfs; i++) { + for (j = 0; j < q_per_pool; j++) { + u32 h, t; + + h = IXGBE_READ_REG(hw, IXGBE_PVFTDHn(q_per_pool, i, j)); + t = IXGBE_READ_REG(hw, IXGBE_PVFTDTn(q_per_pool, i, j)); + + if (h != t) + return true; + } + } + + return false; +} + +/** + * ixgbe_watchdog_flush_tx - flush queues on link down + * @adapter: pointer to the device adapter structure + **/ +static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) +{ + if (!netif_carrier_ok(adapter->netdev)) { + if (ixgbe_ring_tx_pending(adapter) || + ixgbe_vf_tx_pending(adapter)) { + /* We've lost link, so the controller stops DMA, + * but we've got queued Tx work that's never going + * to get done, so reset controller to flush Tx. + * (Do the reset outside of interrupt context). + */ + e_warn(drv, "initiating reset due to lost link with pending Tx work\n"); + set_bit(__IXGBE_RESET_REQUESTED, adapter->state); + } + } +} + +#ifdef CONFIG_PCI_IOV +static inline void ixgbe_issue_vf_flr(struct ixgbe_adapter *adapter, + struct pci_dev *vfdev) +{ + int pos, i; + u16 status; + + /* wait for pending transactions on the bus */ + for (i = 0; i < 4; i++) { + if (i) + msleep((1 << (i - 1)) * 100); + + pcie_capability_read_word(vfdev, PCI_EXP_DEVSTA, &status); + if (!(status & PCI_EXP_DEVSTA_TRPND)) + goto clear; + } + + e_dev_warn("Issuing VFLR with pending transactions\n"); + +clear: + pos = pci_find_capability(vfdev, PCI_CAP_ID_EXP); + if (!pos) + return; + + e_dev_err("Issuing VFLR for VF %s\n", pci_name(vfdev)); + pci_write_config_word(vfdev, pos + PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_BCR_FLR); + msleep(100); +} + +static void ixgbe_bad_vf_abort(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (adapter->hw.mac.type == ixgbe_mac_82599EB && + adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) { + adapter->vfinfo[vf].primary_abort_count++; + if (adapter->vfinfo[vf].primary_abort_count == + IXGBE_PRIMARY_ABORT_LIMIT) { + ixgbe_set_vf_link_state(adapter, vf, + IFLA_VF_LINK_STATE_DISABLE); + adapter->vfinfo[vf].primary_abort_count = 0; + + e_info(drv, + "Malicious Driver Detection event detected on PF %d VF %d MAC: %pM mdd-disable-vf=on", + hw->bus.func, vf, + adapter->vfinfo[vf].vf_mac_addresses); + } + } +} + +static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + unsigned int vf; + u32 gpc; + + if (!(netif_carrier_ok(adapter->netdev))) + return; + + gpc = IXGBE_READ_REG(hw, IXGBE_TXDGPC); + if (gpc) /* If incrementing then no need for the check below */ + return; + /* + * Check to see if a bad DMA write target from an errant or + * malicious VF has caused a PCIe error. If so then we can + * issue a VFLR to the offending VF(s) and then resume without + * requesting a full slot reset. + */ + + if (!pdev) + return; + + /* check status reg for all VFs owned by this PF */ + for (vf = 0; vf < adapter->num_vfs; ++vf) { + struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev; + u16 status_reg; + + if (!vfdev) + continue; + pci_read_config_word(vfdev, PCI_STATUS, &status_reg); + if (status_reg != IXGBE_FAILED_READ_CFG_WORD && + status_reg & PCI_STATUS_REC_MASTER_ABORT) { + ixgbe_bad_vf_abort(adapter, vf); + ixgbe_issue_vf_flr(adapter, vfdev); + } + } +} + +static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) +{ + u32 ssvpc; + + /* Do not perform spoof check for 82598 or if not in IOV mode */ + if (adapter->hw.mac.type == ixgbe_mac_82598EB || + adapter->num_vfs == 0) + return; + + ssvpc = IXGBE_READ_REG(&adapter->hw, IXGBE_SSVPC); + + /* + * ssvpc register is cleared on read, if zero then no + * spoofed packets in the last interval. + */ + if (!ssvpc) + return; + + e_warn(drv, "%d Spoofed packets detected\n", ssvpc); +} + +#endif /* CONFIG_PCI_IOV */ + +/** + * ixgbe_watchdog_subtask - check and bring link up + * @adapter: pointer to the device adapter structure + **/ +static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter) +{ + /* if interface is down, removing or resetting, do nothing */ + if (test_bit(__IXGBE_DOWN, adapter->state) || + test_bit(__IXGBE_REMOVING, adapter->state) || + test_bit(__IXGBE_RESETTING, adapter->state)) + return; + + ixgbe_watchdog_update_link(adapter); + + if (adapter->link_up) + ixgbe_watchdog_link_is_up(adapter); + else + ixgbe_watchdog_link_is_down(adapter); +#ifdef CONFIG_PCI_IOV + ixgbe_spoof_check(adapter); + ixgbe_check_for_bad_vf(adapter); +#endif /* CONFIG_PCI_IOV */ + ixgbe_update_stats(adapter); + + ixgbe_watchdog_flush_tx(adapter); +} + +/** + * ixgbe_sfp_detection_subtask - poll for SFP+ cable + * @adapter: the ixgbe adapter structure + **/ +static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + s32 err; + + /* not searching for SFP so there is nothing to do here */ + if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) && + !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) + return; + + if (adapter->sfp_poll_time && + time_after(adapter->sfp_poll_time, jiffies)) + return; /* If not yet time to poll for SFP */ + + /* someone else is in init, wait until next service event */ + if (test_and_set_bit(__IXGBE_IN_SFP_INIT, adapter->state)) + return; + + adapter->sfp_poll_time = jiffies + IXGBE_SFP_POLL_JIFFIES - 1; + + err = hw->phy.ops.identify_sfp(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto sfp_out; + + if (err == IXGBE_ERR_SFP_NOT_PRESENT) { + /* If no cable is present, then we need to reset + * the next time we find a good cable. */ + adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; + } + + /* exit on error */ + if (err) + goto sfp_out; + + /* exit if reset not needed */ + if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) + goto sfp_out; + + adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET; + + /* + * A module may be identified correctly, but the EEPROM may not have + * support for that module. setup_sfp() will fail in that case, so + * we should not allow that module to load. + */ + if (hw->mac.type == ixgbe_mac_82598EB) + err = hw->phy.ops.reset(hw); + else + err = hw->mac.ops.setup_sfp(hw); + + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto sfp_out; + + adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; + e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type); + +sfp_out: + clear_bit(__IXGBE_IN_SFP_INIT, adapter->state); + + if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) && + adapter->netdev_registered) { + e_dev_err("failed to initialize because an unsupported " + "SFP+ module type was detected.\n"); + e_dev_err("Reload the driver after installing a " + "supported module.\n"); + unregister_netdev(adapter->netdev); + adapter->netdev_registered = false; + } +} + +/** + * ixgbe_sfp_link_config_subtask - set up link SFP after module install + * @adapter: the ixgbe adapter structure + **/ +static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 cap_speed; + u32 speed = 0; + bool autoneg = false; + + if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG)) + return; + + /* someone else is in init, wait until next service event */ + if (test_and_set_bit(__IXGBE_IN_SFP_INIT, adapter->state)) + return; + + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; + + hw->mac.ops.get_link_capabilities(hw, &cap_speed, &autoneg); + + /* Advertise highest capable link speed */ + if (cap_speed & IXGBE_LINK_SPEED_10GB_FULL) { + if (!autoneg) + speed = IXGBE_LINK_SPEED_10GB_FULL; + else + speed = cap_speed; + } else if (cap_speed == IXGBE_LINK_SPEED_1GB_FULL) { + speed = IXGBE_LINK_SPEED_1GB_FULL; + } + + if (hw->mac.ops.setup_link) + hw->mac.ops.setup_link(hw, speed, true); + + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; + clear_bit(__IXGBE_IN_SFP_INIT, adapter->state); +} + +/** + * ixgbe_service_timer - Timer Call-back + * @t: pointer to timer_list + **/ +static void ixgbe_service_timer(struct timer_list *t) +{ + struct ixgbe_adapter *adapter = timer_container_of(adapter, t, service_timer); + unsigned long next_event_offset; + + /* poll faster when waiting for link */ + if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) + next_event_offset = HZ / 10; + else + next_event_offset = HZ * 2; + + /* Reset the timer */ + mod_timer(&adapter->service_timer, next_event_offset + jiffies); + + ixgbe_service_event_schedule(adapter); +} + +static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter) +{ + u32 status; + + if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT)) + return; + adapter->flags2 &= ~IXGBE_FLAG2_PHY_INTERRUPT; + status = ixgbe_handle_lasi(&adapter->hw); + if (status != IXGBE_ERR_OVERTEMP) + return; + e_crit(drv, "%s\n", ixgbe_overheat_msg); +} + +static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) +{ + if (!test_and_clear_bit(__IXGBE_RESET_REQUESTED, adapter->state)) + return; + + rtnl_lock(); + /* If we're already down or resetting, just bail */ + if (test_bit(__IXGBE_DOWN, adapter->state) || + test_bit(__IXGBE_REMOVING, adapter->state) || + test_bit(__IXGBE_RESETTING, adapter->state)) { + rtnl_unlock(); + return; + } + + netdev_err(adapter->netdev, "Reset adapter\n"); + adapter->tx_timeout_count++; + + ixgbe_reinit_locked(adapter); + + rtnl_unlock(); +} + +static int ixgbe_check_fw_api_ver(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (hw->api_maj_ver > IXGBE_FW_API_VER_MAJOR) { + e_dev_err("The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n"); + + ixgbe_down(adapter); + return -EOPNOTSUPP; + + } else if (hw->api_maj_ver == IXGBE_FW_API_VER_MAJOR && + hw->api_min_ver > (IXGBE_FW_API_VER_MINOR + 2)) { + e_dev_info("The driver for the device detected a newer version of the NVM image than expected. Please install the most recent version of the network driver.\n"); + + } else if (hw->api_maj_ver < IXGBE_FW_API_VER_MAJOR || + hw->api_min_ver < IXGBE_FW_API_VER_MINOR - 2) { + e_dev_info("The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n"); + } + + return 0; +} + +/** + * ixgbe_check_fw_error - Check firmware for errors + * @adapter: the adapter private structure + * + * Check firmware errors in register FWSM + **/ +static bool ixgbe_check_fw_error(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (hw->mac.ops.fw_recovery_mode && hw->mac.ops.fw_recovery_mode(hw)) { + e_dev_err("Firmware recovery mode detected. Limiting functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n"); + return true; + } + + if (ixgbe_is_mac_E6xx(hw->mac.type) && ixgbe_fw_rollback_mode(hw)) { + struct ixgbe_nvm_info *nvm_info = &adapter->hw.flash.nvm; + char ver_buff[64] = ""; + + if (!ixgbe_get_fw_version(hw) && !ixgbe_get_nvm_ver(hw, nvm_info)) { + snprintf(ver_buff, sizeof(ver_buff), + "Current version is NVM:%x.%02x 0x%x, FW:%d.%d. ", + nvm_info->major, nvm_info->minor, nvm_info->eetrack, + hw->fw_maj_ver, hw->fw_maj_ver); + } + + dev_warn_once(ixgbe_pf_to_dev(adapter), + "Firmware rollback mode detected. %sDevice may exhibit limited functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware rollback mode.", + ver_buff); + } + return false; +} + +static void ixgbe_recovery_service_task(struct work_struct *work) +{ + struct ixgbe_adapter *adapter = container_of(work, + struct ixgbe_adapter, + service_task); + + ixgbe_handle_fw_event(adapter); + ixgbe_service_event_complete(adapter); + + mod_timer(&adapter->service_timer, jiffies + msecs_to_jiffies(100)); +} + +/** + * ixgbe_service_task - manages and runs subtasks + * @work: pointer to work_struct containing our data + **/ +static void ixgbe_service_task(struct work_struct *work) +{ + struct ixgbe_adapter *adapter = container_of(work, + struct ixgbe_adapter, + service_task); + struct ixgbe_hw *hw = &adapter->hw; + + if (IXGBE_REMOVED(adapter->hw.hw_addr)) { + if (!test_bit(__IXGBE_DOWN, adapter->state)) { + rtnl_lock(); + ixgbe_down(adapter); + rtnl_unlock(); + } + ixgbe_service_event_complete(adapter); + return; + } + + if (ixgbe_check_fw_error(adapter)) { + if (!test_bit(__IXGBE_DOWN, adapter->state)) { + unregister_netdev(adapter->netdev); + adapter->netdev_registered = false; + } + ixgbe_service_event_complete(adapter); + return; + } + if (adapter->flags2 & IXGBE_FLAG2_FW_ASYNC_EVENT) + ixgbe_handle_fw_event(adapter); +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) +#ifndef HAVE_UDP_TUNNEL_NIC_INFO + if (adapter->flags2 & IXGBE_FLAG2_UDP_TUN_REREG_NEEDED) { + rtnl_lock(); + adapter->flags2 &= ~IXGBE_FLAG2_UDP_TUN_REREG_NEEDED; +#ifdef HAVE_UDP_ENC_RX_OFFLOAD + udp_tunnel_get_rx_info(adapter->netdev); +#else + vxlan_get_rx_port(adapter->netdev); +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ + rtnl_unlock(); + } +#endif /* HAVE_UDP_TUNNEL_NIC_INFO */ +#endif /* HAVE_UDP_ENC_RX_OFFLOAD || HAVE_VXLAN_RX_OFFLOAD */ + if (ixgbe_is_mac_E6xx(hw->mac.type)) + ixgbe_check_media_subtask(adapter); + ixgbe_reset_subtask(adapter); + ixgbe_phy_interrupt_subtask(adapter); + ixgbe_sfp_detection_subtask(adapter); + ixgbe_sfp_link_config_subtask(adapter); + ixgbe_check_overtemp_subtask(adapter); + ixgbe_watchdog_subtask(adapter); +#ifdef HAVE_TX_MQ + ixgbe_fdir_reinit_subtask(adapter); +#endif + ixgbe_check_hang_subtask(adapter); +#ifdef HAVE_PTP_1588_CLOCK + if (test_bit(__IXGBE_PTP_RUNNING, adapter->state)) { + if (!ixgbe_is_mac_E6xx(hw->mac.type)) + ixgbe_ptp_overflow_check(adapter); + if (unlikely(adapter->flags & IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER)) + ixgbe_ptp_rx_hang(adapter); + ixgbe_ptp_tx_hang(adapter); + } +#endif /* HAVE_PTP_1588_CLOCK */ + + ixgbe_service_event_complete(adapter); +} + +static int ixgbe_tso(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, + u8 *hdr_len) +{ +#ifdef NETIF_F_TSO + u32 vlan_macip_lens, type_tucmd, mss_l4len_idx; + struct sk_buff *skb = first->skb; + union { + struct iphdr *v4; + struct ipv6hdr *v6; + unsigned char *hdr; + } ip; + union { + struct tcphdr *tcp; + unsigned char *hdr; + } l4; + u32 paylen, l4_offset; + int err; + + if (skb->ip_summed != CHECKSUM_PARTIAL) + return 0; + + if (!skb_is_gso(skb)) + return 0; + + err = skb_cow_head(skb, 0); + if (err < 0) + return err; + + ip.hdr = skb_network_header(skb); + l4.hdr = skb_checksum_start(skb); + + /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ + type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP; + + /* initialize outer IP header fields */ + if (ip.v4->version == 4) { + unsigned char *csum_start = skb_checksum_start(skb); + unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4); + + /* IP header will have to cancel out any data that + * is not a part of the outer IP header + */ + ip.v4->check = csum_fold(csum_partial(trans_start, + csum_start - trans_start, + 0)); + type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4; + + ip.v4->tot_len = 0; + first->tx_flags |= IXGBE_TX_FLAGS_TSO | + IXGBE_TX_FLAGS_CSUM | + IXGBE_TX_FLAGS_IPV4; + } else { + ip.v6->payload_len = 0; + first->tx_flags |= IXGBE_TX_FLAGS_TSO | + IXGBE_TX_FLAGS_CSUM; + } + + /* determine offset of inner transport header */ + l4_offset = l4.hdr - skb->data; + + /* compute length of segmentation header */ + *hdr_len = (l4.tcp->doff * 4) + l4_offset; + + /* remove payload length from inner checksum */ + paylen = skb->len - l4_offset; + csum_replace_by_diff(&l4.tcp->check, htonl(paylen)); + + /* update gso size and bytecount with header size */ + first->gso_segs = skb_shinfo(skb)->gso_segs; + first->bytecount += (first->gso_segs - 1) * *hdr_len; + + /* mss_l4len_id: use 0 as index for TSO */ + mss_l4len_idx = (*hdr_len - l4_offset) << IXGBE_ADVTXD_L4LEN_SHIFT; + mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT; + + /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */ + vlan_macip_lens = l4.hdr - ip.hdr; + vlan_macip_lens |= (ip.hdr - skb->data) << IXGBE_ADVTXD_MACLEN_SHIFT; + vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; + + ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, + mss_l4len_idx); + + return 1; +#else + return 0; +#endif /* NETIF_F_TSO */ +} + +static inline bool ixgbe_ipv6_csum_is_sctp(struct sk_buff *skb) +{ + unsigned int offset = 0; + + ipv6_find_hdr(skb, &offset, IPPROTO_SCTP, NULL, NULL); + + return offset == skb_checksum_start_offset(skb); +} + +static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first) +{ + struct sk_buff *skb = first->skb; + u32 vlan_macip_lens = 0; + u32 type_tucmd = 0; + + if (skb->ip_summed != CHECKSUM_PARTIAL) { +csum_failed: + if (!(first->tx_flags & (IXGBE_TX_FLAGS_HW_VLAN | + IXGBE_TX_FLAGS_CC))) + return; + goto no_csum; + } + + switch (skb->csum_offset) { + case offsetof(struct tcphdr, check): + type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP; + /* fall through */ + case offsetof(struct udphdr, check): + break; + case offsetof(struct sctphdr, checksum): + /* validate that this is actually an SCTP request */ + if (((first->protocol == htons(ETH_P_IP)) && + (ip_hdr(skb)->protocol == IPPROTO_SCTP)) || + ((first->protocol == htons(ETH_P_IPV6)) && + ixgbe_ipv6_csum_is_sctp(skb))) { + type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; + } + fallthrough; + default: + skb_checksum_help(skb); + goto csum_failed; + } + + /* update TX checksum flag */ + first->tx_flags |= IXGBE_TX_FLAGS_CSUM; + vlan_macip_lens = skb_checksum_start_offset(skb) - + skb_network_offset(skb); +no_csum: + /* vlan_macip_lens: MACLEN, VLAN tag */ + vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT; + vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; + + ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, 0); +} + +#define IXGBE_SET_FLAG(_input, _flag, _result) \ + ((_flag <= _result) ? \ + ((u32)(_input & _flag) * (_result / _flag)) : \ + ((u32)(_input & _flag) / (_flag / _result))) + +static u32 ixgbe_tx_cmd_type(u32 tx_flags) +{ + /* set type for advanced descriptor with frame checksum insertion */ + u32 cmd_type = IXGBE_ADVTXD_DTYP_DATA | + IXGBE_ADVTXD_DCMD_DEXT | + IXGBE_ADVTXD_DCMD_IFCS; + + /* set HW vlan bit if vlan is present */ + cmd_type |= IXGBE_SET_FLAG(tx_flags, IXGBE_TX_FLAGS_HW_VLAN, + IXGBE_ADVTXD_DCMD_VLE); + + /* set segmentation enable bits for TSO/FSO */ + cmd_type |= IXGBE_SET_FLAG(tx_flags, IXGBE_TX_FLAGS_TSO, + IXGBE_ADVTXD_DCMD_TSE); + + /* set timestamp bit if present */ + cmd_type |= IXGBE_SET_FLAG(tx_flags, IXGBE_TX_FLAGS_TSTAMP, + IXGBE_ADVTXD_MAC_TSTAMP); + + return cmd_type; +} + +static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc, + u32 tx_flags, unsigned int paylen) +{ + u32 olinfo_status = paylen << IXGBE_ADVTXD_PAYLEN_SHIFT; + + /* enable L4 checksum for TSO and TX checksum offload */ + olinfo_status |= IXGBE_SET_FLAG(tx_flags, + IXGBE_TX_FLAGS_CSUM, + IXGBE_ADVTXD_POPTS_TXSM); + + /* enble IPv4 checksum for TSO */ + olinfo_status |= IXGBE_SET_FLAG(tx_flags, + IXGBE_TX_FLAGS_IPV4, + IXGBE_ADVTXD_POPTS_IXSM); + + /* + * Check Context must be set if Tx switch is enabled, which it + * always is for case where virtual functions are running + */ + olinfo_status |= IXGBE_SET_FLAG(tx_flags, + IXGBE_TX_FLAGS_CC, + IXGBE_ADVTXD_CC); + + tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); +} + +static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) +{ + netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); + + /* Herbert's original patch had: + * smp_mb__after_netif_stop_queue(); + * but since that doesn't exist yet, just open code it. + */ + smp_mb(); + + /* We need to check again in a case another CPU has just + * made room available. + */ + if (likely(ixgbe_desc_unused(tx_ring) < size)) + return -EBUSY; + + /* A reprieve! - use start_queue because it doesn't call schedule */ + netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index); + ++tx_ring->tx_stats.restart_queue; + return 0; +} + +static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) +{ + if (likely(ixgbe_desc_unused(tx_ring) >= size)) + return 0; + + return __ixgbe_maybe_stop_tx(tx_ring, size); +} + +static int ixgbe_tx_map(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, + const u8 hdr_len) +{ + struct sk_buff *skb = first->skb; + struct ixgbe_tx_buffer *tx_buffer; + union ixgbe_adv_tx_desc *tx_desc; + skb_frag_t *frag; + dma_addr_t dma; + unsigned int data_len, size; + u32 tx_flags = first->tx_flags; + u32 cmd_type = ixgbe_tx_cmd_type(tx_flags); + u16 i = tx_ring->next_to_use; + + tx_desc = IXGBE_TX_DESC(tx_ring, i); + + ixgbe_tx_olinfo_status(tx_desc, tx_flags, skb->len - hdr_len); + + size = skb_headlen(skb); + data_len = skb->data_len; + +#if IS_ENABLED(CONFIG_FCOE) + if (tx_flags & IXGBE_TX_FLAGS_FCOE) { + if (data_len < sizeof(struct fcoe_crc_eof)) { + size -= sizeof(struct fcoe_crc_eof) - data_len; + data_len = 0; + } else { + data_len -= sizeof(struct fcoe_crc_eof); + } + } +#endif /* CONFIG_FCOE */ + + dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE); + + tx_buffer = first; + + for (frag = &skb_shinfo(skb)->frags[0];; frag++) { + if (dma_mapping_error(tx_ring->dev, dma)) + goto dma_error; + + /* record length, and DMA address */ + dma_unmap_len_set(tx_buffer, len, size); + dma_unmap_addr_set(tx_buffer, dma, dma); + + tx_desc->read.buffer_addr = cpu_to_le64(dma); + + while (unlikely(size > IXGBE_MAX_DATA_PER_TXD)) { + tx_desc->read.cmd_type_len = + cpu_to_le32(cmd_type ^ IXGBE_MAX_DATA_PER_TXD); + + i++; + tx_desc++; + if (i == tx_ring->count) { + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + i = 0; + } + tx_desc->read.olinfo_status = 0; + + dma += IXGBE_MAX_DATA_PER_TXD; + size -= IXGBE_MAX_DATA_PER_TXD; + + tx_desc->read.buffer_addr = cpu_to_le64(dma); + } + + if (likely(!data_len)) + break; + + tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type ^ size); + + i++; + tx_desc++; + if (i == tx_ring->count) { + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + i = 0; + } + tx_desc->read.olinfo_status = 0; + +#if IS_ENABLED(CONFIG_FCOE) + size = min_t(unsigned int, data_len, skb_frag_size(frag)); +#else + size = skb_frag_size(frag); +#endif + data_len -= size; + + dma = skb_frag_dma_map(tx_ring->dev, frag, 0, size, + DMA_TO_DEVICE); + + tx_buffer = &tx_ring->tx_buffer_info[i]; + } + + /* write last descriptor with RS and EOP bits */ + cmd_type |= size | IXGBE_TXD_CMD; + tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); + + netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount); + + /* set the timestamp */ + first->time_stamp = jiffies; + +#ifndef HAVE_TRANS_START_IN_QUEUE + netdev_ring(tx_ring)->trans_start = first->time_stamp; +#endif + /* + * Force memory writes to complete before letting h/w know there + * are new descriptors to fetch. (Only applicable for weak-ordered + * memory model archs, such as IA-64). + * + * We also need this memory barrier to make certain all of the + * status bits have been updated before next_to_watch is written. + */ + wmb(); + + /* set next_to_watch value indicating a packet is present */ + first->next_to_watch = tx_desc; + + i++; + if (i == tx_ring->count) + i = 0; + + tx_ring->next_to_use = i; + + ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); + + skb_tx_timestamp(skb); + + if (netif_xmit_stopped(txring_txq(tx_ring)) || !netdev_xmit_more()) { + writel(i, tx_ring->tail); +#ifndef SPIN_UNLOCK_IMPLIES_MMIOWB + + /* The following mmiowb() is required on certain + * architechtures (IA64/Altix in particular) in order to + * synchronize the I/O calls with respect to a spin lock. This + * is because the wmb() on those architectures does not + * guarantee anything for posted I/O writes. + * + * Note that the associated spin_unlock() is not within the + * driver code, but in the networking core stack. + */ + mmiowb(); +#endif /* SPIN_UNLOCK_IMPLIES_MMIOWB */ + } + + return 0; +dma_error: + dev_err(tx_ring->dev, "TX DMA map failed\n"); + + /* clear dma mappings for failed tx_buffer_info map */ + for (;;) { + tx_buffer = &tx_ring->tx_buffer_info[i]; + if (dma_unmap_len(tx_buffer, len)) + dma_unmap_page(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + dma_unmap_len_set(tx_buffer, len, 0); + if (tx_buffer == first) + break; + if (i == 0) + i += tx_ring->count; + i--; + } + + dev_kfree_skb_any(first->skb); + first->skb = NULL; + + tx_ring->next_to_use = i; + + return -1; +} + +static void ixgbe_atr(struct ixgbe_ring *ring, + struct ixgbe_tx_buffer *first) +{ + struct ixgbe_q_vector *q_vector = ring->q_vector; + union ixgbe_atr_hash_dword input = { .dword = 0 }; + union ixgbe_atr_hash_dword common = { .dword = 0 }; + union { + unsigned char *network; + struct iphdr *ipv4; + struct ipv6hdr *ipv6; + } hdr; + struct tcphdr *th; + struct sk_buff *skb; + unsigned int hlen; + __be16 vlan_id; + int l4_proto; + + /* if ring doesn't have a interrupt vector, cannot perform ATR */ + if (!q_vector) + return; + + /* do nothing if sampling is disabled */ + if (!ring->atr_sample_rate) + return; + + ring->atr_count++; + + /* currently only IPv4/IPv6 with TCP is supported */ + if (first->protocol != htons(ETH_P_IP) && + first->protocol != htons(ETH_P_IPV6)) + return; + + /* snag network header to get L4 type and address */ + skb = first->skb; + hdr.network = skb_network_header(skb); + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) + if (unlikely(hdr.network <= skb->data)) + return; + + if (skb->encapsulation && + first->protocol == htons(ETH_P_IP) && + hdr.ipv4->protocol == IPPROTO_UDP) { + struct ixgbe_adapter *adapter = q_vector->adapter; +#ifndef VXLAN_HEADROOM + if (unlikely(skb_tail_pointer(skb) < hdr.network + + vxlan_headroom(0))) + return; +#else + if (unlikely(skb_tail_pointer(skb) < hdr.network + + VXLAN_HEADROOM)) + return; +#endif /*VXLAN_HEADROOM*/ + + /* verify the port is recognized as VXLAN or GENEVE*/ + if (adapter->vxlan_port && + udp_hdr(skb)->dest == adapter->vxlan_port) + hdr.network = skb_inner_network_header(skb); + +#ifdef HAVE_UDP_ENC_RX_OFFLOAD + if (adapter->geneve_port && + udp_hdr(skb)->dest == adapter->geneve_port) + hdr.network = skb_inner_network_header(skb); +#endif + } +#endif /* HAVE_UDP_ENC_RX_OFFLOAD || HAVE_VXLAN_RX_OFFLOAD */ + + /* Make sure we have at least [minimum IPv4 header + TCP] + * or [IPv6 header] bytes + */ + if (unlikely(skb_tail_pointer(skb) < hdr.network + 40)) + return; + + /* Currently only IPv4/IPv6 with TCP is supported */ + switch (hdr.ipv4->version) { + case IPVERSION: + /* access ihl as u8 to avoid unaligned access on ia64 */ + hlen = (hdr.network[0] & 0x0F) << 2; + l4_proto = hdr.ipv4->protocol; + break; + case 6: + hlen = hdr.network - skb->data; + l4_proto = ipv6_find_hdr(skb, &hlen, IPPROTO_TCP, NULL, NULL); + hlen -= hdr.network - skb->data; + break; + default: + return; + } + + if (l4_proto != IPPROTO_TCP) + return; + + if (unlikely(skb_tail_pointer(skb) < hdr.network + + hlen + sizeof(struct tcphdr))) + return; + + th = (struct tcphdr *)(hdr.network + hlen); + + /* skip this packet since the socket is closing */ + if (th->fin) + return; + + /* sample on all syn packets or once every atr sample count */ + if (!th->syn && (ring->atr_count < ring->atr_sample_rate)) + return; + + /* reset sample count */ + ring->atr_count = 0; + + vlan_id = htons(first->tx_flags >> IXGBE_TX_FLAGS_VLAN_SHIFT); + + /* + * src and dst are inverted, think how the receiver sees them + * + * The input is broken into two sections, a non-compressed section + * containing vm_pool, vlan_id, and flow_type. The rest of the data + * is XORed together and stored in the compressed dword. + */ + input.formatted.vlan_id = vlan_id; + + /* + * since src port and flex bytes occupy the same word XOR them together + * and write the value to source port portion of compressed dword + */ + if (first->tx_flags & (IXGBE_TX_FLAGS_SW_VLAN | IXGBE_TX_FLAGS_HW_VLAN)) + common.port.src ^= th->dest ^ htons(ETH_P_8021Q); + else + common.port.src ^= th->dest ^ first->protocol; + common.port.dst ^= th->source; + + switch (hdr.ipv4->version) { + case IPVERSION: + input.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4; + common.ip ^= hdr.ipv4->saddr ^ hdr.ipv4->daddr; + break; + case 6: + input.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV6; + common.ip ^= hdr.ipv6->saddr.s6_addr32[0] ^ + hdr.ipv6->saddr.s6_addr32[1] ^ + hdr.ipv6->saddr.s6_addr32[2] ^ + hdr.ipv6->saddr.s6_addr32[3] ^ + hdr.ipv6->daddr.s6_addr32[0] ^ + hdr.ipv6->daddr.s6_addr32[1] ^ + hdr.ipv6->daddr.s6_addr32[2] ^ + hdr.ipv6->daddr.s6_addr32[3]; + break; + default: + break; + } + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) + if (hdr.network != skb_network_header(skb)) + input.formatted.flow_type |= IXGBE_ATR_L4TYPE_TUNNEL_MASK; +#endif /* HAVE_UDP_ENC_RX_OFFLOAD || HAVE_VXLAN_RX_OFFLOAD */ + + /* This assumes the Rx queue and Tx queue are bound to the same CPU */ + ixgbe_fdir_add_signature_filter_82599(&q_vector->adapter->hw, + input, common, ring->queue_index); +} +#ifdef HAVE_NETDEV_SELECT_QUEUE +#if IS_ENABLED(CONFIG_FCOE) + +#if defined(HAVE_NDO_SELECT_QUEUE_FALLBACK_REMOVED) +static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) +#elif defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) +static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, + __always_unused struct net_device *sb_dev, + select_queue_fallback_t fallback) +#elif defined(HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK) +static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, + __always_unused void *accel, + select_queue_fallback_t fallback) +#elif defined(HAVE_NDO_SELECT_QUEUE_ACCEL) +static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, + __always_unused void *accel) +#else +static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) +#endif /* HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */ +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_ring_feature *f; + int txq; + + /* + * only execute the code below if protocol is FCoE + * or FIP and we have FCoE enabled on the adapter + */ + switch (vlan_get_protocol(skb)) { + case __constant_htons(ETH_P_FCOE): + case __constant_htons(ETH_P_FIP): + adapter = netdev_priv(dev); + + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) + break; + fallthrough; + default: +#if defined(HAVE_NDO_SELECT_QUEUE_FALLBACK_REMOVED) + return netdev_pick_tx(dev, skb, sb_dev); +#elif defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) + return fallback(dev, skb, sb_dev); +#elif defined(HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK) + return fallback(dev, skb); +#else + return __netdev_pick_tx(dev, skb); +#endif + } + + f = &adapter->ring_feature[RING_F_FCOE]; + + txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : + smp_processor_id(); + + while (txq >= f->indices) + txq -= f->indices; + + return txq + f->offset; +} +#endif /* CONFIG_FCOE */ +#endif /* HAVE_NETDEV_SELECT_QUEUE */ + +#ifdef HAVE_XDP_SUPPORT +#ifdef HAVE_XDP_FRAME_STRUCT +int ixgbe_xmit_xdp_ring(struct ixgbe_ring *ring, struct xdp_frame *xdpf) +#else +int ixgbe_xmit_xdp_ring(struct ixgbe_ring *ring, struct xdp_buff *xdp) +#endif +{ + struct ixgbe_tx_buffer *tx_buffer; + union ixgbe_adv_tx_desc *tx_desc; + u32 len, cmd_type; + dma_addr_t dma; + u16 i; + +#ifdef HAVE_XDP_FRAME_STRUCT + len = xdpf->len; +#else + len = xdp->data_end - xdp->data; +#endif + + if (unlikely(!ixgbe_desc_unused(ring))) + return IXGBE_XDP_CONSUMED; + +#ifdef HAVE_XDP_FRAME_STRUCT + dma = dma_map_single(ring->dev, xdpf->data, len, DMA_TO_DEVICE); +#else + dma = dma_map_single(ring->dev, xdp->data, len, DMA_TO_DEVICE); +#endif + if (dma_mapping_error(ring->dev, dma)) + return IXGBE_XDP_CONSUMED; + + /* record the location of the first descriptor for this packet */ + tx_buffer = &ring->tx_buffer_info[ring->next_to_use]; + tx_buffer->bytecount = len; + tx_buffer->gso_segs = 1; + tx_buffer->protocol = 0; + + i = ring->next_to_use; + tx_desc = IXGBE_TX_DESC(ring, i); + + dma_unmap_len_set(tx_buffer, len, len); + dma_unmap_addr_set(tx_buffer, dma, dma); +#ifdef HAVE_XDP_FRAME_STRUCT + tx_buffer->xdpf = xdpf; +#else + tx_buffer->data = xdp->data; +#endif + + tx_desc->read.buffer_addr = cpu_to_le64(dma); + + /* put descriptor type bits */ + cmd_type = IXGBE_ADVTXD_DTYP_DATA | + IXGBE_ADVTXD_DCMD_DEXT | + IXGBE_ADVTXD_DCMD_IFCS; + cmd_type |= len | IXGBE_TXD_CMD; + tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); + tx_desc->read.olinfo_status = + cpu_to_le32(len << IXGBE_ADVTXD_PAYLEN_SHIFT); + + /* Avoid any potential race with xdp_xmit and cleanup */ + smp_wmb(); + +#ifdef HAVE_XDP_SUPPORT +#ifdef HAVE_AF_XDP_ZC_SUPPORT + ring->xdp_tx_active++; +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif /* HAVE_XDP_SUPPORT */ + + /* set next_to_watch value indicating a packet is present */ + i++; + if (i == ring->count) + i = 0; + + tx_buffer->next_to_watch = tx_desc; + ring->next_to_use = i; + + return IXGBE_XDP_TX; +} + +#ifdef HAVE_AF_XDP_ZC_SUPPORT +static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) +{ + unsigned long wait_delay, delay_interval; + struct ixgbe_hw *hw = &adapter->hw; + u8 reg_idx = tx_ring->reg_idx; + int wait_loop; + u32 txdctl; + + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH); + + /* delay mechanism from ixgbe_disable_tx */ + delay_interval = ixgbe_get_completion_timeout(adapter) / 100; + + wait_loop = IXGBE_MAX_RX_DESC_POLL; + wait_delay = delay_interval; + + while (wait_loop--) { + usleep_range(wait_delay, wait_delay + 10); + wait_delay += delay_interval * 2; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + + if (!(txdctl & IXGBE_TXDCTL_ENABLE)) + return; + } + + e_err(drv, "TXDCTL.ENABLE not cleared within the polling period\n"); +} + +static void ixgbe_disable_txr(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) +{ + set_bit(__IXGBE_TX_DISABLED, &tx_ring->state); + ixgbe_disable_txr_hw(adapter, tx_ring); +} + +static void ixgbe_disable_rxr_hw(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) +{ + unsigned long wait_delay, delay_interval; + struct ixgbe_hw *hw = &adapter->hw; + u8 reg_idx = rx_ring->reg_idx; + int wait_loop; + u32 rxdctl; + + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + rxdctl &= ~IXGBE_RXDCTL_ENABLE; + rxdctl |= IXGBE_RXDCTL_SWFLSH; + + /* write value back with RXDCTL.ENABLE bit cleared */ + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); + + /* RXDCTL.EN may not change on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + /* delay mechanism from ixgbe_disable_rx */ + delay_interval = ixgbe_get_completion_timeout(adapter) / 100; + + wait_loop = IXGBE_MAX_RX_DESC_POLL; + wait_delay = delay_interval; + + while (wait_loop--) { + usleep_range(wait_delay, wait_delay + 10); + wait_delay += delay_interval * 2; + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + + if (!(rxdctl & IXGBE_RXDCTL_ENABLE)) + return; + } + + e_err(drv, "RXDCTL.ENABLE not cleared within the polling period\n"); +} + +static void ixgbe_reset_txr_stats(struct ixgbe_ring *tx_ring) +{ + memset(&tx_ring->stats, 0, sizeof(tx_ring->stats)); + memset(&tx_ring->tx_stats, 0, sizeof(tx_ring->tx_stats)); +} + +static void ixgbe_reset_rxr_stats(struct ixgbe_ring *rx_ring) +{ + memset(&rx_ring->stats, 0, sizeof(rx_ring->stats)); + memset(&rx_ring->rx_stats, 0, sizeof(rx_ring->rx_stats)); +} + +/** + * ixgbe_txrx_ring_disable - Disable Rx/Tx/XDP Tx rings + * @adapter: adapter structure + * @ring: ring index + * + * This function disables a certain Rx/Tx/XDP Tx ring. The function + * assumes that the netdev is running. + **/ +void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring) +{ + struct ixgbe_ring *rx_ring, *tx_ring, *xdp_ring; + + rx_ring = adapter->rx_ring[ring]; + tx_ring = adapter->tx_ring[ring]; + xdp_ring = adapter->xdp_ring[ring]; + + ixgbe_disable_txr(adapter, tx_ring); + if (xdp_ring) + ixgbe_disable_txr(adapter, xdp_ring); + ixgbe_disable_rxr_hw(adapter, rx_ring); + + if (xdp_ring) + synchronize_rcu(); + + /* Rx/Tx/XDP Tx share the same napi context. */ + napi_disable(&rx_ring->q_vector->napi); + + ixgbe_clean_tx_ring(tx_ring); + if (xdp_ring) + ixgbe_clean_tx_ring(xdp_ring); + ixgbe_clean_rx_ring(rx_ring); + + ixgbe_reset_txr_stats(tx_ring); + if (xdp_ring) + ixgbe_reset_txr_stats(xdp_ring); + ixgbe_reset_rxr_stats(rx_ring); +} + +/** + * ixgbe_txrx_ring_enable - Enable Rx/Tx/XDP Tx rings + * @adapter: adapter structure + * @ring: ring index + * + * This function enables a certain Rx/Tx/XDP Tx ring. The function + * assumes that the netdev is running. + **/ +void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring) +{ + struct ixgbe_ring *rx_ring, *tx_ring, *xdp_ring; + + rx_ring = adapter->rx_ring[ring]; + tx_ring = adapter->tx_ring[ring]; + xdp_ring = adapter->xdp_ring[ring]; + + /* Rx/Tx/XDP Tx share the same napi context. */ + napi_enable(&rx_ring->q_vector->napi); + + ixgbe_configure_tx_ring(adapter, tx_ring); + if (xdp_ring) + ixgbe_configure_tx_ring(adapter, xdp_ring); + ixgbe_configure_rx_ring(adapter, rx_ring); + + clear_bit(__IXGBE_TX_DISABLED, &tx_ring->state); + if (xdp_ring) + clear_bit(__IXGBE_TX_DISABLED, &xdp_ring->state); +} +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif /* HAVE_XDP_SUPPORT */ + +/** + * ixgbe_xmit_frame_ring - Transmit a frame on a specific TX ring + * @skb: Socket buffer containing the packet to transmit + * @adapter: Pointer to the ixgbe adapter structure (may be unused) + * @tx_ring: Transmit ring to use for sending the packet + * + * This function handles the transmission of a network packet on a specified + * transmit ring of the ixgbe network adapter. It prepares the packet for + * transmission, including handling VLAN tags, timestamping, and offloads + * like TSO and checksum. The function checks for available descriptors and + * updates the ring state accordingly. It also manages special cases such as + * FCoE and PTP timestamping. + * + * Return: NETDEV_TX_OK on success, or NETDEV_TX_BUSY if the ring is full. + */ +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, + struct ixgbe_adapter __maybe_unused *adapter, + struct ixgbe_ring *tx_ring) +{ + struct ixgbe_tx_buffer *first; + int tso; + u32 tx_flags = 0; + unsigned short f; + u16 count = TXD_USE_COUNT(skb_headlen(skb)); + __be16 protocol = skb->protocol; + u8 hdr_len = 0; + + /* + * need: 1 descriptor per page * PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD, + * + 1 desc for skb_headlen/IXGBE_MAX_DATA_PER_TXD, + * + 2 desc gap to keep tail from touching head, + * + 1 desc for context descriptor, + * otherwise try next time + */ + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)-> + frags[f])); + + if (ixgbe_maybe_stop_tx(tx_ring, count + 3)) { + tx_ring->tx_stats.tx_busy++; + return NETDEV_TX_BUSY; + } + + /* record the location of the first descriptor for this packet */ + first = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; + first->skb = skb; + first->bytecount = skb->len; + first->gso_segs = 1; + + /* if we have a HW VLAN tag being added default to the HW one */ + if (skb_vlan_tag_present(skb)) { + tx_flags |= skb_vlan_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT; + tx_flags |= IXGBE_TX_FLAGS_HW_VLAN; + /* else if it is a SW VLAN check the next protocol and store the tag */ + } else if (protocol == htons(ETH_P_8021Q)) { + struct vlan_hdr *vhdr, _vhdr; + vhdr = skb_header_pointer(skb, ETH_HLEN, sizeof(_vhdr), &_vhdr); + if (!vhdr) + goto out_drop; + + protocol = vhdr->h_vlan_encapsulated_proto; + tx_flags |= ntohs(vhdr->h_vlan_TCI) << + IXGBE_TX_FLAGS_VLAN_SHIFT; + tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; + } + +#ifdef HAVE_PTP_1588_CLOCK +#ifdef SKB_SHARED_TX_IS_UNION + if (unlikely(skb_tx(skb)->hardware) && + adapter->ptp_clock) { + if (!test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS, + adapter->state)) { + skb_tx(skb)->in_progress = 1; +#else + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && + adapter->ptp_clock) { + if (!test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS, + adapter->state)) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; +#endif + tx_flags |= IXGBE_TX_FLAGS_TSTAMP; + + /* schedule check for Tx timestamp */ + adapter->ptp_tx_skb = skb_get(skb); + adapter->ptp_tx_start = jiffies; + + /* schedule check for Tx timestamp */ + if (!ixgbe_ptp_is_tx_ptp(adapter, adapter->ptp_tx_skb)) + schedule_work(&adapter->ptp_tx_work); + } else { + adapter->tx_hwtstamp_skipped++; + } + } + +#endif +#ifdef CONFIG_PCI_IOV + /* + * Use the l2switch_enable flag - would be false if the DMA + * Tx switch had been disabled. + */ + if (adapter->flags & IXGBE_FLAG_SRIOV_L2SWITCH_ENABLE) + tx_flags |= IXGBE_TX_FLAGS_CC; + +#endif +#ifdef HAVE_TX_MQ + if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && + ((tx_flags & (IXGBE_TX_FLAGS_HW_VLAN | IXGBE_TX_FLAGS_SW_VLAN)) || + (skb->priority != TC_PRIO_CONTROL))) { + tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK; +#if IS_ENABLED(CONFIG_FCOE) + /* for FCoE with DCB, we force the priority to what + * was specified by the switch */ + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + ((protocol == htons(ETH_P_FCOE)) || + (protocol == htons(ETH_P_FIP)))) + tx_flags |= adapter->fcoe.up << + IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT; + else +#endif /* CONFIG_FCOE */ + tx_flags |= skb->priority << + IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT; + if (tx_flags & IXGBE_TX_FLAGS_SW_VLAN) { + struct vlan_ethhdr *vhdr; + if (skb_header_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto out_drop; + vhdr = (struct vlan_ethhdr *)skb->data; + vhdr->h_vlan_TCI = htons(tx_flags >> + IXGBE_TX_FLAGS_VLAN_SHIFT); + } else { + tx_flags |= IXGBE_TX_FLAGS_HW_VLAN; + } + } + +#endif /* HAVE_TX_MQ */ + /* record initial flags and protocol */ + first->tx_flags = tx_flags; + first->protocol = protocol; + +#if IS_ENABLED(CONFIG_FCOE) + /* setup tx offload for FCoE */ + if ((protocol == htons(ETH_P_FCOE)) && + (tx_ring->netdev->features & (NETIF_F_FSO | NETIF_F_FCOE_CRC))) { + tso = ixgbe_fso(tx_ring, first, &hdr_len); + if (tso < 0) + goto out_drop; + + goto xmit_fcoe; + } else if (protocol == htons(ETH_P_FIP)) { + /* FCoE stack has a bug where it does not set the network + * header offset for FIP frames sent resulting into MACLEN + * being set to ZERO in the Tx context descriptor. + * This will cause MDD events when trying to Tx such frames. + */ + if (!skb_network_offset(skb)) { + if (tx_flags & (IXGBE_TX_FLAGS_HW_VLAN | + IXGBE_TX_FLAGS_SW_VLAN)) + skb_set_network_header(skb, + sizeof(struct ethhdr) + + sizeof(struct vlan_hdr)); + else + skb_set_network_header(skb, + sizeof(struct ethhdr)); + } + } +#endif /* CONFIG_FCOE */ + + tso = ixgbe_tso(tx_ring, first, &hdr_len); + if (tso < 0) + goto out_drop; + else if (!tso) + ixgbe_tx_csum(tx_ring, first); + + /* add the ATR filter if ATR is on */ + if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state)) + ixgbe_atr(tx_ring, first); + +#if IS_ENABLED(CONFIG_FCOE) +xmit_fcoe: +#endif /* CONFIG_FCOE */ +#ifdef HAVE_PTP_1588_CLOCK + if (ixgbe_tx_map(tx_ring, first, hdr_len)) + goto cleanup_tx_tstamp; +#else + ixgbe_tx_map(tx_ring, first, hdr_len); +#endif + + return NETDEV_TX_OK; + +out_drop: + dev_kfree_skb_any(first->skb); + first->skb = NULL; +#ifdef HAVE_PTP_1588_CLOCK +cleanup_tx_tstamp: + if (unlikely(tx_flags & IXGBE_TX_FLAGS_TSTAMP)) { + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb = NULL; + cancel_work_sync(&adapter->ptp_tx_work); + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state); + } +#endif + + return NETDEV_TX_OK; +} + +static netdev_tx_t __ixgbe_xmit_frame(struct sk_buff *skb, + struct net_device *netdev, + __always_unused struct ixgbe_ring *ring) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_ring *tx_ring; +#ifdef HAVE_TX_MQ + unsigned int r_idx = skb->queue_mapping; +#endif + + if (!netif_carrier_ok(netdev)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + /* + * The minimum packet size for olinfo paylen is 17 so pad the skb + * in order to meet this minimum size requirement. + */ + if (skb_put_padto(skb, 17)) + return NETDEV_TX_OK; + +#ifdef HAVE_TX_MQ + if (r_idx >= adapter->num_tx_queues) + r_idx = r_idx % adapter->num_tx_queues; + tx_ring = adapter->tx_ring[r_idx]; +#else + tx_ring = adapter->tx_ring[0]; +#endif + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (unlikely(test_bit(__IXGBE_TX_DISABLED, &tx_ring->state))) + return NETDEV_TX_BUSY; +#endif + + return ixgbe_xmit_frame_ring(skb, adapter, tx_ring); +} + +/** + * ixgbe_xmit_frame - Transmit a network frame on the ixgbe device + * @skb: Socket buffer containing the packet to transmit + * @netdev: Network device structure pointer + * + * This function is a wrapper for transmitting a network frame on the ixgbe + * network adapter. It calls the internal `__ixgbe_xmit_frame` function to + * handle the actual transmission process. The function is responsible for + * preparing the packet and invoking the lower-level transmission logic. + * + * Return: NETDEV_TX_OK on successful transmission. + */ +static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, + struct net_device *netdev) +{ + return __ixgbe_xmit_frame(skb, netdev, NULL); +} + +/** + * ixgbe_set_mac - Change the Ethernet address of the NIC + * @netdev: Network interface device structure pointer + * @p: Pointer to a sockaddr structure containing the new address + * + * This function changes the Ethernet (MAC) address of the ixgbe network + * adapter. It first validates the new address to ensure it is a valid + * Ethernet address. If valid, it updates the network device and hardware + * structures with the new address and sets the default MAC filter. + * + * Return: 0 on success, or a negative error code on failure, such as + * -EADDRNOTAVAIL if the address is invalid. + */ +static int ixgbe_set_mac(struct net_device *netdev, void *p) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + eth_hw_addr_set(netdev, addr->sa_data); + memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); + + ixgbe_mac_set_default_filter(adapter); + + return 0; +} + +#if defined(HAVE_NETDEV_STORAGE_ADDRESS) && defined(NETDEV_HW_ADDR_T_SAN) +/** + * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the device's address list + * @dev: Network interface device structure pointer + * + * This function adds the Storage Area Network (SAN) MAC address to the + * specified network device's address list. It first checks if the SAN MAC + * address is valid. If valid, it adds the address to the device's list and + * updates the SAN MAC VMDq pool selection. + * + * Return: 0 on success, or a non-zero error code on failure. + */ +static int ixgbe_add_sanmac_netdev(struct net_device *dev) +{ + int err = IXGBE_SUCCESS; + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + + if (is_valid_ether_addr(hw->mac.san_addr)) { + rtnl_lock(); + err = dev_addr_add(dev, hw->mac.san_addr, + NETDEV_HW_ADDR_T_SAN); + rtnl_unlock(); + + /* update SAN MAC vmdq pool selection */ + hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0)); + } + return err; +} + +/** + * ixgbe_del_sanmac_netdev - Remove the SAN MAC address from the device's address list + * @dev: Network interface device structure pointer + * + * This function removes the Storage Area Network (SAN) MAC address from the + * specified network device's address list. It first checks if the SAN MAC + * address is valid. If valid, it removes the address from the device's list. + * + * Return: 0 on success, or a non-zero error code on failure. + */ +static int ixgbe_del_sanmac_netdev(struct net_device *dev) +{ + int err = IXGBE_SUCCESS; + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_mac_info *mac = &adapter->hw.mac; + + if (is_valid_ether_addr(mac->san_addr)) { + rtnl_lock(); + err = dev_addr_del(dev, mac->san_addr, NETDEV_HW_ADDR_T_SAN); + rtnl_unlock(); + } + return err; +} + +#endif /* (HAVE_NETDEV_STORAGE_ADDRESS) && defined(NETDEV_HW_ADDR_T_SAN) */ + +static int ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, + u16 addr) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u16 value; + int rc; + + if (prtad != hw->phy.addr) + return -EINVAL; + + if (!hw->phy.ops.read_reg) + return -EOPNOTSUPP; + + rc = hw->phy.ops.read_reg(hw, addr, devad, &value); + if (!rc) + rc = value; + + return rc; +} + +static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad, + u16 addr, u16 value) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (prtad != hw->phy.addr) + return -EINVAL; + + if (!hw->phy.ops.write_reg) + return -EOPNOTSUPP; + + return hw->phy.ops.write_reg(hw, addr, devad, value); +} + +static int ixgbe_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, + int cmd) +{ + struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &ifr->ifr_data; + int prtad, devad, ret; + + prtad = (mii->phy_id & MDIO_PHY_ID_PRTAD) >> 5; + devad = (mii->phy_id & MDIO_PHY_ID_DEVAD); + + if (cmd == SIOCGMIIREG) { + ret = ixgbe_mdio_read(netdev, prtad, devad, mii->reg_num); + if (ret < 0) + return ret; + mii->val_out = ret; + return 0; + } else { + return ixgbe_mdio_write(netdev, prtad, devad, mii->reg_num, + mii->val_in); + } +} + +/** + * ixgbe_ioctl - Handle ioctl commands for the network device + * @netdev: Network device structure + * @ifr: Interface request structure + * @cmd: Ioctl command + * + * This function processes various ioctl commands for the specified network + * device. It supports hardware timestamping configuration, ethtool operations, + * bypass operations, and MII register access, depending on the command and + * available features. + * + * Return: 0 on success, or a negative error code if the command is not supported. + */ +static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ +#ifdef HAVE_PTP_1588_CLOCK + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +#endif + switch (cmd) { +#ifdef HAVE_PTP_1588_CLOCK +#ifdef SIOCGHWTSTAMP + case SIOCGHWTSTAMP: + return ixgbe_ptp_get_ts_config(adapter, ifr); +#endif + case SIOCSHWTSTAMP: + return ixgbe_ptp_set_ts_config(adapter, ifr); +#endif +#ifdef ETHTOOL_OPS_COMPAT + case SIOCETHTOOL: + return ethtool_ioctl(ifr); +#endif + case SIOCGMIIREG: + case SIOCSMIIREG: + return ixgbe_mii_ioctl(netdev, ifr, cmd); + default: + return -EOPNOTSUPP; + } +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * ixgbe_netpoll - Handle polling for network device without interrupts + * @netdev: Network device structure + * + * This function handles polling for the specified network device, allowing + * operations like netconsole to send packets without re-enabling interrupts. + * It checks if the interface is up and processes received packets using either + * MSI-X or legacy interrupt handling, depending on the device configuration. + */ +static void ixgbe_netpoll(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + /* if interface is down do nothing */ + if (test_bit(__IXGBE_DOWN, adapter->state)) + return; + + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + int i; + for (i = 0; i < adapter->num_q_vectors; i++) { + adapter->q_vector[i]->netpoll_rx = true; + ixgbe_msix_clean_rings(0, adapter->q_vector[i]); + adapter->q_vector[i]->netpoll_rx = false; + } + } else { + ixgbe_intr(0, adapter); + } +} +#endif /* CONFIG_NET_POLL_CONTROLLER */ + +/* ixgbe_validate_rtr - verify 802.1Qp to Rx packet buffer mapping is valid. + * @adapter: pointer to ixgbe_adapter + * @tc: number of traffic classes currently enabled + * + * Configure a valid 802.1Qp to Rx packet buffer mapping ie confirm + * 802.1Q priority maps to a packet buffer that exists. + */ +static void ixgbe_validate_rtr(struct ixgbe_adapter *adapter, u8 tc) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reg, rsave; + int i; + + /* 82598 have a static priority to TC mapping that can not + * be changed so no validation is needed. + */ + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC); + rsave = reg; + + for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { + u8 up2tc = IXGBE_RTRUP2TC_UP_MASK & + (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT)); + + /* If up2tc is out of bounds default to zero */ + if (up2tc > tc) + reg &= ~(IXGBE_RTRUP2TC_UP_MASK << (i * IXGBE_RTRUP2TC_UP_SHIFT)); + } + + if (reg != rsave) + IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg); + + return; +} + +/** + * ixgbe_set_prio_tc_map - Configure netdev prio tc map + * @adapter: Pointer to adapter struct + * + * Populate the netdev user priority to tc map + */ +static void ixgbe_set_prio_tc_map(struct ixgbe_adapter __maybe_unused *adapter) +{ +#ifdef HAVE_DCBNL_IEEE + struct net_device *dev = adapter->netdev; + struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; + struct ieee_ets *ets = adapter->ixgbe_ieee_ets; + u8 prio; + + for (prio = 0; prio < IXGBE_DCB_MAX_USER_PRIORITY; prio++) { + u8 tc = 0; + + if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) + tc = ixgbe_dcb_get_tc_from_up(dcb_cfg, 0, prio); + else if (ets) + tc = ets->prio_tc[prio]; + + netdev_set_prio_tc_map(dev, prio, tc); + } +#endif +} + +#ifdef NETIF_F_HW_TC +#ifdef HAVE_TC_SETUP_CLSU32 +static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter, + struct tc_cls_u32_offload *cls) +{ + u32 hdl = cls->knode.handle; + u32 uhtid = TC_U32_USERHTID(cls->knode.handle); + u32 loc = cls->knode.handle & 0xfffff; + int err = 0, i, j; + struct ixgbe_jump_table *jump = NULL; + + if (loc > IXGBE_MAX_HW_ENTRIES) + return -EINVAL; + + if ((uhtid != 0x800) && (uhtid >= IXGBE_MAX_LINK_HANDLE)) + return -EINVAL; + + /* Clear this filter in the link data it is associated with */ + if (uhtid != 0x800) { + jump = adapter->jump_tables[uhtid]; + if (!jump) + return -EINVAL; + if (!test_bit(loc - 1, jump->child_loc_map)) + return -EINVAL; + clear_bit(loc - 1, jump->child_loc_map); + } + + /* Check if the filter being deleted is a link */ + for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) { + jump = adapter->jump_tables[i]; + if (jump && jump->link_hdl == hdl) { + /* Delete filters in the hardware in the child hash + * table associated with this link + */ + for (j = 0; j < IXGBE_MAX_HW_ENTRIES; j++) { + if (!test_bit(j, jump->child_loc_map)) + continue; + spin_lock(&adapter->fdir_perfect_lock); + err = ixgbe_update_ethtool_fdir_entry(adapter, + NULL, + j + 1); + spin_unlock(&adapter->fdir_perfect_lock); + clear_bit(j, jump->child_loc_map); + } + /* Remove resources for this link */ + kfree(jump->input); + kfree(jump->mask); + kfree(jump); + adapter->jump_tables[i] = NULL; + return err; + } + } + + spin_lock(&adapter->fdir_perfect_lock); + err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, loc); + spin_unlock(&adapter->fdir_perfect_lock); + return err; +} + +#ifdef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV +static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter, + struct tc_cls_u32_offload *cls) +{ +#else +static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter, + __be16 protocol, + struct tc_cls_u32_offload *cls) +{ +#endif + u32 uhtid = TC_U32_USERHTID(cls->hnode.handle); + + if (uhtid >= IXGBE_MAX_LINK_HANDLE) + return -EINVAL; + + /* This ixgbe devices do not support hash tables at the moment + * so abort when given hash tables. + */ + if (cls->hnode.divisor > 0) + return -EINVAL; + + set_bit(uhtid - 1, &adapter->tables); + return 0; +} + +static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter, + struct tc_cls_u32_offload *cls) +{ + u32 uhtid = TC_U32_USERHTID(cls->hnode.handle); + + if (uhtid >= IXGBE_MAX_LINK_HANDLE) + return -EINVAL; + + clear_bit(uhtid - 1, &adapter->tables); + return 0; +} + +#ifdef CONFIG_NET_CLS_ACT +#ifdef HAVE_TCF_MIRRED_REDIRECT +static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex, + u8 *queue, u64 *action) +{ + unsigned int num_vfs = adapter->num_vfs, vf; + struct net_device *upper; + + /* redirect to a SRIOV VF */ + for (vf = 0; vf < num_vfs; ++vf) { + upper = pci_get_drvdata(adapter->vfinfo[vf].vfdev); + if (upper->ifindex == ifindex) { + if (adapter->num_rx_pools > 1) + *queue = vf * 2; + else + *queue = vf * adapter->num_rx_queues_per_pool; + + *action = vf + 1; + *action <<= ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF; + return 0; + } + } + return -EINVAL; +} +#endif + +static int parse_tc_actions(struct ixgbe_adapter *adapter, + struct tcf_exts *exts, u64 *action, u8 *queue) +{ + const struct tc_action *a; +#if defined(HAVE_TCF_EXTS_TO_LIST) + LIST_HEAD(actions); +#elif defined(HAVE_TCF_EXTS_FOR_EACH_ACTION) + int i; +#endif + +#ifdef HAVE_TCF_EXTS_HAS_ACTION + if (!tcf_exts_has_actions(exts)) +#else + if (tc_no_actions(exts)) +#endif + return -EINVAL; + +#if defined(HAVE_TCF_EXTS_TO_LIST) + tcf_exts_to_list(exts, &actions); + list_for_each_entry(a, &actions, list) { +#elif defined(HAVE_TCF_EXTS_FOR_EACH_ACTION) + tcf_exts_for_each_action(i, a, exts) { +#else + tc_for_each_action(a, exts) { +#endif + /* Drop action */ + if (is_tcf_gact_shot(a)) { + *action = IXGBE_FDIR_DROP_QUEUE; + *queue = IXGBE_FDIR_DROP_QUEUE; + return 0; + } + +#ifdef HAVE_TCF_MIRRED_REDIRECT + /* Redirect to a VF or a offloaded macvlan */ +#ifdef HAVE_TCF_MIRRED_EGRESS_REDIRECT + if (is_tcf_mirred_egress_redirect(a)) { +#else + if (is_tcf_mirred_redirect(a)) { +#endif +#ifdef HAVE_TCF_MIRRED_DEV + struct net_device *dev = tcf_mirred_dev(a); + + if (!dev) + return -EINVAL; + return handle_redirect_action(adapter, dev->ifindex, + queue, action); +#else + int ifindex = tcf_mirred_ifindex(a); + + return handle_redirect_action(adapter, ifindex, + queue, action); +#endif + } +#endif + return -EINVAL; + } + + return -EINVAL; +} +#else +static int parse_tc_actions(struct ixgbe_adapter *adapter, + struct tcf_exts *exts, u64 *action, u8 *queue) +{ + return -EINVAL; +} +#endif /* CONFIG_NET_CLS_ACT */ + +static int ixgbe_clsu32_build_input(struct ixgbe_fdir_filter *input, + union ixgbe_atr_input *mask, + struct tc_cls_u32_offload *cls, + struct ixgbe_mat_field *field_ptr, + struct ixgbe_nexthdr *nexthdr) +{ + int i, j, off; + __be32 val, m; + bool found_entry = false, found_jump_field = false; + + for (i = 0; i < cls->knode.sel->nkeys; i++) { + off = cls->knode.sel->keys[i].off; + val = cls->knode.sel->keys[i].val; + m = cls->knode.sel->keys[i].mask; + + for (j = 0; field_ptr[j].val; j++) { + if (field_ptr[j].off == off) { + field_ptr[j].val(input, mask, val, m); + input->filter.formatted.flow_type |= + field_ptr[j].type; + found_entry = true; + break; + } + } + if (nexthdr) { + if (nexthdr->off == cls->knode.sel->keys[i].off && + nexthdr->val == cls->knode.sel->keys[i].val && + nexthdr->mask == cls->knode.sel->keys[i].mask) + found_jump_field = true; + else + continue; + } + } + + if (nexthdr && !found_jump_field) + return -EINVAL; + + if (!found_entry) + return 0; + + mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK | + IXGBE_ATR_L4TYPE_MASK; + + if (input->filter.formatted.flow_type == IXGBE_ATR_FLOW_TYPE_IPV4) + mask->formatted.flow_type &= IXGBE_ATR_L4TYPE_IPV6_MASK; + + return 0; +} + +#ifdef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV +static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, + struct tc_cls_u32_offload *cls) +{ + __be16 protocol = cls->common.protocol; +#else +static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, + __be16 protocol, + struct tc_cls_u32_offload *cls) +{ +#endif + u32 loc = cls->knode.handle & 0xfffff; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_mat_field *field_ptr; + struct ixgbe_fdir_filter *input; + struct ixgbe_jump_table *jump; + union ixgbe_atr_input *mask; + u32 uhtid, link_uhtid; + int i, err = -EINVAL; + u8 queue; + + uhtid = TC_U32_USERHTID(cls->knode.handle); + link_uhtid = TC_U32_USERHTID(cls->knode.link_handle); + + /* At the moment cls_u32 jumps to network layer and skips past + * L2 headers. The canonical method to match L2 frames is to use + * negative values. However this is error prone at best but really + * just broken because there is no way to "know" what sort of hdr + * is in front of the network layer. Fix cls_u32 to support L2 + * headers when needed. + */ + if (protocol != htons(ETH_P_IP)) + return err; + + if (loc >= ((1024 << adapter->fdir_pballoc) - 2)) { + e_err(drv, "Location out of range\n"); + return err; + } + + /* cls u32 is a graph starting at root node 0x800. The driver tracks + * links and also the fields used to advance the parser across each + * link (e.g. nexthdr/eat parameters from 'tc'). This way we can map + * the u32 graph onto the hardware parse graph denoted in ixgbe_model.h + * To add support for new nodes update ixgbe_model.h parse structures + * this function _should_ be generic try not to hardcode values here. + */ + if (uhtid == 0x800) { + field_ptr = (adapter->jump_tables[0])->mat; + } else { + if (uhtid >= IXGBE_MAX_LINK_HANDLE) + return err; + if (!adapter->jump_tables[uhtid]) + return err; + field_ptr = (adapter->jump_tables[uhtid])->mat; + } + + if (!field_ptr) + return err; + + /* At this point we know the field_ptr is valid and need to either + * build cls_u32 link or attach filter. Because adding a link to + * a handle that does not exist is invalid and the same for adding + * rules to handles that don't exist. + */ + + if (link_uhtid) { + struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps; + + if (link_uhtid >= IXGBE_MAX_LINK_HANDLE) + return err; + + if (!test_bit(link_uhtid - 1, &adapter->tables)) + return err; + + /* Multiple filters as links to the same hash table are not + * supported. To add a new filter with the same next header + * but different match/jump conditions, create a new hash table + * and link to it. + */ + if (adapter->jump_tables[link_uhtid] && + (adapter->jump_tables[link_uhtid])->link_hdl) { + e_err(drv, "Link filter exists for link: %x\n", + link_uhtid); + return err; + } + + jump = kzalloc(sizeof(*jump), GFP_KERNEL); + input = kzalloc(sizeof(*input), GFP_KERNEL); + mask = kzalloc(sizeof(*mask), GFP_KERNEL); + if (!jump || !input || !mask) { + err = -ENOMEM; + goto err_out; + } + + for (i = 0; nexthdr[i].jump; i++) { + if (nexthdr[i].o != cls->knode.sel->offoff || + nexthdr[i].s != cls->knode.sel->offshift || + nexthdr[i].m != cls->knode.sel->offmask) + goto err_out; + + jump->input = input; + jump->mask = mask; + jump->link_hdl = cls->knode.handle; + + err = ixgbe_clsu32_build_input(input, mask, cls, + field_ptr, &nexthdr[i]); + if (!err) { + jump->mat = nexthdr[i].jump; + adapter->jump_tables[link_uhtid] = jump; + /* Ownership transferred, clear local pointers */ + jump = NULL; + input = NULL; + mask = NULL; + err = 0; + break; + } + } + + goto err_out; + } + + jump = NULL; /* save one allocation call */ + input = kzalloc(sizeof(*input), GFP_KERNEL); + mask = kzalloc(sizeof(*mask), GFP_KERNEL); + if (!input || !mask) { + err = -ENOMEM; + goto err_out; + } + + if ((uhtid != 0x800) && (adapter->jump_tables[uhtid])) { + if ((adapter->jump_tables[uhtid])->input) + memcpy(input, (adapter->jump_tables[uhtid])->input, + sizeof(*input)); + if ((adapter->jump_tables[uhtid])->mask) + memcpy(mask, (adapter->jump_tables[uhtid])->mask, + sizeof(*mask)); + + /* Lookup in all child hash tables if this location is already + * filled with a filter + */ + for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) { + struct ixgbe_jump_table *link = adapter->jump_tables[i]; + + if (link && (test_bit(loc - 1, link->child_loc_map))) { + e_err(drv, "Filter exists in location: %x\n", + loc); + err = -EINVAL; + goto err_out; + } + } + } + err = ixgbe_clsu32_build_input(input, mask, cls, field_ptr, NULL); + if (err) + goto err_out; + + err = parse_tc_actions(adapter, cls->knode.exts, &input->action, + &queue); + if (err < 0) + goto err_out; + + input->sw_idx = loc; + + spin_lock(&adapter->fdir_perfect_lock); + + if (hlist_empty(&adapter->fdir_filter_list)) { + memcpy(&adapter->fdir_mask, mask, sizeof(*mask)); + err = ixgbe_fdir_set_input_mask_82599(hw, mask, + adapter->cloud_mode); + if (err) + goto err_out_w_lock; + } else if (memcmp(&adapter->fdir_mask, mask, sizeof(*mask))) { + err = -EINVAL; + goto err_out_w_lock; + } + + ixgbe_atr_compute_perfect_hash_82599(&input->filter, mask); + err = ixgbe_fdir_write_perfect_filter_82599(hw, &input->filter, + input->sw_idx, queue, + adapter->cloud_mode); + if (!err) { + ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); + /* Ownership of input transferred to ethtool, clear local pointer */ + input = NULL; + } + spin_unlock(&adapter->fdir_perfect_lock); + + if ((uhtid != 0x800) && (adapter->jump_tables[uhtid])) + set_bit(loc - 1, (adapter->jump_tables[uhtid])->child_loc_map); + + kfree(mask); + kfree(input); + return err; + +err_out_w_lock: + spin_unlock(&adapter->fdir_perfect_lock); +err_out: + kfree(mask); + kfree(input); + kfree(jump); + return err; +} + +#ifdef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV +#ifdef HAVE_TCF_BLOCK +static int ixgbe_setup_tc_cls_u32(struct ixgbe_adapter *adapter, + struct tc_cls_u32_offload *cls_u32) +#else +static int ixgbe_setup_tc_cls_u32(struct net_device *dev, + struct tc_cls_u32_offload *cls_u32) +#endif /* HAVE_TCF_BLOCK */ +{ +#ifdef HAVE_TCF_BLOCK +#ifndef HAVE_TCF_MIRRED_DEV + if (cls_u32->common.chain_index) + return -EOPNOTSUPP; +#endif +#else + struct ixgbe_adapter *adapter = netdev_priv(dev); + + if (!is_classid_clsact_ingress(cls_u32->common.classid) || + cls_u32->common.chain_index) + return -EOPNOTSUPP; +#endif + + switch (cls_u32->command) { + case TC_CLSU32_NEW_KNODE: + case TC_CLSU32_REPLACE_KNODE: + return ixgbe_configure_clsu32(adapter, cls_u32); + case TC_CLSU32_DELETE_KNODE: + return ixgbe_delete_clsu32(adapter, cls_u32); + case TC_CLSU32_NEW_HNODE: + case TC_CLSU32_REPLACE_HNODE: + return ixgbe_configure_clsu32_add_hnode(adapter, cls_u32); + case TC_CLSU32_DELETE_HNODE: + return ixgbe_configure_clsu32_del_hnode(adapter, cls_u32); + default: + return -EOPNOTSUPP; + + } +} +#endif /* HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV */ +#endif /* HAVE_TC_SETUP_CLSU32 */ + +#ifdef HAVE_TCF_BLOCK +static int ixgbe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, + void *cb_priv) +{ + struct ixgbe_adapter *adapter = cb_priv; + +#ifdef HAVE_TCF_MIRRED_DEV + if (!tc_cls_can_offload_and_chain0(adapter->netdev, type_data)) +#else + if (!tc_can_offload(adapter->netdev)) +#endif + return -EOPNOTSUPP; + + switch (type) { +#ifdef HAVE_TC_SETUP_CLSU32 + case TC_SETUP_CLSU32: + return ixgbe_setup_tc_cls_u32(adapter, type_data); +#endif /* HAVE_TC_SETUP_CLSU32 */ + default: + return -EOPNOTSUPP; + } +} + +static LIST_HEAD(ixgbe_block_cb_list); + +#endif +#ifdef TC_MQPRIO_HW_OFFLOAD_MAX +static int ixgbe_setup_tc_mqprio(struct net_device *dev, + struct tc_mqprio_qopt *mqprio) +{ + mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; + return ixgbe_setup_tc(dev, mqprio->num_tc); +} +#endif + +#ifdef HAVE_TCF_BLOCK +#define IXGBE_SETUP_TC_DECLARE_ADAPTER +#endif /* HAVE_TCF_BLOCK */ + +#ifdef HAVE_TC_SETUP_CLSU32 +#ifndef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV +#define IXGBE_SETUP_TC_DECLARE_ADAPTER +#endif /* !HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV */ +#endif /* HAVE_TC_SETUP_CLSU32 */ + +#if defined(HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV) +static int +__ixgbe_setup_tc(struct net_device *dev, enum tc_setup_type type, + void *type_data) +#elif defined(HAVE_NDO_SETUP_TC_CHAIN_INDEX) +static int +__ixgbe_setup_tc(struct net_device *dev, __always_unused u32 handle, + u32 chain_index, __always_unused __be16 proto, + struct tc_to_netdev *tc) +#else +static int +__ixgbe_setup_tc(struct net_device *dev, __always_unused u32 handle, + __always_unused __be16 proto, struct tc_to_netdev *tc) +#endif +{ +#ifdef IXGBE_SETUP_TC_DECLARE_ADAPTER + struct ixgbe_adapter *adapter = netdev_priv(dev); +#endif +#ifndef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV + unsigned int type = tc->type; +#ifdef HAVE_NDO_SETUP_TC_CHAIN_INDEX + + if (chain_index) + return -EOPNOTSUPP; +#endif /* HAVE_NDO_SETUP_TC_CHAIN_INDEX */ +#ifdef HAVE_TC_SETUP_CLSU32 + + if (TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS) && + type == TC_SETUP_CLSU32) { + + switch (tc->cls_u32->command) { + case TC_CLSU32_NEW_KNODE: + case TC_CLSU32_REPLACE_KNODE: + return ixgbe_configure_clsu32(adapter, + proto, tc->cls_u32); + case TC_CLSU32_DELETE_KNODE: + return ixgbe_delete_clsu32(adapter, tc->cls_u32); + case TC_CLSU32_NEW_HNODE: + case TC_CLSU32_REPLACE_HNODE: + return ixgbe_configure_clsu32_add_hnode(adapter, proto, + tc->cls_u32); + case TC_CLSU32_DELETE_HNODE: + return ixgbe_configure_clsu32_del_hnode(adapter, + tc->cls_u32); + default: + return -EINVAL; + } + } +#endif /* HAVE_TC_SETUP_CLSU32 */ +#endif /* !HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV */ + + switch (type) { +#if defined(HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV) +#if defined(HAVE_TCF_BLOCK) + case TC_SETUP_BLOCK: + return flow_block_cb_setup_simple(type_data, + &ixgbe_block_cb_list, + ixgbe_setup_tc_block_cb, + adapter, adapter, true); +#else +#ifdef HAVE_TC_SETUP_CLSU32 + case TC_SETUP_CLSU32: + return ixgbe_setup_tc_cls_u32(dev, type_data); +#endif /* HAVE_TC_SETUP_CLSU32 */ +#endif /* HAVE_TCF_BLOCK */ +#endif /* HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV */ + case TC_SETUP_QDISC_MQPRIO: +#if defined(HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV) + return ixgbe_setup_tc_mqprio(dev, type_data); +#elif defined(TC_MQPRIO_HW_OFFLOAD_MAX) + return ixgbe_setup_tc_mqprio(dev, tc->mqprio); +#else + return ixgbe_setup_tc(dev, tc->tc); +#endif + default: + return -EOPNOTSUPP; + } +} + +#endif /* NETIF_F_HW_TC */ +/** + * ixgbe_setup_tc - Configure net_device for multiple traffic classes + * @dev: Net device to configure + * @tc: Number of traffic classes to enable + * + * This function configures the ixgbe network adapter to support multiple + * traffic classes (TCs). It checks the hardware capabilities and ensures + * that the requested number of TCs is within supported limits. The function + * reinitializes queues and interrupts to match packet buffer alignment and + * updates the device's configuration for Data Center Bridging (DCB) if + * applicable. It handles specific cases for different hardware types and + * features like XDP and macvlan offload. + * + * Return: 0 on success, or -EINVAL if the requested TCs are not supported. + */ +int ixgbe_setup_tc(struct net_device *dev, u8 tc) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + + /* Hardware supports up to 8 traffic classes */ + if (tc > adapter->dcb_cfg.num_tcs.pg_tcs) + return -EINVAL; + + if (tc && hw->mac.type == ixgbe_mac_82598EB && + tc < IXGBE_DCB_MAX_TRAFFIC_CLASS) + return -EINVAL; + + /* Hardware has to reinitialize queues and interrupts to + * match packet buffer alignment. Unfortunately, the + * hardware is not flexible enough to do this dynamically. + */ + if (netif_running(dev)) + ixgbe_close(dev); + else + ixgbe_reset(adapter); + + ixgbe_clear_interrupt_scheme(adapter); + + if (tc) { +#ifdef HAVE_XDP_SUPPORT + if (adapter->xdp_prog) { + e_warn(probe, "DCB is not supported with XDP\n"); + + ixgbe_init_interrupt_scheme(adapter); + if (netif_running(dev)) + ixgbe_open(dev); + return -EINVAL; + } +#endif /* IXGBE_XDP_ENABLED */ + + netdev_set_num_tc(dev, tc); + ixgbe_set_prio_tc_map(adapter); + + adapter->flags |= IXGBE_FLAG_DCB_ENABLED; + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + adapter->last_lfc_mode = adapter->hw.fc.requested_mode; + adapter->hw.fc.requested_mode = ixgbe_fc_none; + } + } else { + netdev_reset_tc(dev); + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + + adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; + + adapter->temp_dcb_cfg.pfc_mode_enable = false; + adapter->dcb_cfg.pfc_mode_enable = false; + } + + ixgbe_validate_rtr(adapter, tc); + + ixgbe_init_interrupt_scheme(adapter); + if (netif_running(dev)) + ixgbe_open(dev); + + return 0; +} + +#ifdef CONFIG_PCI_IOV +void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + rtnl_lock(); + ixgbe_setup_tc(netdev, netdev_get_num_tc(netdev)); + rtnl_unlock(); +} +#endif + +void ixgbe_do_reset(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); +} + +#ifdef HAVE_NDO_SET_FEATURES +/** + * ixgbe_fix_features - Adjust network device features + * @netdev: Network device structure + * @features: Desired features to be adjusted + * + * This function adjusts the network device features based on the current + * configuration and capabilities. It ensures that features like VLAN RX, + * LRO, and L2 offloads are enabled or disabled appropriately, considering + * factors such as DCB, RSC capability, XDP, and SR-IOV. + * + * Return: The adjusted set of features. + */ +#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT +static u32 ixgbe_fix_features(struct net_device *netdev, u32 features) +#else +static netdev_features_t ixgbe_fix_features(struct net_device *netdev, + netdev_features_t features) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +#if IS_ENABLED(CONFIG_DCB) + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) +#ifdef NETIF_F_HW_VLAN_CTAG_RX + features |= NETIF_F_HW_VLAN_CTAG_RX; +#else + features |= NETIF_F_HW_VLAN_RX; +#endif +#endif /* CONFIG_DCB */ + + /* If Rx checksum is disabled, then RSC/LRO should also be disabled */ + if (!(features & NETIF_F_RXCSUM)) + features &= ~NETIF_F_LRO; + + /* Turn off LRO if not RSC capable */ + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) + features &= ~NETIF_F_LRO; + + if (adapter->xdp_prog && (features & NETIF_F_LRO)) { + e_dev_err("LRO is not supported with XDP\n"); + features &= ~NETIF_F_LRO; + } + + return features; +} + +/** + * ixgbe_set_features - Update network device features + * @netdev: Network device structure pointer + * @features: New feature set for the device + * + * This function updates the network device's features, such as LRO, RSC, + * and Flow Director support. It checks for changes and may reset the device + * if necessary to apply new settings. It also handles specific hardware + * capabilities like UDP tunnel offloads. + * + * Return: 0 on success. + */ +#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT +static int ixgbe_set_features(struct net_device *netdev, u32 features) +#else +static int ixgbe_set_features(struct net_device *netdev, + netdev_features_t features) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool need_reset = false; + netdev_features_t changed = netdev->features ^ features; + + /* Make sure RSC matches LRO, reset if change */ + if (!(features & NETIF_F_LRO)) { + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + need_reset = true; + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + } else if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && + !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { + if (adapter->rx_itr_setting == 1 || + adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR) { + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + need_reset = true; + } else if (changed & NETIF_F_LRO) { + e_info(probe, "rx-usecs set too low, " + "disabling RSC\n"); + } + } + + /* + * Check if Flow Director n-tuple support or hw_tc support was + * enabled or disabled. If the state changed, we need to reset. + */ +#ifdef NETIF_F_HW_TC + if ((features & NETIF_F_NTUPLE) || (features & NETIF_F_HW_TC)) { +#else + if (features & NETIF_F_NTUPLE) { +#endif + /* turn off ATR, enable perfect filters and reset */ + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + need_reset = true; + + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + } else { + /* turn off perfect filters, enable ATR and reset */ + if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) + need_reset = true; + + adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + + /* We cannot enable ATR if VMDq is enabled */ + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED || + /* We cannot enable ATR if we have 2 or more tcs */ + netdev_get_num_tc(netdev) > 1 || + /* We cannot enable ATR if RSS is disabled */ + adapter->ring_feature[RING_F_RSS].limit <= 1 || + /* A sample rate of 0 indicates ATR disabled */ + !adapter->atr_sample_rate) + ; /* do nothing not supported */ + else /* otherwise supported and set the flag */ + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + } + + netdev->features = features; + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) || defined(HAVE_VXLAN_RX_OFFLOAD) + if (adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE && + features & NETIF_F_RXCSUM) { + if (!need_reset) + adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED; + } else { + u32 port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK; + + ixgbe_clear_udp_tunnel_port(adapter, port_mask); + } +#endif /* HAVE_UDP_ENC_RX_OFFLOAD || HAVE_VXLAN_RX_OFFLOAD */ + +#ifdef HAVE_UDP_ENC_RX_OFFLOAD + if (adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE && + features & NETIF_F_RXCSUM) { + if (!need_reset) + adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED; + } else { + u32 port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK; + + ixgbe_clear_udp_tunnel_port(adapter, port_mask); + } +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ + + if (need_reset) + ixgbe_do_reset(netdev); +#ifdef NETIF_F_HW_VLAN_CTAG_FILTER + else if (changed & (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_FILTER)) + ixgbe_set_rx_mode(netdev); +#endif +#ifdef NETIF_F_HW_VLAN_FILTER + else if (changed & (NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER)) + ixgbe_set_rx_mode(netdev); +#endif + return 0; + +} +#endif /* HAVE_NDO_SET_FEATURES */ + +#ifdef HAVE_UDP_ENC_RX_OFFLOAD +/** + * ixgbe_add_udp_tunnel_port - Get notifications about adding UDP tunnel ports + * @dev: The port's netdev + * @ti: Tunnel endpoint information + **/ +static void ixgbe_add_udp_tunnel_port(struct net_device *dev, + struct udp_tunnel_info *ti) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + __be16 port = ti->port; + u32 port_shift = 0; + u32 reg; + + if (ti->sa_family != AF_INET) + return; + + switch (ti->type) { + case UDP_TUNNEL_TYPE_VXLAN: + if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) + return; + + if (adapter->vxlan_port == port) + return; + + if (adapter->vxlan_port) { + netdev_info(dev, + "VXLAN port %d set, not adding port %d\n", + ntohs(adapter->vxlan_port), + ntohs(port)); + return; + } + + adapter->vxlan_port = port; + break; + case UDP_TUNNEL_TYPE_GENEVE: + if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)) + return; + + if (adapter->geneve_port == port) + return; + + if (adapter->geneve_port) { + netdev_info(dev, + "GENEVE port %d set, not adding port %d\n", + ntohs(adapter->geneve_port), + ntohs(port)); + return; + } + + port_shift = IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT; + adapter->geneve_port = port; + break; + default: + return; + } + + reg = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) | ntohs(port) << port_shift; + IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, reg); +} + +/** + * ixgbe_del_udp_tunnel_port - Get notifications about removing UDP tunnel ports + * @dev: The port's netdev + * @ti: Tunnel endpoint information + **/ +static void ixgbe_del_udp_tunnel_port(struct net_device *dev, + struct udp_tunnel_info *ti) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + u32 port_mask; + + if (ti->type != UDP_TUNNEL_TYPE_VXLAN && + ti->type != UDP_TUNNEL_TYPE_GENEVE) + return; + + if (ti->sa_family != AF_INET) + return; + + switch (ti->type) { + case UDP_TUNNEL_TYPE_VXLAN: + if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) + return; + + if (adapter->vxlan_port != ti->port) { + netdev_info(dev, "VXLAN port %d not found\n", + ntohs(ti->port)); + return; + } + + port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK; + break; + case UDP_TUNNEL_TYPE_GENEVE: + if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)) + return; + + if (adapter->geneve_port != ti->port) { + netdev_info(dev, "GENEVE port %d not found\n", + ntohs(ti->port)); + return; + } + + port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK; + break; + default: + return; + } + + ixgbe_clear_udp_tunnel_port(adapter, port_mask); + adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED; +} + +#ifdef HAVE_UDP_TUNNEL_NIC_INFO +/** + * ixgbe_udp_tunnel_set - Configure UDP tunnel settings for the ixgbe device + * @dev: Network device structure pointer + * @table: Table index for the UDP tunnel entry + * @entry: Entry index within the table + * @ti: UDP tunnel information structure + * + * This function configures UDP tunnel settings for the ixgbe network adapter. + * It checks if the device supports only IPv4 tunnels and sets the address + * family accordingly. It then adds the specified UDP tunnel port to the device. + * + * Return: 0 on success. + */ +static int ixgbe_udp_tunnel_set(struct net_device *dev, + unsigned int table, unsigned int entry, + struct udp_tunnel_info *ti) +{ + const struct udp_tunnel_nic_info *tni = dev->udp_tunnel_nic_info; + + if (tni->flags & UDP_TUNNEL_NIC_INFO_IPV4_ONLY) + ti->sa_family = AF_INET; + + ixgbe_add_udp_tunnel_port(dev, ti); + return 0; +} + +/** + * ixgbe_udp_tunnel_unset - Remove UDP tunnel settings from the ixgbe device + * @dev: Network device structure pointer + * @table: Table index for the UDP tunnel entry + * @entry: Entry index within the table + * @ti: UDP tunnel information structure + * + * This function removes UDP tunnel settings from the ixgbe network adapter. + * It checks if the device supports only IPv4 tunnels and sets the address + * family accordingly. It then deletes the specified UDP tunnel port from the device. + * + * Return: 0 on success. + */ +static int ixgbe_udp_tunnel_unset(struct net_device *dev, + unsigned int table, unsigned int entry, + struct udp_tunnel_info *ti) +{ + const struct udp_tunnel_nic_info *tni = dev->udp_tunnel_nic_info; + + if (tni->flags & UDP_TUNNEL_NIC_INFO_IPV4_ONLY) + ti->sa_family = AF_INET; + + ixgbe_del_udp_tunnel_port(dev, ti); + + return 0; +} + +static const struct udp_tunnel_nic_info ixgbe_udp_tunnels_x550 = { + .set_port = ixgbe_udp_tunnel_set, + .unset_port = ixgbe_udp_tunnel_unset, + .flags = UDP_TUNNEL_NIC_INFO_IPV4_ONLY, + .tables = { + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, }, + }, +}; +#endif +#elif defined(HAVE_VXLAN_RX_OFFLOAD) +/** + * ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up + * @dev: The port's netdev + * @sa_family: Socket Family that VXLAN is notifiying us about + * @port: New UDP port number that VXLAN started listening to + */ +static void ixgbe_add_vxlan_port(struct net_device *dev, sa_family_t sa_family, + __be16 port) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + + if (sa_family != AF_INET) + return; + + if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_ENABLE)) + return; + + if (adapter->vxlan_port == port) + return; + + if (adapter->vxlan_port) { + netdev_info(dev, + "Hit Max num of VXLAN ports, not adding port %d\n", + ntohs(port)); + return; + } + + adapter->vxlan_port = port; + IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, ntohs(port)); +} + +/** + * ixgbe_del_vxlan_port - Get notifications about VXLAN ports that go away + * @dev: The port's netdev + * @sa_family: Socket Family that VXLAN is notifying us about + * @port: UDP port number that VXLAN stopped listening to + */ +static void ixgbe_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, + __be16 port) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_ENABLE)) + return; + + if (sa_family != AF_INET) + return; + + if (adapter->vxlan_port != port) { + netdev_info(dev, "Port %d was not found, not deleting\n", + ntohs(port)); + return; + } + + ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK); + adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED; +} +#endif /* HAVE_VXLAN_RX_OFFLOAD */ + +#ifdef HAVE_NDO_GSO_CHECK +/** + * ixgbe_gso_check - Check if a packet is suitable for GSO + * @skb: Socket buffer containing the packet + * @dev: Network device structure (unused) + * + * This function checks if the given packet is suitable for Generic Segmentation + * Offload (GSO) by delegating the check to `vxlan_gso_check`. It determines + * whether the packet can be offloaded based on its characteristics. + * + * Return: true if the packet is suitable for GSO, false otherwise. + */ +static bool +ixgbe_gso_check(struct sk_buff *skb, __always_unused struct net_device *dev) +{ + return vxlan_gso_check(skb); +} +#endif /* HAVE_NDO_GSO_CHECK */ + +#ifdef HAVE_FDB_OPS +/** + * ixgbe_ndo_fdb_add - Add a forwarding database (FDB) entry + * @ndm: Netlink message structure + * @tb: Netlink attributes + * @dev: Network device structure + * @addr: MAC address to add to the FDB + * @vid: (Optional) VLAN ID + * @flags: Flags for the operation + * @notified: (Optional) Pointer to a boolean indicating if a notification was sent + * @extack: (Optional) Netlink extended acknowledgment structure + * + * This function adds an entry to the forwarding database (FDB) for the specified + * network device. It ensures that a unique filter can be provided for unicast + * and link-local addresses by checking the available resources. The function + * supports additional parameters based on kernel capabilities. + * + * Return: 0 on success, or -ENOMEM if there are insufficient resources. + */ +static int +ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, const unsigned char *addr, +#ifdef HAVE_NDO_FDB_ADD_VID + u16 vid, +#endif + u16 flags +#ifdef HAVE_NDO_FDB_ADD_NOTIFIED + , bool *notified +#endif +#ifdef HAVE_NDO_FDB_ADD_EXTACK + , struct netlink_ext_ack __always_unused *extack +#endif +) +{ + /* guarantee we can provide a unique filter for the unicast address */ + if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) { + struct ixgbe_adapter *adapter = netdev_priv(dev); + u16 pool = VMDQ_P(0); + + if (netdev_uc_count(dev) >= ixgbe_available_rars(adapter, pool)) + return -ENOMEM; + } + + return ndo_dflt_fdb_add(ndm, tb, dev, addr, +#ifdef HAVE_NDO_FDB_ADD_VID + vid, +#endif + flags); +} + +/** + * ixgbe_ndo_bridge_setlink - Set bridge link attributes for the network device + * @dev: Network device structure + * @nlh: Netlink message header + * @flags: (Optional) Flags for the operation + * @ext: (Optional) Netlink extended acknowledgment structure + * + * This function sets bridge link attributes for the specified network device. + * It processes netlink attributes to configure the bridge mode, supporting + * both VEPA and VEB modes. The function updates the adapter's configuration + * and reconfigures settings related to the bridge mode. It only operates if + * SR-IOV is enabled. + * + * Return: 0 on success, -EOPNOTSUPP if SR-IOV is not enabled, or -EINVAL if + * an invalid mode is specified. + */ +#ifdef HAVE_BRIDGE_ATTRIBS +#ifdef HAVE_NDO_BRIDGE_SETLINK_EXTACK +static int ixgbe_ndo_bridge_setlink(struct net_device *dev, + struct nlmsghdr *nlh, + __always_unused u16 flags, + struct netlink_ext_ack __always_unused *ext) +#elif defined(HAVE_NDO_BRIDGE_SET_DEL_LINK_FLAGS) +static int ixgbe_ndo_bridge_setlink(struct net_device *dev, + struct nlmsghdr *nlh, + __always_unused u16 flags) +#else +static int ixgbe_ndo_bridge_setlink(struct net_device *dev, + struct nlmsghdr *nlh) +#endif /* HAVE_NDO_BRIDGE_SETLINK_EXTACK */ +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct nlattr *attr, *br_spec; + int rem; + + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return -EOPNOTSUPP; + + br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); + + nla_for_each_nested(attr, br_spec, rem) { + __u16 mode; + + if (nla_type(attr) != IFLA_BRIDGE_MODE) + continue; + + mode = nla_get_u16(attr); + if (mode == BRIDGE_MODE_VEPA) { + adapter->flags |= IXGBE_FLAG_SRIOV_VEPA_BRIDGE_MODE; + } else if (mode == BRIDGE_MODE_VEB) { + adapter->flags &= ~IXGBE_FLAG_SRIOV_VEPA_BRIDGE_MODE; + } else { + return -EINVAL; + } + + adapter->bridge_mode = mode; + + /* re-configure settings related to bridge mode */ + ixgbe_configure_bridge_mode(adapter); + + e_info(drv, "enabling bridge mode: %s\n", + mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB"); + } + + return 0; +} + +/** + * ixgbe_ndo_bridge_getlink - Get bridge link information for the network device + * @skb: Socket buffer for the netlink message + * @pid: Netlink PID + * @seq: Netlink sequence number + * @dev: Network device structure + * @filter_mask: (Optional) Filter mask for bridge attributes + * @nlflags: (Optional) Netlink flags + * + * This function retrieves bridge link information for the specified network + * device. It checks if SR-IOV is enabled and uses the default bridge getlink + * handler to populate the netlink message with the bridge mode and other + * attributes. The function supports different parameter configurations based + * on kernel capabilities. + * + * Return: 0 on success, or a negative error code on failure. + */ +#ifdef HAVE_NDO_BRIDGE_GETLINK_NLFLAGS +static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, + struct net_device *dev, + u32 __maybe_unused filter_mask, + int nlflags) +#elif defined(HAVE_BRIDGE_FILTER) +static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, + struct net_device *dev, + u32 __always_unused filter_mask) +#else +static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, + struct net_device *dev) +#endif /* HAVE_NDO_BRIDGE_GETLINK_NLFLAGS */ +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + u16 mode; + + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return 0; + + mode = adapter->bridge_mode; +#ifdef HAVE_NDO_DFLT_BRIDGE_GETLINK_VLAN_SUPPORT + return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0, nlflags, + filter_mask, NULL); +#elif defined(HAVE_NDO_BRIDGE_GETLINK_NLFLAGS) + return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0, nlflags); +#elif defined(HAVE_NDO_FDB_ADD_VID) || \ + defined NDO_DFLT_BRIDGE_GETLINK_HAS_BRFLAGS + return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0); +#else + return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode); +#endif /* HAVE_NDO_BRIDGE_GETLINK_NLFLAGS */ +} +#endif /* HAVE_BRIDGE_ATTRIBS */ +#endif /* HAVE_FDB_OPS */ + +#ifdef HAVE_NDO_FEATURES_CHECK +/** + * ixgbe_features_check - Validate features for a given packet + * @skb: Socket buffer containing the packet + * @dev: Network device structure + * @features: Current set of features to validate + * + * This function checks if the given packet's headers can be supported by the + * network device's features. It ensures that the MAC and network header lengths + * are within the limits that can be described by a context descriptor. It also + * checks encapsulated packets and adjusts the features accordingly, especially + * for TSO and checksum offload capabilities. + * + * Return: The validated set of features that can be supported for the packet. + */ +#define IXGBE_MAX_TUNNEL_HDR_LEN 80 +#ifdef NETIF_F_GSO_PARTIAL +#define IXGBE_MAX_MAC_HDR_LEN 127 +#define IXGBE_MAX_NETWORK_HDR_LEN 511 + +static netdev_features_t +ixgbe_features_check(struct sk_buff *skb, struct net_device *dev, + netdev_features_t features) +{ + unsigned int network_hdr_len, mac_hdr_len; + + /* Make certain the headers can be described by a context descriptor */ + mac_hdr_len = skb_network_header(skb) - skb->data; + if (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN)) + return features & ~(NETIF_F_HW_CSUM | + NETIF_F_SCTP_CRC | + NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_TSO | + NETIF_F_TSO6); + + network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); + if (unlikely(network_hdr_len > IXGBE_MAX_NETWORK_HDR_LEN)) + return features & ~(NETIF_F_HW_CSUM | + NETIF_F_SCTP_CRC | + NETIF_F_TSO | + NETIF_F_TSO6); + + /* We can only support IPV4 TSO in tunnels if we can mangle the + * inner IP ID field, so strip TSO if MANGLEID is not supported. + */ + if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID)) + features &= ~NETIF_F_TSO; + + return features; +} +#else +static netdev_features_t +ixgbe_features_check(struct sk_buff *skb, struct net_device *dev, + netdev_features_t features) +{ + if (!skb->encapsulation) + return features; + + if (unlikely(skb_inner_mac_header(skb) - skb_transport_header(skb) > + IXGBE_MAX_TUNNEL_HDR_LEN)) + return features & ~NETIF_F_CSUM_MASK; + + return features; +} +#endif /* NETIF_F_GSO_PARTIAL */ +#endif /* HAVE_NDO_FEATURES_CHECK */ + +void ixgbe_xdp_ring_update_tail(struct ixgbe_ring *ring) +{ + /* Force memory writes to complete before letting h/w know there + * are new descriptors to fetch. + */ + wmb(); + writel(ring->next_to_use, ring->tail); +} + +void ixgbe_xdp_ring_update_tail_locked(struct ixgbe_ring *ring) +{ + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_lock(&ring->tx_lock); + ixgbe_xdp_ring_update_tail(ring); + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_unlock(&ring->tx_lock); +} + +#ifdef HAVE_XDP_SUPPORT +static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog) +{ + int i, frame_size = dev->mtu + IXGBE_PKT_HDR_PAD; + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct bpf_prog *old_prog; + bool need_reset; + + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + return -EINVAL; + + /* verify ixgbe ring attributes are sufficient for XDP */ + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + + if (ring_is_rsc_enabled(ring)) + return -EINVAL; + + if (frame_size > ixgbe_rx_bufsz(ring)) + return -EINVAL; + } + + old_prog = xchg(&adapter->xdp_prog, prog); + need_reset = (!!prog != !!old_prog); + + /* If transitioning XDP modes reconfigure rings */ + if (need_reset) { + int err = ixgbe_setup_tc(dev, netdev_get_num_tc(dev)); + + if (err) { + rcu_assign_pointer(adapter->xdp_prog, old_prog); + return -EINVAL; + } + if (!prog) + xdp_features_clear_redirect_target(dev); + } else { + for (i = 0; i < adapter->num_rx_queues; i++) + xchg(&adapter->rx_ring[i]->xdp_prog, adapter->xdp_prog); + } + + if (old_prog) + bpf_prog_put(old_prog); + + if (need_reset && prog) { +#ifdef HAVE_AF_XDP_ZC_SUPPORT + /* Kick start the NAPI context if there is an AF_XDP socket open + * on that queue id. This so that receiving will start. + */ + for (i = 0; i < adapter->num_rx_queues; i++) + if (adapter->xdp_ring[i]->xsk_pool) +#ifdef HAVE_NDO_XSK_WAKEUP + (void)ixgbe_xsk_wakeup(adapter->netdev, i, + XDP_WAKEUP_RX); +#else + (void)ixgbe_xsk_async_xmit(adapter->netdev, i); +#endif +#endif + xdp_features_set_redirect_target(dev, true); + } + + return 0; +} + +/** + * ixgbe_xdp - Handle XDP (eXpress Data Path) operations for the ixgbe device + * @dev: Network device structure pointer + * @xdp: XDP or netdev_bpf structure containing XDP command and data + * + * This function processes XDP-related commands for the ixgbe network adapter. + * It supports setting up XDP programs, querying attached XDP programs, and + * configuring AF_XDP zero-copy socket pools. The function handles different + * commands based on the `xdp->command` field and performs the appropriate + * setup or query operation. + * + * Return: 0 on success, or a negative error code on failure. + */ +#ifdef HAVE_NDO_BPF +static int ixgbe_xdp(struct net_device *dev, struct netdev_bpf *xdp) +#else +static int ixgbe_xdp(struct net_device *dev, struct netdev_xdp *xdp) +#endif +{ +#if defined(HAVE_XDP_QUERY_PROG) || defined(HAVE_AF_XDP_ZC_SUPPORT) + struct ixgbe_adapter *adapter = netdev_priv(dev); +#endif + + switch (xdp->command) { + case XDP_SETUP_PROG: + return ixgbe_xdp_setup(dev, xdp->prog); +#ifdef HAVE_XDP_QUERY_PROG + case XDP_QUERY_PROG: +#ifndef NO_NETDEV_BPF_PROG_ATTACHED + xdp->prog_attached = !!(adapter->xdp_prog); +#endif /* !NO_NETDEV_BPF_PROG_ATTACHED */ + xdp->prog_id = adapter->xdp_prog ? + adapter->xdp_prog->aux->id : 0; + return 0; +#endif +#ifdef HAVE_AF_XDP_ZC_SUPPORT + case XDP_SETUP_XSK_POOL: +#ifndef HAVE_NETDEV_BPF_XSK_POOL + return ixgbe_xsk_umem_setup(adapter, xdp->xsk.umem, + xdp->xsk.queue_id); +#else + return ixgbe_xsk_umem_setup(adapter, xdp->xsk.pool, + xdp->xsk.queue_id); +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ + default: + return -EINVAL; + } +} + +/** + * ixgbe_xdp_xmit - Transmit XDP frames on the ixgbe device + * @dev: Network device structure pointer + * @n: Number of XDP frames to transmit (used if + * HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS is defined) + * @frames: Array of XDP frame pointers (used if + * HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS is defined) + * @flags: Transmission flags (used if + * HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS is defined) + * @xdp: XDP buffer to transmit (used if + * HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS is not defined) + * + * This function handles the transmission of XDP (eXpress Data Path) frames + * for the ixgbe network adapter. It supports both bulk transmission with + * flags and single frame transmission, depending on the configuration. The + * function checks the device state and ring configuration before attempting + * to transmit frames. It also manages locking and updates the ring tail as + * needed. + * + * Return: Number of frames successfully transmitted, or a negative error + * code on failure. + */ +#ifdef HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS +static int ixgbe_xdp_xmit(struct net_device *dev, int n, + struct xdp_frame **frames, u32 flags) +#else +static int ixgbe_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_ring *ring; +#ifdef HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS + int drops = 0; + int i; +#else + int err; +#endif + + if (unlikely(test_bit(__IXGBE_DOWN, adapter->state))) + return -ENETDOWN; + +#ifdef HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) + return -EINVAL; +#endif + + /* During program transitions its possible adapter->xdp_prog is assigned + * but ring has not been configured yet. In this case simply abort xmit. + */ + ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL; + if (unlikely(!ring)) + return -ENXIO; + +#ifdef HAVE_AF_XDP_ZC_SUPPORT + if (unlikely(test_bit(__IXGBE_TX_DISABLED, &ring->state))) + return -ENXIO; +#endif + +#ifdef HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_lock(&ring->tx_lock); + + for (i = 0; i < n; i++) { + struct xdp_frame *xdpf = frames[i]; + int err; + + err = ixgbe_xmit_xdp_ring(ring, xdpf); + if (err != IXGBE_XDP_TX) { + xdp_return_frame_rx_napi(xdpf); + drops++; + } + } + + if (unlikely(flags & XDP_XMIT_FLUSH)) + ixgbe_xdp_ring_update_tail(ring); + + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_unlock(&ring->tx_lock); + + return n - drops; +#else /* HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS */ + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_lock(&ring->tx_lock); + err = ixgbe_xmit_xdp_ring(ring, xdp); + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_unlock(&ring->tx_lock); + + if (err != IXGBE_XDP_TX) + return -ENOSPC; + + return 0; +#endif /* HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS */ +} + +#ifndef NO_NDO_XDP_FLUSH +/** + * ixgbe_xdp_flush - Flush XDP transmit operations for the ixgbe device + * @dev: Network device structure pointer + * + * This function flushes pending XDP (eXpress Data Path) transmit operations + * for the ixgbe network adapter. It ensures that the device is still up + * before proceeding and updates the tail of the XDP ring to complete + * transmission. This is necessary to ensure that all XDP packets are + * properly transmitted before the function returns. + * + * Note: The function checks if the device is down and exits early if so. + */ +static void ixgbe_xdp_flush(struct net_device *dev) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_ring *ring; + + /* Its possible the device went down between xdp xmit and flush so + * we need to ensure device is still up. + */ + if (unlikely(test_bit(__IXGBE_DOWN, adapter->state))) + return; + + ring = adapter->xdp_prog ? adapter->xdp_ring[smp_processor_id()] : NULL; + if (unlikely(!ring)) + return; + + ixgbe_xdp_ring_update_tail(ring); + + return; +} +#endif /* !NO_NDO_XDP_FLUSH */ +#endif /* HAVE_XDP_SUPPORT */ +#ifdef HAVE_NET_DEVICE_OPS +static const struct net_device_ops ixgbe_netdev_ops = { + .ndo_open = ixgbe_open, + .ndo_stop = ixgbe_close, + .ndo_start_xmit = ixgbe_xmit_frame, +#ifdef HAVE_NETDEV_SELECT_QUEUE +#if IS_ENABLED(CONFIG_FCOE) + .ndo_select_queue = ixgbe_select_queue, +#else +#ifndef HAVE_MQPRIO + .ndo_select_queue = __netdev_pick_tx, +#endif +#endif /* CONFIG_FCOE */ +#endif /* HAVE_NETDEV_SELECT_QUEUE */ + .ndo_set_rx_mode = ixgbe_set_rx_mode, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = ixgbe_set_mac, +#ifdef HAVE_RHEL7_EXTENDED_MIN_MAX_MTU + .extended.ndo_change_mtu = ixgbe_change_mtu, +#else + .ndo_change_mtu = ixgbe_change_mtu, +#endif + .ndo_tx_timeout = ixgbe_tx_timeout, +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) + .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, +#endif +#ifdef HAVE_NDO_ETH_IOCTL + .ndo_eth_ioctl = ixgbe_ioctl, +#else + .ndo_do_ioctl = ixgbe_ioctl, +#endif /* HAVE_NDO_ETH_IOCTL */ +#ifdef HAVE_RHEL7_NET_DEVICE_OPS_EXT +/* RHEL7 requires this to be defined to enable extended ops. RHEL7 uses the + * function get_ndo_ext to retrieve offsets for extended fields from with the + * net_device_ops struct and ndo_size is checked to determine whether or not + * the offset is valid. + */ + .ndo_size = sizeof(const struct net_device_ops), +#endif +#ifdef IFLA_VF_MAX + .ndo_set_vf_mac = ixgbe_ndo_set_vf_mac, +#ifdef HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SET_VF_VLAN + .extended.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, +#else + .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, +#endif +#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE + .ndo_set_vf_rate = ixgbe_ndo_set_vf_bw, +#else + .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw, +#endif /* HAVE_NDO_SET_VF_MIN_MAX_TX_RATE */ +#if defined(HAVE_VF_SPOOFCHK_CONFIGURE) && IS_ENABLED(CONFIG_PCI_IOV) + .ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk, +#endif +#ifdef HAVE_NDO_SET_VF_LINK_STATE + .ndo_set_vf_link_state = ixgbe_ndo_set_vf_link_state, +#endif +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN + .ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en, +#endif +#ifdef HAVE_NDO_SET_VF_TRUST +#ifdef HAVE_RHEL7_NET_DEVICE_OPS_EXT + .extended.ndo_set_vf_trust = ixgbe_ndo_set_vf_trust, +#else + .ndo_set_vf_trust = ixgbe_ndo_set_vf_trust, +#endif /* HAVE_RHEL7_NET_DEVICE_OPS_EXT */ +#endif /* HAVE_NDO_SET_VF_TRUST */ + .ndo_get_vf_config = ixgbe_ndo_get_vf_config, +#endif /* IFLA_VF_MAX */ +#ifdef HAVE_VF_STATS + .ndo_get_vf_stats = ixgbe_ndo_get_vf_stats, +#endif /* HAVE_VF_STATS */ +#ifdef HAVE_NDO_GET_STATS64 + .ndo_get_stats64 = ixgbe_get_stats64, +#else + .ndo_get_stats = ixgbe_get_stats, +#endif /* HAVE_NDO_GET_STATS64 */ +#ifdef HAVE_SETUP_TC +#ifdef HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SETUP_TC + .extended.ndo_setup_tc_rh = __ixgbe_setup_tc, +#else +#ifdef NETIF_F_HW_TC + .ndo_setup_tc = __ixgbe_setup_tc, +#else + .ndo_setup_tc = ixgbe_setup_tc, +#endif /* NETIF_F_HW_TC */ +#endif /* HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SETUP_TC */ +#endif /* HAVE_SETUP_TC */ +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ixgbe_netpoll, +#endif +#ifndef HAVE_RHEL6_NET_DEVICE_EXTENDED +#ifdef HAVE_NDO_BUSY_POLL + .ndo_busy_poll = ixgbe_busy_poll_recv, +#endif /* HAVE_NDO_BUSY_POLL */ +#endif /* !HAVE_RHEL6_NET_DEVICE_EXTENDED */ +#if IS_ENABLED(CONFIG_FCOE) + .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get, +#ifdef HAVE_NETDEV_OPS_FCOE_DDP_TARGET + .ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target, +#endif + .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put, +#ifdef HAVE_NETDEV_OPS_FCOE_ENABLE + .ndo_fcoe_enable = ixgbe_fcoe_enable, + .ndo_fcoe_disable = ixgbe_fcoe_disable, +#endif +#ifdef HAVE_NETDEV_OPS_FCOE_GETWWN + .ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn, +#endif +#endif /* CONFIG_FCOE */ +#ifdef HAVE_VLAN_RX_REGISTER + .ndo_vlan_rx_register = &ixgbe_vlan_mode, +#endif +#ifdef HAVE_FDB_OPS + .ndo_fdb_add = ixgbe_ndo_fdb_add, +#ifndef USE_DEFAULT_FDB_DEL_DUMP + .ndo_fdb_del = ndo_dflt_fdb_del, + .ndo_fdb_dump = ndo_dflt_fdb_dump, +#endif +#ifdef HAVE_BRIDGE_ATTRIBS + .ndo_bridge_setlink = ixgbe_ndo_bridge_setlink, + .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink, +#endif /* HAVE_BRIDGE_ATTRIBS */ +#endif +#ifdef HAVE_UDP_ENC_RX_OFFLOAD +#ifdef HAVE_RHEL7_NETDEV_OPS_EXT_NDO_UDP_TUNNEL + .extended.ndo_udp_tunnel_add = ixgbe_add_udp_tunnel_port, + .extended.ndo_udp_tunnel_del = ixgbe_del_udp_tunnel_port, +#else +#ifndef HAVE_UDP_TUNNEL_NIC_INFO + .ndo_udp_tunnel_add = ixgbe_add_udp_tunnel_port, + .ndo_udp_tunnel_del = ixgbe_del_udp_tunnel_port, +#endif +#endif +#elif defined(HAVE_VXLAN_RX_OFFLOAD) + .ndo_add_vxlan_port = ixgbe_add_vxlan_port, + .ndo_del_vxlan_port = ixgbe_del_vxlan_port, +#endif /* HAVE_UDP_ENC_RX_OFFLOAD */ +#ifdef HAVE_NDO_GSO_CHECK + .ndo_gso_check = ixgbe_gso_check, +#endif /* HAVE_NDO_GSO_CHECK */ +#ifdef HAVE_NDO_FEATURES_CHECK + .ndo_features_check = ixgbe_features_check, +#endif /* HAVE_NDO_FEATURES_CHECK */ +#ifdef HAVE_XDP_SUPPORT +#ifdef HAVE_NDO_BPF + .ndo_bpf = ixgbe_xdp, +#else + .ndo_xdp = ixgbe_xdp, +#endif + .ndo_xdp_xmit = ixgbe_xdp_xmit, +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#ifdef HAVE_NDO_XSK_WAKEUP + .ndo_xsk_wakeup = ixgbe_xsk_wakeup, +#else + .ndo_xsk_async_xmit = ixgbe_xsk_async_xmit, +#endif +#endif +#ifndef NO_NDO_XDP_FLUSH + .ndo_xdp_flush = ixgbe_xdp_flush, +#endif /* !NO_NDO_XDP_FLUSH */ +#endif +#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT +}; + +/* RHEL6 keeps these operations in a separate structure */ +static const struct net_device_ops_ext ixgbe_netdev_ops_ext = { + .size = sizeof(struct net_device_ops_ext), +#endif /* HAVE_RHEL6_NET_DEVICE_OPS_EXT */ +#ifdef HAVE_NDO_SET_FEATURES + .ndo_set_features = ixgbe_set_features, + .ndo_fix_features = ixgbe_fix_features, +#endif /* HAVE_NDO_SET_FEATURES */ +}; +#endif /* HAVE_NET_DEVICE_OPS */ + +void ixgbe_assign_netdev_ops(struct net_device *dev) +{ +#ifdef HAVE_NET_DEVICE_OPS + dev->netdev_ops = &ixgbe_netdev_ops; +#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT + set_netdev_ops_ext(dev, &ixgbe_netdev_ops_ext); +#endif /* HAVE_RHEL6_NET_DEVICE_OPS_EXT */ +#else /* HAVE_NET_DEVICE_OPS */ + dev->open = &ixgbe_open; + dev->stop = &ixgbe_close; + dev->hard_start_xmit = &ixgbe_xmit_frame; + dev->get_stats = &ixgbe_get_stats; +#ifdef HAVE_SET_RX_MODE + dev->set_rx_mode = &ixgbe_set_rx_mode; +#endif + dev->set_multicast_list = &ixgbe_set_rx_mode; + dev->set_mac_address = &ixgbe_set_mac; + dev->change_mtu = &ixgbe_change_mtu; + dev->do_ioctl = &ixgbe_ioctl; +#ifdef HAVE_TX_TIMEOUT + dev->tx_timeout = &ixgbe_tx_timeout; +#endif +#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX) + dev->vlan_rx_register = &ixgbe_vlan_mode; + dev->vlan_rx_add_vid = &ixgbe_vlan_rx_add_vid; + dev->vlan_rx_kill_vid = &ixgbe_vlan_rx_kill_vid; +#endif +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = &ixgbe_netpoll; +#endif +#ifdef HAVE_NETDEV_SELECT_QUEUE +#if IS_ENABLED(CONFIG_FCOE) + dev->select_queue = &ixgbe_select_queue; +#else + dev->select_queue = &__netdev_pick_tx; +#endif +#endif /* HAVE_NETDEV_SELECT_QUEUE */ +#endif /* HAVE_NET_DEVICE_OPS */ + +#ifdef HAVE_RHEL6_NET_DEVICE_EXTENDED +#ifdef HAVE_NDO_BUSY_POLL + netdev_extended(dev)->ndo_busy_poll = ixgbe_busy_poll_recv; +#endif /* HAVE_NDO_BUSY_POLL */ +#endif /* HAVE_RHEL6_NET_DEVICE_EXTENDED */ + + dev->watchdog_timeo = 5 * HZ; +} + +/** + * ixgbe_wol_supported - Check whether device supports WoL + * @adapter: the adapter private structure + * @device_id: the device ID + * @subdevice_id: the subsystem device ID + * + * This function is used by probe and ethtool to determine + * which devices have WoL support + * + **/ +bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, + u16 subdevice_id) +{ + struct ixgbe_hw *hw = &adapter->hw; + u16 wol_cap = adapter->eeprom_cap & IXGBE_DEVICE_CAPS_WOL_MASK; + + /* WOL not supported on 82598 */ + if (hw->mac.type == ixgbe_mac_82598EB) + return false; + + /* check eeprom to see if WOL is enabled for X540 and newer */ + if (hw->mac.type >= ixgbe_mac_X540) { + if ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0_1) || + ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0) && + (hw->bus.func == 0))) + return true; + } + + /* WOL is determined based on device IDs for 82599 MACs */ + switch (device_id) { + case IXGBE_DEV_ID_82599_SFP: + /* Only these subdevices could supports WOL */ + switch (subdevice_id) { + case IXGBE_SUBDEV_ID_82599_560FLR: + case IXGBE_SUBDEV_ID_82599_LOM_SNAP6: + case IXGBE_SUBDEV_ID_82599_SFP_WOL0: + case IXGBE_SUBDEV_ID_82599_SFP_2OCP: + /* only support first port */ + if (hw->bus.func != 0) + break; + fallthrough; + case IXGBE_SUBDEV_ID_82599_SP_560FLR: + case IXGBE_SUBDEV_ID_82599_SFP: + case IXGBE_SUBDEV_ID_82599_RNDC: + case IXGBE_SUBDEV_ID_82599_ECNA_DP: + case IXGBE_SUBDEV_ID_82599_SFP_1OCP: + case IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM1: + case IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM2: + return true; + } + break; + case IXGBE_DEV_ID_82599EN_SFP: + /* Only these subdevices support WoL */ + switch (subdevice_id) { + case IXGBE_SUBDEV_ID_82599EN_SFP_OCP1: + return true; + } + break; + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + /* All except this subdevice support WOL */ + if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) + return true; + break; + case IXGBE_DEV_ID_82599_KX4: + return true; + default: + break; + } + + return false; +} +/** + * ixgbe_set_fw_version_E610 - Set FW version specifically on E610 adapters + * @adapter: the adapter private structure + * + * This function is used by probe and ethtool to determine the FW version to + * format to display. The FW version is taken from the EEPROM/NVM. + * + */ +static void ixgbe_set_fw_version_E610(struct ixgbe_adapter *adapter) +{ + struct ixgbe_orom_info *orom = &adapter->hw.flash.orom; + struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm; + + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), + "%x.%02x 0x%x %d.%d.%d", nvm->major, nvm->minor, + nvm->eetrack, orom->major, orom->build, orom->patch); +} + +/** + * ixgbe_refresh_fw_version - Refresh the firmware version for the adapter + * @adapter: Pointer to the ixgbe adapter structure + * + * This function refreshes the firmware version information for the specified + * adapter. It initializes the NVM (Non-Volatile Memory) and updates the + * firmware version specifically for E610 hardware. + */ +int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + + err = ixgbe_init_nvm(hw); + if (err) + return err; + + ixgbe_set_fw_version_E610(adapter); + + return 0; +} + +/** + * ixgbe_set_fw_version - Set FW version + * @adapter: the adapter private structure + * + * This function is used by probe and ethtool to determine the FW version to + * format to display. The FW version is taken from the EEPROM/NVM. + * + **/ +static void ixgbe_set_fw_version(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u16 eeprom_verh = 0, eeprom_verl = 0; + u16 offset = 0; + u32 etrack_id; + + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + ixgbe_set_fw_version_E610(adapter); + return; + } + /* Check for OEM Product Version block format */ + hw->eeprom.ops.read(hw, 0x1b, &offset); + + /* Make sure offset to OEM Product Version block is valid */ + if (!(offset == 0x0) && !(offset == 0xffff)) { + u16 mod_len = 0, cap = 0, prod_ver = 0, rel_num = 0; + u16 build, major, patch; + + /* Read product version block */ + hw->eeprom.ops.read(hw, offset, &mod_len); + hw->eeprom.ops.read(hw, offset + 0x1, &cap); + hw->eeprom.ops.read(hw, offset + 0x2, &prod_ver); + hw->eeprom.ops.read(hw, offset + 0x3, &rel_num); + + /* Only display OEM product version if valid block */ + if (mod_len == 0x3 && (cap & 0xf) == 0x0) { + major = prod_ver >> 8; + build = prod_ver & 0xff; + patch = rel_num; + + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), + "%x.%x.%x", major, build, patch); + return; + } + } + + /* + * Save off EEPROM version number and Option Rom version which + * together make a unique identify for the eeprom + */ + if (hw->eeprom.ops.read(hw, 0x2e, &eeprom_verh)) + eeprom_verh = NVM_VER_INVALID; + if (hw->eeprom.ops.read(hw, 0x2d, &eeprom_verl)) + eeprom_verl = NVM_VER_INVALID; + + /* The word order for the version format is determined by high order + * word bit 15. + */ + u32 lo = (eeprom_verh & NVM_ETK_VALID) ? eeprom_verl : eeprom_verh; + u32 hi = (eeprom_verh & NVM_ETK_VALID) ? eeprom_verh : eeprom_verl; + + /* Ensure LHS is u32 so shift occurs in unsigned 32-bit + * to avoid implicit u16 -> int promotion by compiler. + */ + etrack_id = (hi << NVM_ETK_SHIFT) | lo; + + /* Check for SCSI block version format */ + hw->eeprom.ops.read(hw, 0x17, &offset); + + /* Make sure offset to SCSI block is valid */ + if (!(offset == 0x0) && !(offset == 0xffff)) { + u16 eeprom_cfg_blkh = 0, eeprom_cfg_blkl = 0; + u16 build, major, patch; + + hw->eeprom.ops.read(hw, offset + 0x84, &eeprom_cfg_blkh); + hw->eeprom.ops.read(hw, offset + 0x83, &eeprom_cfg_blkl); + + /* Only display Option Rom if exist */ + if (eeprom_cfg_blkl && eeprom_cfg_blkh) { + major = eeprom_cfg_blkl >> 8; + /* Use u32 to avoid u16 -> int promotion in left shift */ + build = ((u32)eeprom_cfg_blkl << 8) | (eeprom_cfg_blkh >> 8); + patch = eeprom_cfg_blkh & 0x00ff; + + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), + "0x%08x, %d.%d.%d", etrack_id, major, build, + patch); + return; + } + } + + /* Set ETrack ID format */ + snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id), + "0x%08x", etrack_id); +} + +/** + * ixgbe_recovery_probe - handle FW recovery mode during probe + * @adapter: the adapter private structure + * + * Perform limited driver initialization when FW error is detected. + **/ +static int ixgbe_recovery_probe(struct ixgbe_adapter *adapter) +{ + bool disable_dev, devlink_registered = false; + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct ixgbe_hw *hw = &adapter->hw; + int err = -EIO; + + if (!ixgbe_is_mac_E6xx(hw->mac.type)) + goto clean_up_probe; + + ixgbe_init_aci(hw); + + err = ixgbe_init_nvm(&adapter->hw); + if (err) + goto shutdown_aci; + + timer_setup(&adapter->service_timer, ixgbe_service_timer, 0); + INIT_WORK(&adapter->service_task, ixgbe_recovery_service_task); + set_bit(__IXGBE_SERVICE_INITED, adapter->state); + clear_bit(__IXGBE_SERVICE_SCHED, adapter->state); + + if (hw->mac.ops.get_bus_info) + hw->mac.ops.get_bus_info(hw); + + pci_set_drvdata(pdev, adapter); + /* We are creating devlink interface so NIC can be managed, + * e.g. new NVM image loaded + */ + ixgbe_devlink_register_port(adapter); +#ifdef HAVE_SET_NETDEV_DEVLINK_PORT + SET_NETDEV_DEVLINK_PORT(adapter->netdev, + &adapter->devlink_port); +#else /* !HAVE_SET_NETDEV_DEVLINK_PORT */ + devlink_port_type_eth_set(&adapter->devlink_port, + adapter->netdev); +#endif /* HAVE_SET_NETDEV_DEVLINK_PORT */ + +#ifdef HAVE_PCI_ERS + /* + * call save state here in standalone driver because it relies on + * adapter struct to exist, and needs to call netdev_priv + */ + pci_save_state(pdev); + +#endif +#ifndef HAVE_DEVLINK_PARAMS_PUBLISH + /* for old kernels, prior to auto-publish of devlink params, + * API has required a call to devlink_register() prior to + * registering params. API has changed to be the other way + * around at the same moment that explicit param + * publishing was deprecated. + * Some older kernels have backported the removal of param publishing + * but not the reversing of register order. Because of that, we need + * to check if devlink->dev was properly allocated before registering + * params to avoid segfaults. + */ + if (!devlink_to_dev(adapter->devlink)) { + ixgbe_devlink_register(adapter); + devlink_registered = true; + } +#else /* HAVE_DEVLINK_PARAMS_PUBLISH */ + ixgbe_devlink_register(adapter); +#endif /* HAVE_DEVLINK_PARAMS_PUBLISH */ + err = ixgbe_devlink_register_params(adapter); + if (err) + goto unregister_devlink; + ixgbe_devlink_init_regions(adapter); + +#ifndef HAVE_DEVLINK_PARAMS_PUBLISH + if (!devlink_registered) { + ixgbe_devlink_register(adapter); + devlink_registered = true; + } +#endif /* !HAVE_DEVLINK_PARAMS_PUBLISH */ + + return 0; +unregister_devlink: + ixgbe_devlink_unregister_port(adapter); + if (devlink_registered) + ixgbe_devlink_unregister(adapter); +shutdown_aci: + ixgbe_shutdown_aci(&adapter->hw); + devlink_free(adapter->devlink); +clean_up_probe: + ixgbe_release_hw_control(adapter); + disable_dev = !test_and_set_bit(__IXGBE_DISABLED, adapter->state); + free_netdev(netdev); + pci_release_mem_regions(pdev); + if (disable_dev) + pci_disable_device(pdev); + return err; +} + +/** + * ixgbe_probe - Device Initialization Routine + * @pdev: PCI device information struct + * @ent: entry in ixgbe_pci_tbl + * + * Returns 0 on success, negative on failure + * + * ixgbe_probe initializes an adapter identified by a pci_dev structure. + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur. + **/ +#ifdef HAVE_CONFIG_HOTPLUG +static int __devinit ixgbe_probe(struct pci_dev *pdev, + const struct pci_device_id __always_unused *ent) +#else +static int ixgbe_probe(struct pci_dev *pdev, + const struct pci_device_id __always_unused *ent) +#endif +{ + struct ixgbe_adapter *adapter = NULL; + struct net_device *netdev = NULL; + struct ixgbe_hw *hw = NULL; + static int cards_found; + int err, pci_using_dac; + char *info_string; + u8 part_str[IXGBE_PBANUM_LENGTH]; + enum ixgbe_mac_type mac_type = ixgbe_mac_unknown; +#ifdef HAVE_TX_MQ + unsigned int indices = MAX_TX_QUEUES; +#endif /* HAVE_TX_MQ */ + bool disable_dev = false; +#if IS_ENABLED(CONFIG_FCOE) + u16 device_caps; +#endif +#ifndef NETIF_F_GSO_PARTIAL +#ifdef HAVE_NDO_SET_FEATURES +#ifndef HAVE_RHEL6_NET_DEVICE_OPS_EXT + netdev_features_t hw_features; +#else + u32 hw_features; +#endif +#endif +#endif /* NETIF_F_GSO_PARTIAL */ + int i; + + err = pci_enable_device_mem(pdev); + if (err) + return err; + + if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && + !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { + pci_using_dac = 1; + } else { + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (err) { + err = dma_set_coherent_mask(&pdev->dev, + DMA_BIT_MASK(32)); + if (err) { + dev_err(&pdev->dev, "No usable DMA " + "configuration, aborting\n"); + goto err_dma; + } + } + pci_using_dac = 0; + } + + err = pci_request_mem_regions(pdev, ixgbe_driver_name); + if (err) { + dev_err(&pdev->dev, + "pci_request_selected_regions failed 0x%x\n", err); + goto err_pci_reg; + } + + /* + * The mac_type is needed before we have the adapter is set up + * so rather than maintain two devID -> MAC tables we dummy up + * an ixgbe_hw stuct and use ixgbe_set_mac_type. + */ + hw = vmalloc(sizeof(struct ixgbe_hw)); + if (!hw) { + pr_info("Unable to allocate memory for early mac " + "check\n"); + } else { + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + ixgbe_set_mac_type(hw); + mac_type = hw->mac.type; + vfree(hw); + } + + /* + * Workaround of Silicon errata on 82598. Disable LOs in the PCI switch + * port to which the 82598 is connected to prevent duplicate + * completions caused by LOs. We need the mac type so that we only + * do this on 82598 devices, ixgbe_set_mac_type does this for us if + * we set it's device ID. + */ + if (mac_type == ixgbe_mac_82598EB) + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + +#ifdef HAVE_PCI_ENABLE_PCIE_ERROR_REPORTING + pci_enable_pcie_error_reporting(pdev); +#endif /* HAVE_PCI_ENABLE_PCIE_ERROR_REPORTING */ + + pci_set_master(pdev); + +#ifdef HAVE_TX_MQ + if (mac_type == ixgbe_mac_82598EB) { +#if IS_ENABLED(CONFIG_DCB) + indices = IXGBE_MAX_DCB_INDICES * 4; +#else /* CONFIG_DCB */ + indices = IXGBE_MAX_RSS_INDICES; +#endif /* !CONFIG_DCB */ + } + + if (ixgbe_is_mac_E6xx(mac_type)) + indices = IXGBE_MAX_RSS_INDICES_E610; + + netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices); +#else /* HAVE_TX_MQ */ + netdev = alloc_etherdev(sizeof(struct ixgbe_adapter)); +#endif /* HAVE_TX_MQ */ + + if (!netdev) { + err = -ENOMEM; + goto err_alloc_etherdev; + } + + SET_MODULE_OWNER(netdev); + SET_NETDEV_DEV(netdev, &pdev->dev); + + adapter = netdev_priv(netdev); + +#ifdef HAVE_TX_MQ +#ifndef HAVE_NETDEV_SELECT_QUEUE + adapter->indices = indices; +#endif +#endif + adapter->netdev = netdev; + adapter->pdev = pdev; + hw = &adapter->hw; + hw->back = adapter; + adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1; + + hw->hw_addr = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + adapter->io_addr = hw->hw_addr; + if (!hw->hw_addr) { + err = -EIO; + goto err_ioremap; + } + if (ixgbe_is_mac_E6xx(mac_type)) { + struct ixgbe_adapter **padapter = NULL; + + padapter = ixgbe_allocate_devlink(adapter); + if (!padapter) { + err = -ENOMEM; + goto err_alloc_devlink; + } + } + + ixgbe_assign_netdev_ops(netdev); + + strscpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); + + adapter->bd_number = cards_found; + + ixgbe_get_hw_control(adapter); + /* setup the private structure */ + err = ixgbe_sw_init(adapter); + if (err) + goto err_sw_init; + + if (ixgbe_check_fw_error(adapter)) + return ixgbe_recovery_probe(adapter); + + if (ixgbe_is_mac_E6xx(mac_type)) { + u32 status; + + ixgbe_init_aci(hw); + + status = ixgbe_init_nvm(&adapter->hw); + if (status) + pr_err("ixgbe_init_nvm failed %d\n", status); + + status = ixgbe_get_caps(&adapter->hw); + if (status) + pr_err("ixgbe_get_caps failed %d\n", status); + + status = ixgbe_aci_get_fw_ver(hw); + if (status) + pr_err("ixgbe_aci_get_fw_ver failed %d\n", status); + } + + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + adapter->flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF; + + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + if (adapter->flags2 & IXGBE_FLAG2_FWLOG_CAPABLE) + ixgbe_fwlog_set_support_ena(hw); + + if (hw->fwlog_support_ena) { + if (ixgbe_pf_fwlog_init(adapter)) { + dev_err(&pdev->dev, "failed to initialize FW logging 0x%x\n", + err); + adapter->flags2 &= ~IXGBE_FLAG2_FWLOG_CAPABLE; + hw->fwlog_support_ena = false; + } + } + } + +#if defined(HAVE_UDP_ENC_RX_OFFLOAD) && defined(HAVE_UDP_TUNNEL_NIC_INFO) + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_E610: + netdev->udp_tunnel_nic_info = &ixgbe_udp_tunnels_x550; + break; + default: + break; + } +#endif + /* Make sure the SWFW semaphore is in a valid state */ + if (hw->mac.ops.init_swfw_sync) + hw->mac.ops.init_swfw_sync(hw); + + /* Make it possible the adapter to be woken up via WOL */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); + break; + default: + break; + } + + /* + * If we have a fan, this is as early we know, warn if we + * have had a failure. + */ + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) { + u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (esdp & IXGBE_ESDP_SDP1) + e_crit(probe, "Fan has stopped, replace the adapter\n"); + } + + /* + * check_options must be called before setup_link to set up + * hw->fc completely + */ + ixgbe_check_options(adapter); + + /* reset_hw fills in the perm_addr as well */ + hw->phy.reset_if_overtemp = true; + err = hw->mac.ops.reset_hw(hw); + hw->phy.reset_if_overtemp = false; + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + e_dev_err("failed to load because an unsupported SFP+ or QSFP " + "module type was detected.\n"); + e_dev_err("Reload the driver after installing a supported " + "module.\n"); + goto err_sw_init; + } else if (err && err != IXGBE_ERR_SFP_NOT_PRESENT) { + e_dev_err("HW Init failed: %d\n", err); + goto err_sw_init; + } + +#ifdef CONFIG_PCI_IOV +#if defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE) + if (adapter->max_vfs > 0) { + e_dev_warn("Enabling SR-IOV VFs using the max_vfs module parameter is deprecated.\n"); + e_dev_warn("Please use the pci sysfs interface instead. Ex:\n"); + e_dev_warn("echo '%d' > /sys/bus/pci/devices/%04x:%02x:%02x.%1x/sriov_numvfs\n", + adapter->max_vfs, + pci_domain_nr(pdev->bus), + pdev->bus->number, + PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); + } + +#endif + if (adapter->flags & IXGBE_FLAG_SRIOV_CAPABLE) { + pci_sriov_set_totalvfs(pdev, IXGBE_MAX_VFS_DRV_LIMIT); + ixgbe_enable_sriov(adapter); + } + +#endif /* CONFIG_PCI_IOV */ + +#ifdef NETIF_F_GSO_PARTIAL + /* keep |= here to avoid conflict with features set in param.c */ + netdev->features |= NETIF_F_SG | + NETIF_F_TSO | + NETIF_F_TSO6 | + NETIF_F_RXHASH | + NETIF_F_RXCSUM | + NETIF_F_HW_CSUM; + + netdev->gso_partial_features = IXGBE_GSO_PARTIAL_FEATURES; + netdev->features |= NETIF_F_GSO_PARTIAL | + IXGBE_GSO_PARTIAL_FEATURES; + + if (hw->mac.type >= ixgbe_mac_82599EB) + netdev->features |= NETIF_F_SCTP_CRC; + + /* copy netdev features into list of user selectable features */ + netdev->hw_features |= netdev->features | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_RXALL; + + if (hw->mac.type >= ixgbe_mac_82599EB) + netdev->hw_features |= NETIF_F_NTUPLE | + NETIF_F_HW_TC; + + if (pci_using_dac) + netdev->features |= NETIF_F_HIGHDMA; + + netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID; + netdev->hw_enc_features |= netdev->vlan_features; + netdev->mpls_features |= NETIF_F_HW_CSUM; + + /* set this bit last since it cannot be part of vlan_features */ + netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_TX; + + netdev->priv_flags |= IFF_UNICAST_FLT; + netdev->priv_flags |= IFF_SUPP_NOFCS; + + /* give us the option of enabling RSC/LRO later */ + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + netdev->hw_features |= NETIF_F_LRO; + +#else /* NETIF_F_GSO_PARTIAL */ + /* keep |= here to avoid conflict with features set in param.c */ + netdev->features |= NETIF_F_SG | + NETIF_F_IP_CSUM; + +#ifdef NETIF_F_IPV6_CSUM + netdev->features |= NETIF_F_IPV6_CSUM; +#endif + +#ifdef NETIF_F_HW_VLAN_CTAG_TX + netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_RX; +#endif + +#ifdef NETIF_F_HW_VLAN_TX + netdev->features |= NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_FILTER | + NETIF_F_HW_VLAN_RX; +#endif + netdev->features |= ixgbe_tso_features(); +#ifdef NETIF_F_RXHASH + netdev->features |= NETIF_F_RXHASH; +#endif /* NETIF_F_RXHASH */ + netdev->features |= NETIF_F_RXCSUM; + +#ifdef HAVE_NDO_SET_FEATURES + /* copy netdev features into list of user selectable features */ +#ifndef HAVE_RHEL6_NET_DEVICE_OPS_EXT + hw_features = netdev->hw_features; +#else + hw_features = get_netdev_hw_features(netdev); +#endif + hw_features |= netdev->features; + + /* give us the option of enabling RSC/LRO later */ + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + hw_features |= NETIF_F_LRO; + +#else +#ifdef NETIF_F_GRO + + /* this is only needed on kernels prior to 2.6.39 */ + netdev->features |= NETIF_F_GRO; +#endif /* NETIF_F_GRO */ +#endif /* HAVE_NDO_SET_FEATURES */ + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + netdev->features |= NETIF_F_SCTP_CSUM; +#ifdef HAVE_NDO_SET_FEATURES + hw_features |= NETIF_F_SCTP_CSUM | +#ifdef NETIF_F_HW_TC + NETIF_F_HW_TC | +#endif + NETIF_F_NTUPLE; +#endif + break; + default: + break; + } +#ifdef HAVE_NDO_SET_FEATURES +#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT + set_netdev_hw_features(netdev, hw_features); +#else + netdev->hw_features = hw_features; +#endif +#endif + +#ifdef HAVE_NETDEV_VLAN_FEATURES + netdev->vlan_features |= NETIF_F_SG | + NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_TSO | + NETIF_F_TSO6; + +#endif /* HAVE_NETDEV_VLAN_FEATURES */ +#ifdef HAVE_ENCAP_CSUM_OFFLOAD + netdev->hw_enc_features |= NETIF_F_SG; +#endif /* HAVE_ENCAP_CSUM_OFFLOAD */ +#ifdef HAVE_VXLAN_RX_OFFLOAD + if (adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE) { + netdev->hw_enc_features |= NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM; + } +#endif /* NETIF_F_GSO_PARTIAL */ + +#endif /* HAVE_VXLAN_RX_OFFLOAD */ + if (netdev->features & NETIF_F_LRO) { + if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && + ((adapter->rx_itr_setting == 1) || + (adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR))) { + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + } else if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { + e_dev_info("InterruptThrottleRate set too high, " + "disabling RSC\n"); + } + } +#ifdef IFF_UNICAST_FLT + netdev->priv_flags |= IFF_UNICAST_FLT; +#endif +#ifdef IFF_SUPP_NOFCS + netdev->priv_flags |= IFF_SUPP_NOFCS; +#endif + +#ifdef HAVE_XDP_SUPPORT + xdp_set_features_flag(netdev, NETDEV_XDP_ACT_BASIC | + NETDEV_XDP_ACT_REDIRECT | + NETDEV_XDP_ACT_XSK_ZEROCOPY); +#endif /* HAVE_XDP_SUPPORT */ + +#ifdef HAVE_NETDEVICE_MIN_MAX_MTU + /* MTU range: 68 - 9710 */ +#ifdef HAVE_RHEL7_EXTENDED_MIN_MAX_MTU + netdev->extended->min_mtu = ETH_MIN_MTU; + netdev->extended->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - + (ETH_HLEN + ETH_FCS_LEN); +#else + netdev->min_mtu = ETH_MIN_MTU; + netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN); +#endif + +#endif +#if IS_ENABLED(CONFIG_DCB) + if (adapter->flags & IXGBE_FLAG_DCB_CAPABLE) + netdev->dcbnl_ops = &ixgbe_dcbnl_ops; +#endif /* CONFIG_DCB */ +#if IS_ENABLED(CONFIG_FCOE) +#ifdef NETIF_F_FSO + if (adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) { + unsigned int fcoe_l; + + hw->mac.ops.get_device_caps(hw, &device_caps); + if (device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS) { + adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; + adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE; + e_dev_info("FCoE offload feature is not available. " + "Disabling FCoE offload feature\n"); + } else { + netdev->features |= NETIF_F_FSO | + NETIF_F_FCOE_CRC; +#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE + ixgbe_fcoe_ddp_enable(adapter); + adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; + netdev->features |= NETIF_F_FCOE_MTU; +#endif /* HAVE_NETDEV_OPS_FCOE_ENABLE */ + } + + fcoe_l = min_t(int, IXGBE_FCRETA_SIZE, num_online_cpus()); + adapter->ring_feature[RING_F_FCOE].limit = fcoe_l; + +#ifdef HAVE_NETDEV_VLAN_FEATURES +#ifdef HAVE_NETDEV_FCOE_MTU + netdev->vlan_features |= NETIF_F_FSO | + NETIF_F_FCOE_CRC; +#else + netdev->vlan_features |= NETIF_F_FSO | + NETIF_F_FCOE_CRC | + NETIF_F_FCOE_MTU; +#endif /* HAVE_NETDEV_FCOE_MTU */ +#endif /* HAVE_NETDEV_VLAN_FEATURES */ + } +#endif /* NETIF_F_FSO */ +#endif /* CONFIG_FCOE */ + if (pci_using_dac) { + netdev->features |= NETIF_F_HIGHDMA; +#ifdef HAVE_NETDEV_VLAN_FEATURES + netdev->vlan_features |= NETIF_F_HIGHDMA; +#endif /* HAVE_NETDEV_VLAN_FEATURES */ + } + + if (hw->eeprom.ops.validate_checksum && + (hw->eeprom.ops.validate_checksum(hw, NULL) < 0)) { + e_dev_err("The EEPROM Checksum Is Not Valid\n"); + err = -EIO; + goto err_sw_init; + } + + eth_hw_addr_set(netdev, hw->mac.perm_addr); +#ifdef ETHTOOL_GPERMADDR + memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len); +#endif + if (!is_valid_ether_addr(netdev->dev_addr)) { + e_dev_err("invalid MAC address\n"); + err = -EIO; + goto err_sw_init; + } + + /* Set hw->mac.addr to permanent MAC address */ + ether_addr_copy(hw->mac.addr, hw->mac.perm_addr); + ixgbe_mac_set_default_filter(adapter); + + timer_setup(&adapter->service_timer, ixgbe_service_timer, 0); + + if (IXGBE_REMOVED(hw->hw_addr)) { + err = -EIO; + goto err_aci_lock; + } + INIT_WORK(&adapter->service_task, ixgbe_service_task); + set_bit(__IXGBE_SERVICE_INITED, adapter->state); + clear_bit(__IXGBE_SERVICE_SCHED, adapter->state); + + err = ixgbe_init_interrupt_scheme(adapter); + if (err) + goto err_aci_lock; + + for (i = 0; i < adapter->num_xdp_queues; i++) + u64_stats_init(&adapter->xdp_ring[i]->syncp); + /* WOL not supported for all devices */ + adapter->wol = 0; + hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap); + if (ixgbe_wol_supported(adapter, pdev->device, pdev->subsystem_device)) + adapter->wol = IXGBE_WUFC_MAG; + + hw->wol_enabled = !!(adapter->wol); + + device_set_wakeup_enable(ixgbe_pf_to_dev(adapter), adapter->wol); + + ixgbe_set_fw_version(adapter); + + /* gets the number of resets after firmware update */ + if (adapter->hw.mac.type > ixgbe_mac_X550) + hw->fw_rst_cnt = IXGBE_READ_REG(hw, IXGBE_FWRESETCNT); + + /* reset the hardware with the new settings */ + err = hw->mac.ops.start_hw(hw); + if (err == IXGBE_ERR_EEPROM_VERSION) { + /* We are running on a pre-production device, log a warning */ + e_dev_warn("This device is a pre-production adapter/LOM. " + "Please be aware there may be issues associated " + "with your hardware. If you are experiencing " + "problems please contact your Intel or hardware " + "representative who provided you with this " + "hardware.\n"); + } else if (err == IXGBE_ERR_OVERTEMP) { + e_crit(drv, "%s\n", ixgbe_overheat_msg); + goto err_hw_init; + } else if (err) { + e_dev_err("HW init failed %d\n", err); + goto err_hw_init; + } + + if (ixgbe_pcie_from_parent(hw)) + ixgbe_get_parent_bus_info(hw); + else + if (hw->mac.ops.get_bus_info) + hw->mac.ops.get_bus_info(hw); + + strscpy(netdev->name, "eth%d", sizeof(netdev->name)); + pci_set_drvdata(pdev, adapter); + + if (ixgbe_is_mac_E6xx(mac_type)) { + ixgbe_devlink_register_port(adapter); +#ifdef HAVE_SET_NETDEV_DEVLINK_PORT + SET_NETDEV_DEVLINK_PORT(adapter->netdev, + &adapter->devlink_port); +#endif + } + + if (!(ixgbe_is_mac_E6xx(mac_type) && + (ixgbe_check_fw_error(adapter) || + ixgbe_check_fw_api_ver(adapter)))) { + err = register_netdev(netdev); + if (err) + goto err_register; + adapter->netdev_registered = true; + } +#ifndef HAVE_SET_NETDEV_DEVLINK_PORT + if (ixgbe_is_mac_E6xx(mac_type)) + devlink_port_type_eth_set(&adapter->devlink_port, + adapter->netdev); +#endif /* HAVE_SET_NETDEV_DEVLINK_PORT */ + +#ifdef HAVE_PCI_ERS + /* + * call save state here in standalone driver because it relies on + * adapter struct to exist, and needs to call netdev_priv + */ + pci_save_state(pdev); + +#endif + + /* power down the optics for 82599 SFP+ fiber */ + if (hw->mac.ops.disable_tx_laser) + hw->mac.ops.disable_tx_laser(hw); + + /* carrier off reporting is important to ethtool even BEFORE open */ + netif_carrier_off(netdev); + /* keep stopping all the transmit queues for older kernels */ + netif_tx_stop_all_queues(netdev); + +#if IS_ENABLED(CONFIG_DCA) + if (adapter->flags & IXGBE_FLAG_DCA_CAPABLE) { + err = dca_add_requester(&pdev->dev); + switch (err) { + case IXGBE_SUCCESS: + adapter->flags |= IXGBE_FLAG_DCA_ENABLED; + ixgbe_setup_dca(adapter); + break; + /* -19 is returned from the kernel when no provider is found */ + case -19: + e_info(rx_err, "No DCA provider found. Please " + "start ioatdma for DCA functionality.\n"); + break; + default: + e_info(probe, "DCA registration failed: %d\n", err); + break; + } + } +#endif + + /* print all messages at the end so that we use our eth%d name */ + ixgbe_check_minimum_link(adapter); + + /* First try to read PBA as a string */ + err = ixgbe_read_pba_string(hw, part_str, IXGBE_PBANUM_LENGTH); + if (err) + strscpy(part_str, "Unknown", IXGBE_PBANUM_LENGTH); + if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) + e_info(probe, "MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, hw->phy.sfp_type, part_str); + else + e_info(probe, "MAC: %d, PHY: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, part_str); + + e_dev_info("%02x:%02x:%02x:%02x:%02x:%02x\n", + netdev->dev_addr[0], netdev->dev_addr[1], + netdev->dev_addr[2], netdev->dev_addr[3], + netdev->dev_addr[4], netdev->dev_addr[5]); + +#define INFO_STRING_LEN 255 + info_string = kzalloc(INFO_STRING_LEN, GFP_KERNEL); + if (!info_string) { + e_err(probe, "allocation for info string failed\n"); + goto no_info_string; + } + snprintf(info_string, INFO_STRING_LEN, + "Enabled Features: RxQ: %d TxQ: %d", + adapter->num_rx_queues, adapter->num_tx_queues); +#if IS_ENABLED(CONFIG_FCOE) + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) + strlcat(info_string, " FCoE", INFO_STRING_LEN); +#endif + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) + strlcat(info_string, " FdirHash", INFO_STRING_LEN); + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + strlcat(info_string, " DCB", INFO_STRING_LEN); +#if IS_ENABLED(CONFIG_DCA) + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + strlcat(info_string, " DCA", INFO_STRING_LEN); +#endif + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + strlcat(info_string, " RSC", INFO_STRING_LEN); + if (adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_ENABLE) + strlcat(info_string, " vxlan_rx", INFO_STRING_LEN); + + /* end features printing */ + e_info(probe, "%s\n", info_string); + kfree(info_string); +no_info_string: +#ifdef CONFIG_PCI_IOV + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + int i; + for (i = 0; i < adapter->num_vfs; i++) + ixgbe_vf_configuration(pdev, (i | 0x10000000)); + } +#endif + + /* Initialize the LED link active for LED blink support */ + if (hw->mac.ops.init_led_link_act) + hw->mac.ops.init_led_link_act(hw); + + /* firmware requires blank numerical version */ + if (hw->mac.ops.set_fw_drv_ver) + hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, 0xFF, + sizeof(ixgbe_driver_version) - 1, + ixgbe_driver_version); + +#if defined(HAVE_NETDEV_STORAGE_ADDRESS) && defined(NETDEV_HW_ADDR_T_SAN) + /* add san mac addr to netdev */ + ixgbe_add_sanmac_netdev(netdev); + +#endif /* (HAVE_NETDEV_STORAGE_ADDRESS) && (NETDEV_HW_ADDR_T_SAN) */ + e_info(probe, "Intel(R) 10 Gigabit Network Connection\n"); + cards_found++; + +#ifdef IXGBE_SYSFS + if (ixgbe_sysfs_init(adapter)) + e_err(probe, "failed to allocate sysfs resources\n"); +#else +#ifdef IXGBE_PROCFS + if (ixgbe_procfs_init(adapter)) + e_err(probe, "failed to allocate procfs resources\n"); +#endif /* IXGBE_PROCFS */ +#endif /* IXGBE_SYSFS */ +#ifdef HAVE_IXGBE_DEBUG_FS + + ixgbe_dbg_adapter_init(adapter); +#endif /* HAVE_IXGBE_DEBUG_FS */ + + /* setup link for SFP devices with MNG FW, else wait for IXGBE_UP */ + if (ixgbe_mng_enabled(hw) && ixgbe_is_sfp(hw) && hw->mac.ops.setup_link) + hw->mac.ops.setup_link(hw, + IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL, + true); + + if (hw->mac.ops.setup_eee && + (adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE)) { + bool eee_enable = ixgbe_is_eee_enabled(adapter); + + hw->mac.ops.setup_eee(hw, eee_enable); + } + + if (ixgbe_is_mac_E6xx(mac_type)) { +#ifndef HAVE_DEVLINK_PARAMS_PUBLISH + bool need_register = true; + + /* for old kernels, prior to auto-publish of devlink params, + * API has required a call to devlink_register() prior to + * registering params. API has changed to be the other way + * around at the same moment that explicit param + * publishing was deprecated. + * Some older kernels have backported the removal of param publishing + * but not the reversing of register order. Because of that, we need + * to check if devlink->dev was properly allocated before registering + * params to avoid segfaults. + */ + if (!devlink_to_dev(adapter->devlink)) { + ixgbe_devlink_register(adapter); + need_register = false; + } +#else /* HAVE_DEVLINK_PARAMS_PUBLISH */ + ixgbe_devlink_register(adapter); +#endif /* HAVE_DEVLINK_PARAMS_PUBLISH */ + + err = ixgbe_devlink_register_params(adapter); + if (err) + goto err_devlink_register; + ixgbe_devlink_init_regions(adapter); + +#ifndef HAVE_DEVLINK_PARAMS_PUBLISH + if (need_register) + ixgbe_devlink_register(adapter); +#endif /* !HAVE_DEVLINK_PARAMS_PUBLISH */ + } + +#ifdef HAVE_PTP_1588_CLOCK + if (ixgbe_is_mac_E6xx(mac_type)) + ixgbe_ptp_init_e600(adapter); + +#endif /* HAVE_PTP_1588_CLOCK */ + return 0; + +err_devlink_register: +#ifdef HAVE_DEVLINK_PARAMS_PUBLISH + if (ixgbe_is_mac_E6xx(mac_type)) + ixgbe_devlink_unregister(adapter); +#endif /* HAVE_DEVLINK_PARAMS_PUBLISH */ +err_register: + if (ixgbe_is_mac_E6xx(mac_type)) + ixgbe_devlink_unregister_port(adapter); +err_hw_init: + ixgbe_clear_interrupt_scheme(adapter); + + if (ixgbe_is_mac_E6xx(mac_type) && hw->fwlog_support_ena) + ixgbe_pf_fwlog_deinit(adapter); + +err_aci_lock: + if (ixgbe_is_mac_E6xx(mac_type)) + ixgbe_shutdown_aci(&adapter->hw); +err_sw_init: + ixgbe_release_hw_control(adapter); +#ifdef CONFIG_PCI_IOV + ixgbe_disable_sriov(adapter); +#endif /* CONFIG_PCI_IOV */ + adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP; +#ifdef HAVE_TC_SETUP_CLSU32 + kfree(adapter->jump_tables[0]); +#endif + kfree(adapter->mac_table); + kfree(adapter->rss_key); + bitmap_free(adapter->af_xdp_zc_qps); + iounmap(adapter->io_addr); + if (ixgbe_is_mac_E6xx(mac_type)) + devlink_free(adapter->devlink); +err_alloc_devlink: + +err_ioremap: + disable_dev = !test_and_set_bit(__IXGBE_DISABLED, adapter->state); + free_netdev(netdev); +err_alloc_etherdev: + pci_release_mem_regions(pdev); +err_pci_reg: +err_dma: + if (!adapter || disable_dev) + pci_disable_device(pdev); + return err; +} + +/** + * ixgbe_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * ixgbe_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. The could be caused by a + * Hot-Plug event, or because the driver is going to be removed from + * memory. + **/ +#ifdef HAVE_CONFIG_HOTPLUG +static void __devexit ixgbe_remove(struct pci_dev *pdev) +#else +static void ixgbe_remove(struct pci_dev *pdev) +#endif +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev; + bool disable_dev; +#ifdef HAVE_TC_SETUP_CLSU32 + int i; +#endif + + /* if !adapter then we already cleaned up in probe */ + if (!adapter) + return; + +#ifdef HAVE_PTP_1588_CLOCK + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_ptp_release_e600(adapter); + +#endif /* HAVE_PTP_1588_CLOCK */ + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + ixgbe_devlink_unregister(adapter); + ixgbe_devlink_destroy_regions(adapter); + ixgbe_devlink_unregister_params(adapter); + } + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type) && + adapter->hw.fwlog_support_ena) + ixgbe_pf_fwlog_deinit(adapter); + + netdev = adapter->netdev; +#ifdef HAVE_IXGBE_DEBUG_FS + ixgbe_dbg_adapter_exit(adapter); + +#endif /*HAVE_IXGBE_DEBUG_FS */ + set_bit(__IXGBE_REMOVING, adapter->state); + cancel_work_sync(&adapter->service_task); + + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + ixgbe_shutdown_aci(&adapter->hw); +#if IS_ENABLED(CONFIG_DCA) + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { + adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; + dca_remove_requester(&pdev->dev); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, + IXGBE_DCA_CTRL_DCA_DISABLE); + } +#endif /* CONFIG_DCA */ + +#ifdef IXGBE_SYSFS + ixgbe_sysfs_exit(adapter); +#else +#ifdef IXGBE_PROCFS + ixgbe_procfs_exit(adapter); +#endif /* IXGBE_PROCFS */ +#endif /* IXGBE-SYSFS */ + +#if defined(HAVE_NETDEV_STORAGE_ADDRESS) && defined(NETDEV_HW_ADDR_T_SAN) + /* remove the added san mac */ + ixgbe_del_sanmac_netdev(netdev); + +#endif /* (HAVE_NETDEV_STORAGE_ADDRESS) && (NETDEV_HW_ADDR_T_SAN) */ + +#ifdef CONFIG_PCI_IOV + ixgbe_disable_sriov(adapter); +#endif /* CONFIG_PCI_IOV */ + if (adapter->netdev_registered) { + unregister_netdev(netdev); + adapter->netdev_registered = false; + } + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + ixgbe_devlink_unregister_port(adapter); + devlink_free(adapter->devlink); + } + +#if IS_ENABLED(CONFIG_FCOE) +#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE + ixgbe_fcoe_ddp_disable(adapter); +#endif +#endif /* CONFIG_FCOE */ + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_release_hw_control(adapter); + +#ifdef HAVE_DCBNL_IEEE + kfree(adapter->ixgbe_ieee_pfc); + kfree(adapter->ixgbe_ieee_ets); + +#endif + iounmap(adapter->io_addr); + pci_release_mem_regions(pdev); +#ifdef HAVE_TC_SETUP_CLSU32 + for (i = 0; i < IXGBE_MAX_LINK_HANDLE; i++) { + if (adapter->jump_tables[i]) { + kfree(adapter->jump_tables[i]->input); + kfree(adapter->jump_tables[i]->mask); + } + kfree(adapter->jump_tables[i]); + } +#endif /* HAVE_TC_SETUP_CLSU32 */ + kfree(adapter->mac_table); + kfree(adapter->rss_key); + bitmap_free(adapter->af_xdp_zc_qps); + + disable_dev = !test_and_set_bit(__IXGBE_DISABLED, adapter->state); + free_netdev(netdev); + +#ifdef HAVE_PCI_ENABLE_PCIE_ERROR_REPORTING + pci_disable_pcie_error_reporting(pdev); +#endif /* HAVE_PCI_ENABLE_PCIE_ERROR_REPORTING */ + + if (disable_dev) + pci_disable_device(pdev); + +} + +static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev) +{ + u16 value; + + pci_read_config_word(pdev, PCI_VENDOR_ID, &value); + if (value == IXGBE_FAILED_READ_CFG_WORD) { + ixgbe_remove_adapter(hw); + return true; + } + return false; +} + +u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg) +{ + struct ixgbe_adapter *adapter = hw->back; + u16 value; + + if (IXGBE_REMOVED(hw->hw_addr)) + return IXGBE_FAILED_READ_CFG_WORD; + pci_read_config_word(adapter->pdev, reg, &value); + if (value == IXGBE_FAILED_READ_CFG_WORD && + ixgbe_check_cfg_remove(hw, adapter->pdev)) + return IXGBE_FAILED_READ_CFG_WORD; + return value; +} + +#ifdef HAVE_PCI_ERS +#ifdef CONFIG_PCI_IOV +static u32 ixgbe_read_pci_cfg_dword(struct ixgbe_hw *hw, u32 reg) +{ + struct ixgbe_adapter *adapter = hw->back; + u32 value; + + if (IXGBE_REMOVED(hw->hw_addr)) + return IXGBE_FAILED_READ_CFG_DWORD; + pci_read_config_dword(adapter->pdev, reg, &value); + if (value == IXGBE_FAILED_READ_CFG_DWORD && + ixgbe_check_cfg_remove(hw, adapter->pdev)) + return IXGBE_FAILED_READ_CFG_DWORD; + return value; +} +#endif /* CONFIG_PCI_IOV */ +#endif /* HAVE_PCI_ERS */ + +void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value) +{ + struct ixgbe_adapter *adapter = hw->back; + + if (IXGBE_REMOVED(hw->hw_addr)) + return; + pci_write_config_word(adapter->pdev, reg, value); +} + +void ewarn(struct ixgbe_hw *hw, const char *st) +{ + struct ixgbe_adapter *adapter = hw->back; + + netif_warn(adapter, drv, adapter->netdev, "%s", st); +} + +#ifdef HAVE_PCI_ERS +/** + * ixgbe_io_error_detected - Handle PCI error detection + * @pdev: Pointer to the PCI device + * @state: The current PCI connection state + * + * This function is called when a PCI bus error affecting the ixgbe network + * adapter is detected. It handles error detection, including identifying + * and managing errors caused by Virtual Functions (VFs) if applicable. The + * function detaches the network device, suspends operations if necessary, + * and requests a slot reset if the error is recoverable. It returns the + * appropriate PCI error recovery result based on the error state and + * device status. + * + * Return: PCI_ERS_RESULT_RECOVERED if the error is recoverable, + * PCI_ERS_RESULT_DISCONNECT if the device should be disconnected, + * or PCI_ERS_RESULT_NEED_RESET if a slot reset is required. + */ +static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; + +#ifdef CONFIG_PCI_IOV + struct ixgbe_hw *hw = &adapter->hw; + struct pci_dev *bdev, *vfdev; + u32 dw0, dw1, dw2, dw3; + int vf, pos; + u16 req_id, pf_func; + + if (adapter->hw.mac.type == ixgbe_mac_82598EB || + adapter->num_vfs == 0) + goto skip_bad_vf_detection; + + bdev = pdev->bus->self; + while (bdev && (pci_pcie_type(bdev) != PCI_EXP_TYPE_ROOT_PORT)) + bdev = bdev->bus->self; + + if (!bdev) + goto skip_bad_vf_detection; + + pos = pci_find_ext_capability(bdev, PCI_EXT_CAP_ID_ERR); + if (!pos) + goto skip_bad_vf_detection; + + dw0 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG); + dw1 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 4); + dw2 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 8); + dw3 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 12); + if (IXGBE_REMOVED(hw->hw_addr)) + goto skip_bad_vf_detection; + + req_id = dw1 >> 16; + /* On the 82599 if bit 7 of the requestor ID is set then it's a VF */ + if (!(req_id & 0x0080)) + goto skip_bad_vf_detection; + + pf_func = req_id & 0x01; + if ((pf_func & 1) == (pdev->devfn & 1)) { + unsigned int device_id; + + vf = (req_id & 0x7F) >> 1; + e_dev_err("VF %d has caused a PCIe error\n", vf); + e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: " + "%8.8x\tdw3: %8.8x\n", + dw0, dw1, dw2, dw3); + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + device_id = IXGBE_DEV_ID_82599_VF; + break; + case ixgbe_mac_X540: + device_id = IXGBE_DEV_ID_X540_VF; + break; + case ixgbe_mac_X550: + device_id = IXGBE_DEV_ID_X550_VF; + break; + case ixgbe_mac_X550EM_x: + device_id = IXGBE_DEV_ID_X550EM_X_VF; + break; + case ixgbe_mac_X550EM_a: + device_id = IXGBE_DEV_ID_X550EM_A_VF; + break; + case ixgbe_mac_E610: + device_id = IXGBE_DEV_ID_E610_VF; + break; + default: + device_id = 0; + break; + } + + /* Find the pci device of the offending VF */ + vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL); + while (vfdev) { + if (vfdev->devfn == (req_id & 0xFF)) + break; + vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, + device_id, vfdev); + } + /* + * There's a slim chance the VF could have been hot plugged, + * so if it is no longer present we don't need to issue the + * VFLR. Just clean up the AER in that case. + */ + if (vfdev) { + ixgbe_issue_vf_flr(adapter, vfdev); + /* Free device reference count */ + pci_dev_put(vfdev); + } + + pci_aer_clear_nonfatal_status(pdev); + } + + /* + * Even though the error may have occurred on the other port + * we still need to increment the vf error reference count for + * both ports because the I/O resume function will be called + * for both of them. + */ + adapter->vferr_refcount++; + + return PCI_ERS_RESULT_RECOVERED; + +skip_bad_vf_detection: +#endif /* CONFIG_PCI_IOV */ + if (!test_bit(__IXGBE_SERVICE_INITED, adapter->state)) + return PCI_ERS_RESULT_DISCONNECT; + + if (!netif_device_present(netdev)) + return PCI_ERS_RESULT_DISCONNECT; + + rtnl_lock(); + netif_device_detach(netdev); + + if (netif_running(netdev)) + ixgbe_close_suspend(adapter); + + if (state == pci_channel_io_perm_failure) { + rtnl_unlock(); + return PCI_ERS_RESULT_DISCONNECT; + } + + if (!test_and_set_bit(__IXGBE_DISABLED, adapter->state)) + pci_disable_device(pdev); + rtnl_unlock(); + + /* Request a slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +/** + * ixgbe_io_slot_reset - Handle PCI slot reset + * @pdev: Pointer to the PCI device + * + * This function is called after the PCI bus has been reset. It restarts the + * ixgbe network adapter from scratch, as if from a cold boot. The function + * re-enables the PCI device, restores its state, and resets the adapter. + * It clears any non-fatal PCI error status and updates the device's state + * to indicate it is no longer disabled. If the device cannot be re-enabled, + * it returns a disconnect result. + * + * Return: PCI_ERS_RESULT_RECOVERED if the reset is successful, or + * PCI_ERS_RESULT_DISCONNECT if the device cannot be re-enabled. + */ +static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + pci_ers_result_t result; + + if (pci_enable_device_mem(pdev)) { + e_err(probe, "Cannot re-enable PCI device after reset.\n"); + result = PCI_ERS_RESULT_DISCONNECT; + } else { + smp_mb__before_atomic(); + clear_bit(__IXGBE_DISABLED, adapter->state); + adapter->hw.hw_addr = adapter->io_addr; + pci_set_master(pdev); + pci_restore_state(pdev); + /* + * After second error pci->state_saved is false, this + * resets it so EEH doesn't break. + */ + pci_save_state(pdev); + + pci_wake_from_d3(pdev, false); + + ixgbe_reset(adapter); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); + result = PCI_ERS_RESULT_RECOVERED; + } + + pci_aer_clear_nonfatal_status(pdev); + + return result; +} + +/** + * ixgbe_io_resume - Resume normal operation after error recovery + * @pdev: Pointer to the PCI device + * + * This function is called when the error recovery process indicates that + * it is safe to resume normal operation for the ixgbe network adapter. It + * reopens the network interface if it was running before the error and + * reattaches the network device. The function also handles specific cases + * related to Virtual Function (VF) errors, ensuring proper resumption of + * operations. + */ +static void ixgbe_io_resume(struct pci_dev *pdev) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = adapter->netdev; + +#ifdef CONFIG_PCI_IOV + if (adapter->vferr_refcount) { + e_info(drv, "Resuming after VF err\n"); + adapter->vferr_refcount--; + return; + } + +#endif + rtnl_lock(); + if (netif_running(netdev)) + ixgbe_open(netdev); + + netif_device_attach(netdev); + rtnl_unlock(); +} + +#ifdef CONFIG_PM +#ifdef HAVE_PCI_ERROR_HANDLER_RESET_NOTIFY +/** + * ixgbe_io_reset_notify - Notify the device of an I/O reset + * @pdev: PCI device structure + * @prepare: Boolean indicating whether to prepare for reset (true) or resume (false) + * + * This function notifies the specified PCI device of an I/O reset. If the + * `prepare` parameter is true, it suspends the device in preparation for the + * reset. If false, it resumes the device after the reset. + */ +static void ixgbe_io_reset_notify(struct pci_dev *pdev, bool prepare) +{ + struct device *dev = &pdev->dev; + + if (prepare) + ixgbe_suspend(dev); + else + ixgbe_resume(dev); +} +#endif /* HAVE_PCI_ERROR_HANDLER_RESET_NOTIFY */ + +#ifdef HAVE_PCI_ERROR_HANDLER_RESET_PREPARE +static void pci_io_reset_prepare(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + + ixgbe_suspend(dev); +} + +static void pci_io_reset_done(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + + ixgbe_resume(dev); +} +#endif +#endif + +#ifdef HAVE_CONST_STRUCT_PCI_ERROR_HANDLERS +static const struct pci_error_handlers ixgbe_err_handler = { +#else +static struct pci_error_handlers ixgbe_err_handler = { +#endif + .error_detected = ixgbe_io_error_detected, + .slot_reset = ixgbe_io_slot_reset, +#ifdef CONFIG_PM +#ifdef HAVE_PCI_ERROR_HANDLER_RESET_NOTIFY + .reset_notify = ixgbe_io_reset_notify, +#endif +#ifdef HAVE_PCI_ERROR_HANDLER_RESET_PREPARE + .reset_prepare = pci_io_reset_prepare, + .reset_done = pci_io_reset_done, +#endif +#endif + .resume = ixgbe_io_resume, +}; +#endif /* HAVE_PCI_ERS */ + +struct net_device *ixgbe_hw_to_netdev(const struct ixgbe_hw *hw) +{ + return ((struct ixgbe_adapter *)hw->back)->netdev; +} +struct ixgbe_msg *ixgbe_hw_to_msg(const struct ixgbe_hw *hw) +{ + struct ixgbe_adapter *adapter = + container_of(hw, struct ixgbe_adapter, hw); + return (struct ixgbe_msg *)&adapter->msg_enable; +} + +#ifdef HAVE_RHEL6_SRIOV_CONFIGURE +static struct pci_driver_rh ixgbe_driver_rh = { + .sriov_configure = ixgbe_pci_sriov_configure, +}; +#endif + +#ifdef CONFIG_PM +#ifndef USE_LEGACY_PM_SUPPORT +static const struct dev_pm_ops ixgbe_pm_ops = { + .suspend = ixgbe_suspend, + .resume = ixgbe_resume, + .freeze = ixgbe_freeze, + .thaw = ixgbe_thaw, + .poweroff = ixgbe_suspend, + .restore = ixgbe_resume, +}; +#endif /* USE_LEGACY_PM_SUPPORT */ +#endif + +static struct pci_driver ixgbe_driver = { + .name = ixgbe_driver_name, + .id_table = ixgbe_pci_tbl, + .probe = ixgbe_probe, +#ifdef HAVE_CONFIG_HOTPLUG + .remove = __devexit_p(ixgbe_remove), +#else + .remove = ixgbe_remove, +#endif +#ifdef CONFIG_PM +#ifndef USE_LEGACY_PM_SUPPORT + .driver = { + .pm = &ixgbe_pm_ops, + }, +#else + .suspend = ixgbe_suspend, + .resume = ixgbe_resume, +#endif /* USE_LEGACY_PM_SUPPORT */ +#endif +#ifndef USE_REBOOT_NOTIFIER + .shutdown = ixgbe_shutdown, +#endif +#if defined(HAVE_SRIOV_CONFIGURE) + .sriov_configure = ixgbe_pci_sriov_configure, +#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE) + .rh_reserved = &ixgbe_driver_rh, +#endif /* HAVE_SRIOV_CONFIGURE */ +#ifdef HAVE_PCI_ERS + .err_handler = &ixgbe_err_handler +#endif +}; + +bool ixgbe_is_ixgbe(struct pci_dev *pcidev) +{ + if (pci_dev_driver(pcidev) != &ixgbe_driver) + return false; + else + return true; +} + +/** + * ixgbe_init_module - Driver Registration Routine + * + * ixgbe_init_module is the first routine called when the driver is + * loaded. All it does is register with the PCI subsystem. + **/ +static int __init ixgbe_init_module(void) +{ + int ret; + pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version); + pr_info("%s\n", ixgbe_copyright); + + ixgbe_wq = create_singlethread_workqueue(ixgbe_driver_name); + if (!ixgbe_wq) { + pr_err("%s: Failed to create workqueue\n", ixgbe_driver_name); + return -ENOMEM; + } + +#ifdef IXGBE_PROCFS + if (ixgbe_procfs_topdir_init()) + pr_info("Procfs failed to initialize topdir\n"); +#endif + +#ifdef HAVE_IXGBE_DEBUG_FS + ixgbe_dbg_init(); +#endif /* HAVE_IXGBE_DEBUG_FS */ + + ret = pci_register_driver(&ixgbe_driver); + if (ret) { + destroy_workqueue(ixgbe_wq); +#ifdef HAVE_IXGBE_DEBUG_FS + ixgbe_dbg_exit(); +#endif /* HAVE_IXGBE_DEBUG_FS */ +#ifdef IXGBE_PROCFS + ixgbe_procfs_topdir_exit(); +#endif + return ret; + } +#if IS_ENABLED(CONFIG_DCA) + + dca_register_notify(&dca_notifier); +#endif + + return ret; +} + +module_init(ixgbe_init_module); + +/** + * ixgbe_exit_module - Driver Exit Cleanup Routine + * + * ixgbe_exit_module is called just before the driver is removed + * from memory. + **/ +static void __exit ixgbe_exit_module(void) +{ +#if IS_ENABLED(CONFIG_DCA) + dca_unregister_notify(&dca_notifier); +#endif + pci_unregister_driver(&ixgbe_driver); +#ifdef IXGBE_PROCFS + ixgbe_procfs_topdir_exit(); +#endif + destroy_workqueue(ixgbe_wq); +#ifdef HAVE_IXGBE_DEBUG_FS + ixgbe_dbg_exit(); +#endif /* HAVE_IXGBE_DEBUG_FS */ +} + +#if IS_ENABLED(CONFIG_DCA) +/** + * ixgbe_notify_dca - Handle DCA (Direct Cache Access) notifications + * @nb: Notifier block (unused) + * @event: Event type + * @p: Pointer to event data (unused) + * + * This function handles notifications related to Direct Cache Access (DCA) + * for the ixgbe driver. It iterates over each device managed by the driver + * and processes the event using the `__ixgbe_notify_dca` function. + * + * Return: NOTIFY_DONE on success, or NOTIFY_BAD if an error occurs. + */ +static int ixgbe_notify_dca(struct notifier_block __always_unused *nb, unsigned long event, + void __always_unused *p) +{ + int ret_val; + + ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event, + __ixgbe_notify_dca); + + return ret_val ? NOTIFY_BAD : NOTIFY_DONE; +} +#endif /* CONFIG_DCA */ +module_exit(ixgbe_exit_module); + +/* ixgbe_main.c */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.c new file mode 100644 index 0000000000..7a93b7334b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.c @@ -0,0 +1,1181 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_type.h" +#include "ixgbe_mbx.h" + +STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id); +STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id); + +/** + * ixgbe_read_mbx - Reads a message from the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to read + * + * returns SUCCESS if it successfully read message from buffer + **/ +s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + + DEBUGFUNC("ixgbe_read_mbx"); + + /* limit read to size of mailbox */ + if (size > mbx->size) { + ERROR_REPORT3(IXGBE_ERROR_ARGUMENT, + "Invalid mailbox message size %u, changing to %u", + size, mbx->size); + size = mbx->size; + } + + if (mbx->ops[mbx_id].read) + return mbx->ops[mbx_id].read(hw, msg, size, mbx_id); + + return IXGBE_ERR_CONFIG; +} + +/** + * ixgbe_poll_mbx - Wait for message and read it from the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to read + * + * returns SUCCESS if it successfully read message from buffer + **/ +s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val; + + DEBUGFUNC("ixgbe_poll_mbx"); + + if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg || + !mbx->timeout) + return IXGBE_ERR_CONFIG; + + /* limit read to size of mailbox */ + if (size > mbx->size) { + ERROR_REPORT3(IXGBE_ERROR_ARGUMENT, + "Invalid mailbox message size %u, changing to %u", + size, mbx->size); + size = mbx->size; + } + + ret_val = ixgbe_poll_for_msg(hw, mbx_id); + /* if ack received read message, otherwise we timed out */ + if (!ret_val) + return mbx->ops[mbx_id].read(hw, msg, size, mbx_id); + + return ret_val; +} + +/** + * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully copied message into the buffer and + * received an ACK to that message within specified period + * + * Note that the caller to this function must lock before calling, since + * multiple threads can destroy each other messages. + **/ +s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_MBX; + + DEBUGFUNC("ixgbe_write_mbx"); + + /* + * exit if either we can't write, release + * or there is no timeout defined + */ + if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack || + !mbx->ops[mbx_id].release || !mbx->timeout) + return IXGBE_ERR_CONFIG; + + if (size > mbx->size) { + ret_val = IXGBE_ERR_PARAM; + ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, + "Invalid mailbox message size %u", size); + } else { + ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id); + } + + return ret_val; +} + +/** + * ixgbe_check_for_msg - checks to see if someone sent us mail + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the Status bit was found or else ERR_MBX + **/ +s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_CONFIG; + + DEBUGFUNC("ixgbe_check_for_msg"); + + if (mbx->ops[mbx_id].check_for_msg) + ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id); + + return ret_val; +} + +/** + * ixgbe_check_for_ack - checks to see if someone sent us ACK + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the Status bit was found or else ERR_MBX + **/ +s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_CONFIG; + + DEBUGFUNC("ixgbe_check_for_ack"); + + if (mbx->ops[mbx_id].check_for_ack) + ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id); + + return ret_val; +} + +/** + * ixgbe_check_for_rst - checks to see if other side has reset + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the Status bit was found or else ERR_MBX + **/ +s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_CONFIG; + + DEBUGFUNC("ixgbe_check_for_rst"); + + if (mbx->ops[mbx_id].check_for_rst) + ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id); + + return ret_val; +} + +/** + * ixgbe_clear_mbx - Clear Mailbox Memory + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to write + * + * Set VFMBMEM of given VF to 0x0. + **/ +s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_CONFIG; + + DEBUGFUNC("ixgbe_clear_mbx"); + + if (mbx->ops[mbx_id].clear) + ret_val = mbx->ops[mbx_id].clear(hw, mbx_id); + + return ret_val; +} + +/** + * ixgbe_poll_for_msg - Wait for message notification + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully received a message notification + **/ +STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + int countdown = mbx->timeout; + + DEBUGFUNC("ixgbe_poll_for_msg"); + + if (!countdown || !mbx->ops[mbx_id].check_for_msg) + return IXGBE_ERR_CONFIG; + + while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) { + countdown--; + if (!countdown) + break; + usec_delay(mbx->usec_delay); + } + + if (countdown == 0) { + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Polling for VF%u mailbox message timedout", mbx_id); + return IXGBE_ERR_TIMEOUT; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_poll_for_ack - Wait for message acknowledgment + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully received a message acknowledgment + **/ +STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + int countdown = mbx->timeout; + + DEBUGFUNC("ixgbe_poll_for_ack"); + + if (!countdown || !mbx->ops[mbx_id].check_for_ack) + return IXGBE_ERR_CONFIG; + + while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) { + countdown--; + if (!countdown) + break; + usec_delay(mbx->usec_delay); + } + + if (countdown == 0) { + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Polling for VF%u mailbox ack timedout", mbx_id); + return IXGBE_ERR_TIMEOUT; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_mailbox_vf - read VF's mailbox register + * @hw: pointer to the HW structure + * + * This function is used to read the mailbox register dedicated for VF without + * losing the read to clear status bits. + **/ +STATIC u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw) +{ + u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); + + vf_mailbox |= hw->mbx.vf_mailbox; + hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS; + + return vf_mailbox; +} + +STATIC void ixgbe_clear_msg_vf(struct ixgbe_hw *hw) +{ + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); + + if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) { + hw->mbx.stats.reqs++; + hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS; + } +} + +STATIC void ixgbe_clear_ack_vf(struct ixgbe_hw *hw) +{ + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); + + if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) { + hw->mbx.stats.acks++; + hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK; + } +} + +STATIC void ixgbe_clear_rst_vf(struct ixgbe_hw *hw) +{ + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); + + if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) { + hw->mbx.stats.rsts++; + hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI | + IXGBE_VFMAILBOX_RSTD); + } +} + +/** + * ixgbe_check_for_bit_vf - Determine if a status bit was set + * @hw: pointer to the HW structure + * @mask: bitmask for bits to be tested and cleared + * + * This function is used to check for the read to clear bits within + * the V2P mailbox. + **/ +STATIC s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask) +{ + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); + + if (vf_mailbox & mask) + return IXGBE_SUCCESS; + + return IXGBE_ERR_MBX; +} + +/** + * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the PF has set the Status bit or else ERR_MBX + **/ +STATIC s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id) +{ + UNREFERENCED_1PARAMETER(mbx_id); + DEBUGFUNC("ixgbe_check_for_msg_vf"); + + if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) + return IXGBE_SUCCESS; + + return IXGBE_ERR_MBX; +} + +/** + * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX + **/ +STATIC s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id) +{ + UNREFERENCED_1PARAMETER(mbx_id); + DEBUGFUNC("ixgbe_check_for_ack_vf"); + + if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) { + /* TODO: should this be autocleared? */ + ixgbe_clear_ack_vf(hw); + return IXGBE_SUCCESS; + } + + return IXGBE_ERR_MBX; +} + +/** + * ixgbe_check_for_rst_vf - checks to see if the PF has reset + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns true if the PF has set the reset done bit or else false + **/ +STATIC s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id) +{ + UNREFERENCED_1PARAMETER(mbx_id); + DEBUGFUNC("ixgbe_check_for_rst_vf"); + + if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI | + IXGBE_VFMAILBOX_RSTD)) { + /* TODO: should this be autocleared? */ + ixgbe_clear_rst_vf(hw); + return IXGBE_SUCCESS; + } + + return IXGBE_ERR_MBX; +} + +/** + * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock + * @hw: pointer to the HW structure + * + * return SUCCESS if we obtained the mailbox lock + **/ +STATIC s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + int countdown = mbx->timeout; + s32 ret_val = IXGBE_ERR_MBX; + u32 vf_mailbox; + + DEBUGFUNC("ixgbe_obtain_mbx_lock_vf"); + + if (!mbx->timeout) + return IXGBE_ERR_CONFIG; + + while (countdown--) { + /* Reserve mailbox for VF use */ + vf_mailbox = ixgbe_read_mailbox_vf(hw); + vf_mailbox |= IXGBE_VFMAILBOX_VFU; + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); + + /* Verify that VF is the owner of the lock */ + if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) { + ret_val = IXGBE_SUCCESS; + break; + } + + /* Wait a bit before trying again */ + usec_delay(mbx->usec_delay); + } + + if (ret_val != IXGBE_SUCCESS) { + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "Failed to obtain mailbox lock"); + ret_val = IXGBE_ERR_TIMEOUT; + } + + return ret_val; +} + +/** + * ixgbe_release_mbx_lock_dummy - release mailbox lock + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to read + **/ +STATIC void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id) +{ + UNREFERENCED_2PARAMETER(hw, mbx_id); + + DEBUGFUNC("ixgbe_release_mbx_lock_dummy"); +} + +/** + * ixgbe_release_mbx_lock_vf - release mailbox lock + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to read + **/ +STATIC void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id) +{ + u32 vf_mailbox; + + UNREFERENCED_1PARAMETER(mbx_id); + + DEBUGFUNC("ixgbe_release_mbx_lock_vf"); + + /* Return ownership of the buffer */ + vf_mailbox = ixgbe_read_mailbox_vf(hw); + vf_mailbox &= ~IXGBE_VFMAILBOX_VFU; + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); +} + +/** + * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully copied message into the buffer + **/ +STATIC s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + s32 ret_val; + u16 i; + + UNREFERENCED_1PARAMETER(mbx_id); + DEBUGFUNC("ixgbe_write_mbx_vf_legacy"); + + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_vf(hw); + if (ret_val) + return ret_val; + + /* flush msg and acks as we are overwriting the message buffer */ + ixgbe_check_for_msg_vf(hw, 0); + ixgbe_clear_msg_vf(hw); + ixgbe_check_for_ack_vf(hw, 0); + ixgbe_clear_ack_vf(hw); + + /* copy the caller specified message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]); + + /* update stats */ + hw->mbx.stats.msgs_tx++; + + /* interrupt the PF to tell it a message has been sent */ + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_mbx_vf - Write a message to the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully copied message into the buffer + **/ +STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + u32 vf_mailbox; + s32 ret_val; + u16 i; + + UNREFERENCED_1PARAMETER(mbx_id); + + DEBUGFUNC("ixgbe_write_mbx_vf"); + + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_vf(hw); + if (ret_val) + goto out; + + /* flush msg and acks as we are overwriting the message buffer */ + ixgbe_clear_msg_vf(hw); + ixgbe_clear_ack_vf(hw); + + /* copy the caller specified message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]); + + /* update stats */ + hw->mbx.stats.msgs_tx++; + + /* interrupt the PF to tell it a message has been sent */ + vf_mailbox = ixgbe_read_mailbox_vf(hw); + vf_mailbox |= IXGBE_VFMAILBOX_REQ; + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); + + /* if msg sent wait until we receive an ack */ + ixgbe_poll_for_ack(hw, mbx_id); + +out: + hw->mbx.ops[mbx_id].release(hw, mbx_id); + + return ret_val; +} + +/** + * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to read + * + * returns SUCCESS if it successfully read message from buffer + **/ +STATIC s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_read_mbx_vf_legacy"); + UNREFERENCED_1PARAMETER(mbx_id); + + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_vf(hw); + if (ret_val) + return ret_val; + + /* copy the message from the mailbox memory buffer */ + for (i = 0; i < size; i++) + msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i); + + /* Acknowledge receipt and release mailbox, then we're done */ + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK); + + /* update stats */ + hw->mbx.stats.msgs_rx++; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to read + * + * returns SUCCESS if it successfully read message from buffer + **/ +STATIC s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + u32 vf_mailbox; + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_read_mbx_vf"); + UNREFERENCED_1PARAMETER(mbx_id); + + /* check if there is a message from PF */ + ret_val = ixgbe_check_for_msg_vf(hw, 0); + if (ret_val != IXGBE_SUCCESS) + return IXGBE_ERR_MBX_NOMSG; + + ixgbe_clear_msg_vf(hw); + + /* copy the message from the mailbox memory buffer */ + for (i = 0; i < size; i++) + msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i); + + /* Acknowledge receipt */ + vf_mailbox = ixgbe_read_mailbox_vf(hw); + vf_mailbox |= IXGBE_VFMAILBOX_ACK; + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); + + /* update stats */ + hw->mbx.stats.msgs_rx++; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_mbx_params_vf - set initial values for vf mailbox + * @hw: pointer to the HW structure + * + * Initializes single set the hw->mbx struct to correct values for vf mailbox + * Set of legacy functions is being used here + */ +void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + + mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; + mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; + + mbx->size = IXGBE_VFMAILBOX_SIZE; + + /* VF has only one mailbox connection, no need for more IDs */ + mbx->ops[0].release = ixgbe_release_mbx_lock_dummy; + mbx->ops[0].read = ixgbe_read_mbx_vf_legacy; + mbx->ops[0].write = ixgbe_write_mbx_vf_legacy; + mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf; + mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf; + mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf; + mbx->ops[0].clear = NULL; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; +} + +/** + * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox + * @hw: pointer to the HW structure + * + * Initializes the hw->mbx struct to correct values for vf mailbox + */ +void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + + mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; + mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; + + mbx->size = IXGBE_VFMAILBOX_SIZE; + + /* VF has only one mailbox connection, no need for more IDs */ + mbx->ops[0].release = ixgbe_release_mbx_lock_vf; + mbx->ops[0].read = ixgbe_read_mbx_vf; + mbx->ops[0].write = ixgbe_write_mbx_vf; + mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf; + mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf; + mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf; + mbx->ops[0].clear = NULL; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; +} + +STATIC void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); + s32 index = IXGBE_PFMBICR_INDEX(vf_id); + u32 pfmbicr; + + pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index)); + + if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift)) + hw->mbx.stats.reqs++; + + IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), + IXGBE_PFMBICR_VFREQ_VF1 << vf_shift); +} + +STATIC void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); + s32 index = IXGBE_PFMBICR_INDEX(vf_id); + u32 pfmbicr; + + pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index)); + + if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift)) + hw->mbx.stats.acks++; + + IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), + IXGBE_PFMBICR_VFACK_VF1 << vf_shift); +} + +STATIC s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) +{ + u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index)); + + if (pfmbicr & mask) + return IXGBE_SUCCESS; + + return IXGBE_ERR_MBX; +} + +/** + * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * returns SUCCESS if the VF has set the Status bit or else ERR_MBX + **/ +STATIC s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); + s32 index = IXGBE_PFMBICR_INDEX(vf_id); + + DEBUGFUNC("ixgbe_check_for_msg_pf"); + + if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift, + index)) + return IXGBE_SUCCESS; + + return IXGBE_ERR_MBX; +} + +/** + * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * returns SUCCESS if the VF has set the Status bit or else ERR_MBX + **/ +STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); + s32 index = IXGBE_PFMBICR_INDEX(vf_id); + s32 ret_val = IXGBE_ERR_MBX; + + DEBUGFUNC("ixgbe_check_for_ack_pf"); + + if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift, + index)) { + ret_val = IXGBE_SUCCESS; + /* TODO: should this be autocleared? */ + ixgbe_clear_ack_pf(hw, vf_id); + } + + return ret_val; +} + +/** + * ixgbe_check_for_rst_pf - checks to see if the VF has reset + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * returns SUCCESS if the VF has set the Status bit or else ERR_MBX + **/ +STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id); + u32 index = IXGBE_PFVFLRE_INDEX(vf_id); + s32 ret_val = IXGBE_ERR_MBX; + u32 vflre = 0; + + DEBUGFUNC("ixgbe_check_for_rst_pf"); + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index)); + break; + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_X540: + case ixgbe_mac_E610: + vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index)); + break; + default: + break; + } + + if (vflre & (1 << vf_shift)) { + ret_val = IXGBE_SUCCESS; + IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift)); + hw->mbx.stats.rsts++; + } + + return ret_val; +} + +/** + * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * return SUCCESS if we obtained the mailbox lock + **/ +STATIC s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + int countdown = mbx->timeout; + s32 ret_val = IXGBE_ERR_MBX; + u32 pf_mailbox; + + DEBUGFUNC("ixgbe_obtain_mbx_lock_pf"); + + if (!mbx->timeout) + return IXGBE_ERR_CONFIG; + + while (countdown--) { + /* Reserve mailbox for PF use */ + pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); + + /* Check if other thread holds the PF lock already */ + if (pf_mailbox & IXGBE_PFMAILBOX_PFU) + goto retry; + + pf_mailbox |= IXGBE_PFMAILBOX_PFU; + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); + + /* Verify that PF is the owner of the lock */ + pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); + if (pf_mailbox & IXGBE_PFMAILBOX_PFU) { + ret_val = IXGBE_SUCCESS; + break; + } + + retry: + /* Wait a bit before trying again */ + usec_delay(mbx->usec_delay); + } + + if (ret_val != IXGBE_SUCCESS) { + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "Failed to obtain mailbox lock"); + ret_val = IXGBE_ERR_TIMEOUT; + } + + return ret_val; +} + +/** + * ixgbe_release_mbx_lock_pf - release mailbox lock + * @hw: pointer to the HW structure + * @vf_id: the VF index + **/ +STATIC void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u32 pf_mailbox; + + DEBUGFUNC("ixgbe_release_mbx_lock_pf"); + + /* Return ownership of the buffer */ + pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); + pf_mailbox &= ~IXGBE_PFMAILBOX_PFU; + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); +} + +/** + * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @vf_id: the VF index + * + * returns SUCCESS if it successfully copied message into the buffer + **/ +STATIC s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 vf_id) +{ + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_write_mbx_pf_legacy"); + + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id); + if (ret_val) + return ret_val; + + /* flush msg and acks as we are overwriting the message buffer */ + ixgbe_check_for_msg_pf(hw, vf_id); + ixgbe_clear_msg_pf(hw, vf_id); + ixgbe_check_for_ack_pf(hw, vf_id); + ixgbe_clear_ack_pf(hw, vf_id); + + /* copy the caller specified message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]); + + /* Interrupt VF to tell it a message has been sent and release buffer*/ + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS); + + /* update stats */ + hw->mbx.stats.msgs_tx++; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_mbx_pf - Places a message in the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @vf_id: the VF index + * + * returns SUCCESS if it successfully copied message into the buffer + **/ +STATIC s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 vf_id) +{ + u32 pf_mailbox; + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_write_mbx_pf"); + + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id); + if (ret_val) + goto out; + + /* flush msg and acks as we are overwriting the message buffer */ + ixgbe_clear_msg_pf(hw, vf_id); + ixgbe_clear_ack_pf(hw, vf_id); + + /* copy the caller specified message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]); + + /* interrupt VF to tell it a message has been sent */ + pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); + pf_mailbox |= IXGBE_PFMAILBOX_STS; + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); + + /* if msg sent wait until we receive an ack */ + if (msg[0] & IXGBE_VT_MSGTYPE_CTS) + ixgbe_poll_for_ack(hw, vf_id); + + /* update stats */ + hw->mbx.stats.msgs_tx++; + +out: + hw->mbx.ops[vf_id].release(hw, vf_id); + + return ret_val; + +} + +/** + * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @vf_id: the VF index + * + * This function copies a message from the mailbox buffer to the caller's + * memory buffer. The presumption is that the caller knows that there was + * a message due to a VF request so no polling for message is needed. + **/ +STATIC s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 vf_id) +{ + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_read_mbx_pf_legacy"); + + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id); + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* copy the message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i); + + /* Acknowledge the message and release buffer */ + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK); + + /* update stats */ + hw->mbx.stats.msgs_rx++; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_mbx_pf - Read a message from the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @vf_id: the VF index + * + * This function copies a message from the mailbox buffer to the caller's + * memory buffer. The presumption is that the caller knows that there was + * a message due to a VF request so no polling for message is needed. + **/ +STATIC s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 vf_id) +{ + u32 pf_mailbox; + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_read_mbx_pf"); + + /* check if there is a message from VF */ + ret_val = ixgbe_check_for_msg_pf(hw, vf_id); + if (ret_val != IXGBE_SUCCESS) + return IXGBE_ERR_MBX_NOMSG; + + ixgbe_clear_msg_pf(hw, vf_id); + + /* copy the message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i); + + /* Acknowledge the message and release buffer */ + pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); + pf_mailbox |= IXGBE_PFMAILBOX_ACK; + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); + + /* update stats */ + hw->mbx.stats.msgs_rx++; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_clear_mbx_pf - Clear Mailbox Memory + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * Set VFMBMEM of given VF to 0x0. + **/ +STATIC s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + u16 mbx_size = hw->mbx.size; + u16 i; + + if (vf_id > 63) + return IXGBE_ERR_PARAM; + + for (i = 0; i < mbx_size; ++i) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * Initializes single set of the hw->mbx struct to correct values for pf mailbox + * Set of legacy functions is being used here + */ +void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + + mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy; + mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy; + mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy; + mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf; + mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf; + mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf; + mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf; +} + +/** + * ixgbe_init_mbx_params_pf - set initial values for pf mailbox + * @hw: pointer to the HW structure + * + * Initializes all sets of the hw->mbx struct to correct values for pf + * mailbox. One set corresponds to single VF. It also initializes counters + * and general variables. A set of legacy functions is used by default. + */ +void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) +{ + u16 i; + struct ixgbe_mbx_info *mbx = &hw->mbx; + + /* Ensure we are not calling this function from VF */ + if (hw->mac.type != ixgbe_mac_82599EB && + hw->mac.type != ixgbe_mac_X550 && + hw->mac.type != ixgbe_mac_X550EM_x && + hw->mac.type != ixgbe_mac_X550EM_a && + hw->mac.type != ixgbe_mac_X540 && + !ixgbe_is_mac_E6xx(hw->mac.type)) + return; + + /* Initialize common mailbox settings */ + mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; + mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; + mbx->size = IXGBE_VFMAILBOX_SIZE; + + /* Initialize counters with zeroes */ + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; + + /* No matter of VF number, we initialize params for all 64 VFs. */ + /* TODO: 1. Add a define for max VF and refactor SHARED to get rid + * of magic number for that (63 or 64 depending on use case.) + * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for + * certain number of VFs instead of default maximum value of 64 (0..63) + */ + for (i = 0; i < 64; i++) + ixgbe_init_mbx_params_pf_id(hw, i); +} + +/** + * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox + * @hw: pointer to the HW structure + * @vf_id: the VF index + * + * Initializes the hw->mbx struct to new function set for improved + * stability and handling of messages. + */ +void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + + /* Ensure we are not calling this function from VF */ + if (hw->mac.type != ixgbe_mac_82599EB && + hw->mac.type != ixgbe_mac_X550 && + hw->mac.type != ixgbe_mac_X550EM_x && + hw->mac.type != ixgbe_mac_X550EM_a && + hw->mac.type != ixgbe_mac_X540 && + !ixgbe_is_mac_E6xx(hw->mac.type)) + return; + + mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; + mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; + mbx->size = IXGBE_VFMAILBOX_SIZE; + + mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf; + mbx->ops[vf_id].read = ixgbe_read_mbx_pf; + mbx->ops[vf_id].write = ixgbe_write_mbx_pf; + mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf; + mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf; + mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf; + mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.h new file mode 100644 index 0000000000..9ace3ed24a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_mbx.h @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_MBX_H_ +#define _IXGBE_MBX_H_ + +struct ixgbe_hw; + +struct ixgbe_mbx_operations { + void (*init_params)(struct ixgbe_hw *hw); + void (*release)(struct ixgbe_hw *hw, u16 mbx_id); + s32 (*read)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id); + s32 (*write)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id); + s32 (*check_for_msg)(struct ixgbe_hw *hw, u16 vf_number); + s32 (*check_for_ack)(struct ixgbe_hw *hw, u16 vf_number); + s32 (*check_for_rst)(struct ixgbe_hw *hw, u16 vf_number); + s32 (*clear)(struct ixgbe_hw *hw, u16 vf_number); +}; + +struct ixgbe_mbx_stats { + u32 msgs_tx; + u32 msgs_rx; + + u32 acks; + u32 reqs; + u32 rsts; +}; + +struct ixgbe_mbx_info { + /* + * PF: One set of operations for each VF to handle various API versions + * at the same time + * VF: Only the very first (0) set should be used + */ + struct ixgbe_mbx_operations ops[64]; + struct ixgbe_mbx_stats stats; + u32 timeout; + u32 usec_delay; + u32 vf_mailbox; + u16 size; +}; + +#define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ + +#define IXGBE_VFMAILBOX 0x002FC +#define IXGBE_VFMBMEM 0x00200 + +/* Define mailbox register bits */ +#define IXGBE_VFMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */ +#define IXGBE_VFMAILBOX_ACK 0x00000002 /* Ack PF message received */ +#define IXGBE_VFMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ +#define IXGBE_VFMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ +#define IXGBE_VFMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */ +#define IXGBE_VFMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */ +#define IXGBE_VFMAILBOX_RSTI 0x00000040 /* PF has reset indication */ +#define IXGBE_VFMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */ +#define IXGBE_VFMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */ + +#define IXGBE_PFMAILBOX_STS 0x00000001 /* Initiate message send to VF */ +#define IXGBE_PFMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */ +#define IXGBE_PFMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ +#define IXGBE_PFMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ +#define IXGBE_PFMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */ + +#define IXGBE_PFMBICR_VFREQ_MASK 0x0000FFFF /* bits for VF messages */ +#define IXGBE_PFMBICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */ +#define IXGBE_PFMBICR_VFACK_MASK 0xFFFF0000 /* bits for VF acks */ +#define IXGBE_PFMBICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */ + +/* If it's a IXGBE_VF_* msg then it originates in the VF and is sent to the + * PF. The reverse is true if it is IXGBE_PF_*. + * Message results are the value or'd with 0xF0000000 + */ +#define IXGBE_VT_MSGTYPE_SUCCESS 0x80000000 /* Messages or'd with this + * have succeeded + */ +#define IXGBE_VT_MSGTYPE_FAILURE 0x40000000 /* Messages or'd with this + * have failed + */ +#define IXGBE_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still + * clear to send requests + */ +#define IXGBE_VT_MSGINFO_SHIFT 16 +/* bits 23:16 are used for extra info for certain messages */ +#define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT) + +/* definitions to support mailbox API version negotiation */ + +/* + * each element denotes a version of the API; existing numbers may not + * change; any additions must go at the end + */ +enum ixgbe_pfvf_api_rev { + ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ + ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ + ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ + ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */ + ixgbe_mbox_api_13, /* API version 1.3, linux/freebsd VF driver */ + /* API 1.4 is being used in the upstream for IPsec */ + ixgbe_mbox_api_14, /* API version 1.4, linux/freebsd VF driver */ + ixgbe_mbox_api_15, /* API version 1.5, linux/freebsd VF driver */ + ixgbe_mbox_api_16, /* API version 1.6, linux/freebsd VF driver */ + ixgbe_mbox_api_17, /* API version 1.7, linux/freebsd VF driver */ + /* This value should always be last */ + ixgbe_mbox_api_unknown, /* indicates that API version is not known */ +}; + +/* mailbox API, legacy requests */ +#define IXGBE_VF_RESET 0x01 /* VF requests reset */ +#define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */ +#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ +#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ + +/* mailbox API, version 1.0 VF requests */ +#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ +#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ +#define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ + +/* mailbox API, version 1.1 VF requests */ +#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */ + +/* mailbox API, version 1.2 VF requests */ +#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */ +#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS key */ +#define IXGBE_VF_UPDATE_XCAST_MODE 0x0c +#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */ + +/* mailbox API, version 1.6 VF requests */ +#define IXGBE_VF_GET_PF_LINK_STATE 0x11 /* get status of the link on PF */ + +/* mailbox API, version 1.7 VF requests */ +#define IXGBE_VF_FEATURES_NEGOTIATE 0x12 /* get features supported by PF */ + +/* Negotiable features */ +#define IXGBEVF_PF_SUP_IPSEC BIT(0) +#define IXGBEVF_PF_SUP_ESX_MBX BIT(1) + +/* Features supported by IXGBE driver */ +#define IXGBEVF_SUPPORTED_FEATURES IXGBEVF_PF_SUP_ESX_MBX + +/* mode choices for IXGBE_VF_UPDATE_XCAST_MODE */ +enum ixgbevf_xcast_modes { + IXGBEVF_XCAST_MODE_NONE = 0, + IXGBEVF_XCAST_MODE_MULTI, + IXGBEVF_XCAST_MODE_ALLMULTI, + IXGBEVF_XCAST_MODE_PROMISC, +}; + +/* GET_QUEUES return data indices within the mailbox */ +#define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ +#define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ +#define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */ +#define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */ + +/* length of permanent address message returned from PF */ +#define IXGBE_VF_PERMADDR_MSG_LEN 4 +/* word in permanent address message with the current multicast type */ +#define IXGBE_VF_MC_TYPE_WORD 3 + +#define IXGBE_PF_CONTROL_MSG 0x0100 /* PF control message */ + +/* mailbox API, version 2.0 VF requests */ +#define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ +#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */ +#define IXGBE_VF_ENABLE_MACADDR 0x0A /* enable MAC address */ +#define IXGBE_VF_DISABLE_MACADDR 0x0B /* disable MAC address */ +#define IXGBE_VF_GET_MACADDRS 0x0C /* get all configured MAC addrs */ +#define IXGBE_VF_SET_MCAST_PROMISC 0x0D /* enable multicast promiscuous */ +#define IXGBE_VF_GET_MTU 0x0E /* get bounds on MTU */ +#define IXGBE_VF_SET_MTU 0x0F /* set a specific MTU */ + +/* mailbox API, version 2.0 PF requests */ +#define IXGBE_PF_TRANSPARENT_VLAN 0x0101 /* enable transparent vlan */ + +#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */ +#define IXGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */ + +s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id); +s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id); +s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id); +s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id); +s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id); +s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id); +s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 vf_number); +void ixgbe_init_mbx_params_vf(struct ixgbe_hw *); +void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw); +void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw); +void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id); +void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id); + +#endif /* _IXGBE_MBX_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_model.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_model.h new file mode 100644 index 0000000000..778b82343f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_model.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_MODEL_H_ +#define _IXGBE_MODEL_H_ + +#include "ixgbe.h" +#include "ixgbe_type.h" + +struct ixgbe_mat_field { + unsigned int off; + int (*val)(struct ixgbe_fdir_filter *input, + union ixgbe_atr_input *mask, + u32 val, u32 m); + unsigned int type; +}; + +struct ixgbe_jump_table { + struct ixgbe_mat_field *mat; + struct ixgbe_fdir_filter *input; + union ixgbe_atr_input *mask; + u32 link_hdl; + unsigned long child_loc_map[32]; +}; + +#define IXGBE_MAX_HW_ENTRIES 2045 + +static inline int ixgbe_mat_prgm_sip(struct ixgbe_fdir_filter *input, + union ixgbe_atr_input *mask, + u32 val, u32 m) +{ + input->filter.formatted.src_ip[0] = val; + mask->formatted.src_ip[0] = m; + return 0; +} + +static inline int ixgbe_mat_prgm_dip(struct ixgbe_fdir_filter *input, + union ixgbe_atr_input *mask, + u32 val, u32 m) +{ + input->filter.formatted.dst_ip[0] = val; + mask->formatted.dst_ip[0] = m; + return 0; +} + +static struct ixgbe_mat_field ixgbe_ipv4_fields[] = { + { .off = 12, .val = ixgbe_mat_prgm_sip, + .type = IXGBE_ATR_FLOW_TYPE_IPV4}, + { .off = 16, .val = ixgbe_mat_prgm_dip, + .type = IXGBE_ATR_FLOW_TYPE_IPV4}, + { .val = NULL } /* terminal node */ +}; + +static inline int ixgbe_mat_prgm_ports(struct ixgbe_fdir_filter *input, + union ixgbe_atr_input *mask, + u32 val, u32 m) +{ + input->filter.formatted.src_port = val & 0xffff; + mask->formatted.src_port = m & 0xffff; + + input->filter.formatted.dst_port = val >> 16; + mask->formatted.dst_port = m >> 16; + + return 0; +}; + +static struct ixgbe_mat_field ixgbe_tcp_fields[] = { + {.off = 0, .val = ixgbe_mat_prgm_ports, + .type = IXGBE_ATR_FLOW_TYPE_TCPV4}, + { .val = NULL } /* terminal node */ +}; + +static struct ixgbe_mat_field ixgbe_udp_fields[] = { + {.off = 0, .val = ixgbe_mat_prgm_ports, + .type = IXGBE_ATR_FLOW_TYPE_UDPV4}, + { .val = NULL } /* terminal node */ +}; + +struct ixgbe_nexthdr { + /* offset, shift, and mask of position to next header */ + unsigned int o; + u32 s; + u32 m; + /* match criteria to make this jump*/ + unsigned int off; + u32 val; + u32 mask; + /* location of jump to make */ + struct ixgbe_mat_field *jump; +}; + +static struct ixgbe_nexthdr ixgbe_ipv4_jumps[] = { + { .o = 0, .s = 6, .m = 0xf, + .off = 8, .val = 0x600, .mask = 0xff00, .jump = ixgbe_tcp_fields}, + { .o = 0, .s = 6, .m = 0xf, + .off = 8, .val = 0x1100, .mask = 0xff00, .jump = ixgbe_udp_fields}, + { .jump = NULL } /* terminal node */ +}; +#endif /* _IXGBE_MODEL_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep.h new file mode 100644 index 0000000000..34ce24b5df --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep.h @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* glue for the OS independent part of ixgbe + * includes register access macros + */ + +#ifndef _IXGBE_OSDEP_H_ +#define _IXGBE_OSDEP_H_ + +#include "kcompat.h" +#include +#include +#include +#include +#include + +#define IXGBE_CPU_TO_BE16(_x) cpu_to_be16(_x) +#define IXGBE_BE16_TO_CPU(_x) be16_to_cpu(_x) +#define IXGBE_CPU_TO_BE32(_x) cpu_to_be32(_x) +#define IXGBE_BE32_TO_CPU(_x) be32_to_cpu(_x) + +#define msec_delay(_x) msleep(_x) + +#define usec_delay(_x) udelay(_x) + +#define STATIC static + +#define IOMEM __iomem + +#ifdef DBG +#define ASSERT(_x) BUG_ON(!(_x)) +#else +#define ASSERT(_x) do {} while (0) +#endif + +#define DEBUGFUNC(S) do {} while (0) + +#define IXGBE_SFP_DETECT_RETRIES 2 + +struct ixgbe_hw; +struct ixgbe_msg { + u16 msg_enable; +}; +struct net_device *ixgbe_hw_to_netdev(const struct ixgbe_hw *hw); +struct ixgbe_msg *ixgbe_hw_to_msg(const struct ixgbe_hw *hw); + +#define ixgbe_info_fwlog(hw, rowsize, groupsize, buf, len) \ + print_hex_dump(KERN_INFO, " FWLOG: ", DUMP_PREFIX_NONE, \ + rowsize, groupsize, buf, len, false) + +#define hw_dbg(hw, format, arg...) \ + netdev_dbg(ixgbe_hw_to_netdev(hw), format, ## arg) +#define hw_err(hw, format, arg...) \ + netdev_err(ixgbe_hw_to_netdev(hw), format, ## arg) +#define e_dev_info(format, arg...) \ + dev_info(ixgbe_pf_to_dev(adapter), format, ## arg) +#define e_dev_warn(format, arg...) \ + dev_warn(ixgbe_pf_to_dev(adapter), format, ## arg) +#define e_dev_err(format, arg...) \ + dev_err(ixgbe_pf_to_dev(adapter), format, ## arg) +#define e_dev_notice(format, arg...) \ + dev_notice(ixgbe_pf_to_dev(adapter), format, ## arg) +#define e_dbg(msglvl, format, arg...) \ + netif_dbg(adapter, msglvl, adapter->netdev, format, ## arg) +#define e_info(msglvl, format, arg...) \ + netif_info(adapter, msglvl, adapter->netdev, format, ## arg) +#define e_err(msglvl, format, arg...) \ + netif_err(adapter, msglvl, adapter->netdev, format, ## arg) +#define e_warn(msglvl, format, arg...) \ + netif_warn(adapter, msglvl, adapter->netdev, format, ## arg) +#define e_crit(msglvl, format, arg...) \ + netif_crit(adapter, msglvl, adapter->netdev, format, ## arg) + +#define IXGBE_DEAD_READ_RETRIES 10 +#define IXGBE_DEAD_READ_REG 0xdeadbeefU +#define IXGBE_FAILED_READ_REG 0xffffffffU +#define IXGBE_FAILED_READ_RETRIES 5 +#define IXGBE_FAILED_READ_CFG_DWORD 0xffffffffU +#define IXGBE_FAILED_READ_CFG_WORD 0xffffU +#define IXGBE_FAILED_READ_CFG_BYTE 0xffU + +#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) \ + IXGBE_WRITE_REG((a), (reg) + ((offset) << 2), (value)) + +#define IXGBE_READ_REG(h, r) ixgbe_read_reg(h, r, false) +#define IXGBE_R32_Q(h, r) ixgbe_read_reg(h, r, true) +#define IXGBE_R8_Q(h, r) readb(READ_ONCE(h->hw_addr) + r) + +#define IXGBE_READ_REG_ARRAY(a, reg, offset) ( \ + IXGBE_READ_REG((a), (reg) + ((offset) << 2))) + +#ifndef writeq +#define writeq(val, addr) do { writel((u32) (val), addr); \ + writel((u32) (val >> 32), (addr + 4)); \ + } while (0); +#endif + +#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS) + +u32 ixgbe_read_reg(struct ixgbe_hw *, u32 reg, bool quiet); +extern u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg); +extern void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value); +extern void ewarn(struct ixgbe_hw *hw, const char *str); + +#define IXGBE_READ_PCIE_WORD ixgbe_read_pci_cfg_word +#define IXGBE_WRITE_PCIE_WORD ixgbe_write_pci_cfg_word +#define IXGBE_EEPROM_GRANT_ATTEMPS 100 +#define IXGBE_HTONL(_i) htonl(_i) +#define IXGBE_NTOHL(_i) ntohl(_i) +#define IXGBE_NTOHS(_i) ntohs(_i) +#define IXGBE_CPU_TO_LE64(_i) cpu_to_le64(_i) +#define IXGBE_CPU_TO_LE32(_i) cpu_to_le32(_i) +#define IXGBE_CPU_TO_LE16(_i) cpu_to_le16(_i) +#define IXGBE_LE16_TO_CPU(_i) le16_to_cpu(_i) +#define IXGBE_LE32_TO_CPU(_i) le32_to_cpu(_i) +#define IXGBE_LE32_TO_CPUS(_i) le32_to_cpus(_i) +#define IXGBE_LE64_TO_CPU(_i) le64_to_cpu(_i) +#define EWARN(H, W) ewarn(H, W) + +#undef TRUE +#define TRUE true +#undef FALSE +#define FALSE false + +enum { + IXGBE_ERROR_SOFTWARE, + IXGBE_ERROR_POLLING, + IXGBE_ERROR_INVALID_STATE, + IXGBE_ERROR_UNSUPPORTED, + IXGBE_ERROR_ARGUMENT, + IXGBE_ERROR_CAUTION, +}; + +#define ERROR_REPORT(level, format, arg...) do { \ + switch (level) { \ + case IXGBE_ERROR_SOFTWARE: \ + case IXGBE_ERROR_CAUTION: \ + case IXGBE_ERROR_POLLING: \ + netif_warn(ixgbe_hw_to_msg(hw), drv, ixgbe_hw_to_netdev(hw), \ + format, ## arg); \ + break; \ + case IXGBE_ERROR_INVALID_STATE: \ + case IXGBE_ERROR_UNSUPPORTED: \ + case IXGBE_ERROR_ARGUMENT: \ + netif_err(ixgbe_hw_to_msg(hw), hw, ixgbe_hw_to_netdev(hw), \ + format, ## arg); \ + break; \ + default: \ + break; \ + } \ +} while (0) + +#define ERROR_REPORT1 ERROR_REPORT +#define ERROR_REPORT2 ERROR_REPORT +#define ERROR_REPORT3 ERROR_REPORT + +#define UNREFERENCED_XPARAMETER +#define UNREFERENCED_1PARAMETER(_p) do { \ + uninitialized_var(_p); \ +} while (0) +#define UNREFERENCED_2PARAMETER(_p, _q) do { \ + uninitialized_var(_p); \ + uninitialized_var(_q); \ +} while (0) +#define UNREFERENCED_3PARAMETER(_p, _q, _r) do { \ + uninitialized_var(_p); \ + uninitialized_var(_q); \ + uninitialized_var(_r); \ +} while (0) +#define UNREFERENCED_4PARAMETER(_p, _q, _r, _s) do { \ + uninitialized_var(_p); \ + uninitialized_var(_q); \ + uninitialized_var(_r); \ + uninitialized_var(_s); \ +} while (0) + +#define ixgbe_malloc(hw, size) kzalloc(size, GFP_KERNEL) +#define ixgbe_calloc(hw, cnt, size) kcalloc(cnt, size, GFP_KERNEL) +#define ixgbe_free(hw, mptr) kfree(mptr) + +#define ixgbe_lock mutex +#define ixgbe_init_lock(lock) mutex_init(lock) +#define ixgbe_destroy_lock(lock) mutex_destroy(lock) +#define ixgbe_acquire_lock(lock) mutex_lock(lock) +#define ixgbe_release_lock(lock) mutex_unlock(lock) + +#endif /* _IXGBE_OSDEP_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep2.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep2.h new file mode 100644 index 0000000000..d65a32d35f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_osdep2.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_OSDEP2_H_ +#define _IXGBE_OSDEP2_H_ + +static inline bool ixgbe_removed(void __iomem *addr) +{ + return unlikely(!addr); +} +#define IXGBE_REMOVED(a) ixgbe_removed(a) + +static inline void IXGBE_WRITE_REG(struct ixgbe_hw *hw, u32 reg, u32 value) +{ + u8 __iomem *reg_addr; + + reg_addr = READ_ONCE(hw->hw_addr); + if (IXGBE_REMOVED(reg_addr)) + return; +#ifdef DBG + { + struct net_device *netdev = ixgbe_hw_to_netdev(hw); + + switch (reg) { + case IXGBE_EIMS: + case IXGBE_EIMC: + case IXGBE_EIAM: + case IXGBE_EIAC: + case IXGBE_EICR: + case IXGBE_EICS: + netdev_info(netdev, + "%s: Reg - 0x%05X, value - 0x%08X\n", + __func__, reg, value); + } + } +#endif /* DBG */ + writel(value, reg_addr + reg); +} + +static inline void IXGBE_WRITE_REG64(struct ixgbe_hw *hw, u32 reg, u64 value) +{ + u8 __iomem *reg_addr; + + reg_addr = READ_ONCE(hw->hw_addr); + if (IXGBE_REMOVED(reg_addr)) + return; + writeq(value, reg_addr + reg); +} + +#endif /* _IXGBE_OSDEP2_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_param.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_param.c new file mode 100644 index 0000000000..b7c11c9adb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_param.c @@ -0,0 +1,1271 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#include +#include + +/* This is the only thing that needs to be changed to adjust the + * maximum number of ports that the driver can manage. + */ + +#define IXGBE_MAX_NIC 32 + +#define OPTION_UNSET -1 +#define OPTION_DISABLED 0 +#define OPTION_ENABLED 1 + +#define STRINGIFY(foo) #foo /* magic for getting defines into strings */ +#define XSTRINGIFY(bar) STRINGIFY(bar) + +/* All parameters are treated the same, as an integer array of values. + * This macro just reduces the need to repeat the same declaration code + * over and over (plus this helps to avoid typo bugs). + */ + +#define IXGBE_PARAM_INIT { [0 ... IXGBE_MAX_NIC] = OPTION_UNSET } +#ifndef module_param_array +/* Module Parameters are always initialized to -1, so that the driver + * can tell the difference between no user specified value or the + * user asking for the default value. + * The true default values are loaded in when ixgbe_check_options is called. + * + * This is a GCC extension to ANSI C. + * See the item "Labelled Elements in Initializers" in the section + * "Extensions to the C Language Family" of the GCC documentation. + */ + +#define IXGBE_PARAM(X, desc) \ + static const int __devinitdata X[IXGBE_MAX_NIC+1] = IXGBE_PARAM_INIT; \ + MODULE_PARM(X, "1-" __MODULE_STRING(IXGBE_MAX_NIC) "i"); \ + MODULE_PARM_DESC(X, desc); +#else +#define IXGBE_PARAM(X, desc) \ + static int __devinitdata X[IXGBE_MAX_NIC+1] = IXGBE_PARAM_INIT; \ + static unsigned int num_##X; \ + module_param_array_named(X, X, int, &num_##X, 0); \ + MODULE_PARM_DESC(X, desc); +#endif + +/* IntMode (Interrupt Mode) + * + * Valid Range: 0-2 + * - 0 - Legacy Interrupt + * - 1 - MSI Interrupt + * - 2 - MSI-X Interrupt(s) + * + * Default Value: 2 + */ +IXGBE_PARAM(IntMode, "Change Interrupt Mode (0=Legacy, 1=MSI, 2=MSI-X), " + "default 2"); +#define IXGBE_INT_LEGACY 0 +#define IXGBE_INT_MSI 1 +#define IXGBE_INT_MSIX 2 + +IXGBE_PARAM(InterruptType, "Change Interrupt Mode (0=Legacy, 1=MSI, 2=MSI-X), " + "default IntMode (deprecated)"); + +/* MQ - Multiple Queue enable/disable + * + * Valid Range: 0, 1 + * - 0 - disables MQ + * - 1 - enables MQ + * + * Default Value: 1 + */ + +IXGBE_PARAM(MQ, "Disable or enable Multiple Queues, default 1"); + +#if IS_ENABLED(CONFIG_DCA) +/* DCA - Direct Cache Access (DCA) Control + * + * This option allows the device to hint to DCA enabled processors + * which CPU should have its cache warmed with the data being + * transferred over PCIe. This can increase performance by reducing + * cache misses. ixgbe hardware supports DCA for: + * tx descriptor writeback + * rx descriptor writeback + * rx data + * rx data header only (in packet split mode) + * + * enabling option 2 can cause cache thrash in some tests, particularly + * if the CPU is completely utilized + * + * Valid Range: 0 - 2 + * - 0 - disables DCA + * - 1 - enables DCA + * - 2 - enables DCA with rx data included + * + * Default Value: 2 + */ + +#define IXGBE_MAX_DCA 2 + +IXGBE_PARAM(DCA, "Disable or enable Direct Cache Access, 0=disabled, " + "1=descriptor only, 2=descriptor and data"); +#endif /* CONFIG_DCA */ + +/* RSS - Receive-Side Scaling (RSS) Descriptor Queues + * + * Valid Range: 0-16 + * - 0 - enables RSS and sets the Desc. Q's to min(16, num_online_cpus()). + * - 1-16 - enables RSS and sets the Desc. Q's to the specified value. + * + * Default Value: 0 + */ + +IXGBE_PARAM(RSS, "Number of Receive-Side Scaling Descriptor Queues, " + "default 0=number of cpus"); + + +/* VMDQ - Virtual Machine Device Queues (VMDQ) + * + * Valid Range: 1-16 + * - 0/1 Disables VMDQ by allocating only a single queue. + * - 2-16 - enables VMDQ and sets the Desc. Q's to the specified value. + * + * Default Value: 8 + */ + +#define IXGBE_DEFAULT_NUM_VMDQ 8 + +IXGBE_PARAM(VMDQ, "Number of Virtual Machine Device Queues: 0/1 = disable (1 queue) " + "2-16 enable (default=" XSTRINGIFY(IXGBE_DEFAULT_NUM_VMDQ) ")"); + +#ifdef CONFIG_PCI_IOV +/* max_vfs - SR I/O Virtualization + * + * Valid Range: 0-63 + * - 0 Disables SR-IOV + * - 1-63 - enables SR-IOV and sets the number of VFs enabled + * + * Default Value: 0 + */ + +#define MAX_SRIOV_VFS 63 + +IXGBE_PARAM(max_vfs, "Number of Virtual Functions: 0 = disable (default), " + "1-" XSTRINGIFY(MAX_SRIOV_VFS) " = enable " + "this many VFs"); + +/* VEPA - Set internal bridge to VEPA mode + * + * Valid Range: 0-1 + * - 0 Set bridge to VEB mode + * - 1 Set bridge to VEPA mode + * + * Default Value: 0 + */ +/* + *Note: + *===== + * This provides ability to ensure VEPA mode on the internal bridge even if + * the kernel does not support the netdev bridge setting operations. +*/ +IXGBE_PARAM(VEPA, "VEPA Bridge Mode: 0 = VEB (default), 1 = VEPA"); +#endif + +/* Interrupt Throttle Rate (interrupts/sec) + * + * Valid Range: 956-488281 (0=off, 1=dynamic) + * + * Default Value: 1 + */ +#define DEFAULT_ITR 1 +IXGBE_PARAM(InterruptThrottleRate, "Maximum interrupts per second, per vector, " + "(0,1,956-488281), default 1"); +#define MAX_ITR IXGBE_MAX_INT_RATE +#define MIN_ITR IXGBE_MIN_INT_RATE + +#ifndef IXGBE_NO_LLI + +/* LLIPort (Low Latency Interrupt TCP Port) + * + * Valid Range: 0 - 65535 + * + * Default Value: 0 (disabled) + */ +IXGBE_PARAM(LLIPort, "Low Latency Interrupt TCP Port (0-65535)"); + +#define DEFAULT_LLIPORT 0 +#define MAX_LLIPORT 0xFFFF +#define MIN_LLIPORT 0 + +/* LLIPush (Low Latency Interrupt on TCP Push flag) + * + * Valid Range: 0,1 + * + * Default Value: 0 (disabled) + */ +IXGBE_PARAM(LLIPush, "Low Latency Interrupt on TCP Push flag (0,1)"); + +#define DEFAULT_LLIPUSH 0 +#define MAX_LLIPUSH 1 +#define MIN_LLIPUSH 0 + +/* LLISize (Low Latency Interrupt on Packet Size) + * + * Valid Range: 0 - 1500 + * + * Default Value: 0 (disabled) + */ +IXGBE_PARAM(LLISize, "Low Latency Interrupt on Packet Size (0-1500)"); + +#define DEFAULT_LLISIZE 0 +#define MAX_LLISIZE 1500 +#define MIN_LLISIZE 0 + +/* LLIEType (Low Latency Interrupt Ethernet Type) + * + * Valid Range: 0 - 0x8fff + * + * Default Value: 0 (disabled) + */ +IXGBE_PARAM(LLIEType, "Low Latency Interrupt Ethernet Protocol Type"); + +#define DEFAULT_LLIETYPE 0 +#define MAX_LLIETYPE 0x8fff +#define MIN_LLIETYPE 0 + +/* LLIVLANP (Low Latency Interrupt on VLAN priority threshold) + * + * Valid Range: 0 - 7 + * + * Default Value: 0 (disabled) + */ +IXGBE_PARAM(LLIVLANP, "Low Latency Interrupt on VLAN priority threshold"); + +#define DEFAULT_LLIVLANP 0 +#define MAX_LLIVLANP 7 +#define MIN_LLIVLANP 0 + +#endif /* IXGBE_NO_LLI */ +#ifdef HAVE_TX_MQ +/* Flow Director packet buffer allocation level + * + * Valid Range: 1-3 + * 1 = 8k hash/2k perfect, + * 2 = 16k hash/4k perfect, + * 3 = 32k hash/8k perfect + * + * Default Value: 0 + */ +IXGBE_PARAM(FdirPballoc, "Flow Director packet buffer allocation level:\n" + "\t\t\t1 = 8k hash filters or 2k perfect filters\n" + "\t\t\t2 = 16k hash filters or 4k perfect filters\n" + "\t\t\t3 = 32k hash filters or 8k perfect filters"); + +#define IXGBE_DEFAULT_FDIR_PBALLOC IXGBE_FDIR_PBALLOC_64K + +/* Software ATR packet sample rate + * + * Valid Range: 0-255 0 = off, 1-255 = rate of Tx packet inspection + * + * Default Value: 20 + */ +IXGBE_PARAM(AtrSampleRate, "Software ATR Tx packet sample rate"); + +#define IXGBE_MAX_ATR_SAMPLE_RATE 255 +#define IXGBE_MIN_ATR_SAMPLE_RATE 1 +#define IXGBE_ATR_SAMPLE_RATE_OFF 0 +#define IXGBE_DEFAULT_ATR_SAMPLE_RATE 20 +#endif /* HAVE_TX_MQ */ + +#if IS_ENABLED(CONFIG_FCOE) +/* FCoE - Fibre Channel over Ethernet Offload Enable/Disable + * + * Valid Range: 0, 1 + * - 0 - disables FCoE Offload + * - 1 - enables FCoE Offload + * + * Default Value: 1 + */ +IXGBE_PARAM(FCoE, "Disable or enable FCoE Offload, default 1"); +#endif /* CONFIG_FCOE */ + +/* Enable/disable Malicious Driver Detection + * + * Valid Values: 0(off), 1(on) + * + * Default Value: 1 + */ +IXGBE_PARAM(MDD, "Malicious Driver Detection: (0,1), default 1 = on"); + +/* Enable/disable Large Receive Offload + * + * Valid Values: 0(off), 1(on) + * + * Default Value: 1 + */ +IXGBE_PARAM(LRO, "Large Receive Offload (0,1), default 0 = off"); + +/* Enable/disable support for untested SFP+ modules on 82599-based adapters + * + * Valid Values: 0(Disable), 1(Enable) + * + * Default Value: 0 + */ +IXGBE_PARAM(allow_unsupported_sfp, "Allow unsupported and untested " + "SFP+ modules on 82599 based adapters, default 0 = Disable"); + +/* Enable/disable support for DMA coalescing + * + * Valid Values: 0(off), 41 - 10000(on) + * + * Default Value: 0 + */ +IXGBE_PARAM(dmac_watchdog, + "DMA coalescing watchdog in microseconds (0,41-10000), default 0 = off"); + +/* Enable/disable support for VXLAN rx checksum offload + * + * Valid Values: 0(Disable), 1(Enable) + * + * Default Value: 1 on hardware that supports it + */ +IXGBE_PARAM(vxlan_rx, + "VXLAN receive checksum offload (0,1), default 1 = Enable"); + + +struct ixgbe_option { + enum { enable_option, range_option, list_option } type; + const char *name; + const char *err; + const char *msg; + int def; + union { + struct { /* range_option info */ + int min; + int max; + } r; + struct { /* list_option info */ + int nr; + const struct ixgbe_opt_list { + int i; + char *str; + } *p; + } l; + } arg; +}; + +#ifndef IXGBE_NO_LLI +#ifdef module_param_array +/** + * ixgbe_lli_supported - helper function to determine LLI support + * @adapter: board private structure + * @opt: pointer to option struct + * + * LLI is only supported for 82599 and X540 + * LLIPush is not supported on 82599 + **/ +#ifdef HAVE_CONFIG_HOTPLUG +static bool __devinit ixgbe_lli_supported(struct ixgbe_adapter *adapter, + struct ixgbe_option *opt) +#else +static bool ixgbe_lli_supported(struct ixgbe_adapter *adapter, + struct ixgbe_option *opt) +#endif +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (hw->mac.type == ixgbe_mac_82599EB) { + + if (LLIPush[adapter->bd_number] > 0) + goto not_supp; + + return true; + } + + if (hw->mac.type == ixgbe_mac_X540) + return true; + +not_supp: + DPRINTK(PROBE, INFO, "%s not supported on this HW\n", opt->name); + return false; +} +#endif /* module_param_array */ +#endif /* IXGBE_NO_LLI */ + +#ifdef HAVE_CONFIG_HOTPLUG +static int __devinit ixgbe_validate_option(struct net_device *netdev, + unsigned int *value, + struct ixgbe_option *opt) +#else +static int ixgbe_validate_option(struct net_device *netdev, + unsigned int *value, + struct ixgbe_option *opt) +#endif +{ + if (*value == OPTION_UNSET) { + netdev_info(netdev, "Invalid %s specified (%d), %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return 0; + } + + switch (opt->type) { + case enable_option: + switch (*value) { + case OPTION_ENABLED: + netdev_info(netdev, "%s Enabled\n", opt->name); + return 0; + case OPTION_DISABLED: + netdev_info(netdev, "%s Disabled\n", opt->name); + return 0; + } + break; + case range_option: + if ((*value >= opt->arg.r.min && *value <= opt->arg.r.max) || + *value == opt->def) { + if (opt->msg) + netdev_info(netdev, "%s set to %d, %s\n", + opt->name, *value, opt->msg); + else + netdev_info(netdev, "%s set to %d\n", + opt->name, *value); + return 0; + } + break; + case list_option: { + int i; + + for (i = 0; i < opt->arg.l.nr; i++) { + const struct ixgbe_opt_list *ent = &opt->arg.l.p[i]; + if (*value == ent->i) { + if (ent->str[0] != '\0') + netdev_info(netdev, "%s\n", ent->str); + return 0; + } + } + } + break; + default: + BUG(); + } + + netdev_info(netdev, "Invalid %s specified (%d), %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return -1; +} + +#define LIST_LEN(l) (sizeof(l) / sizeof(l[0])) +#define PSTR_LEN 10 + +/** + * ixgbe_check_options - Range Checking for Command Line Parameters + * @adapter: board private structure + * + * This routine checks all command line parameters for valid user + * input. If an invalid value is given, or if no user specified + * value exists, a default value is used. The final value is stored + * in a variable in the adapter structure. + **/ +#ifdef HAVE_CONFIG_HOTPLUG +void __devinit ixgbe_check_options(struct ixgbe_adapter *adapter) +#else +void ixgbe_check_options(struct ixgbe_adapter *adapter) +#endif +{ + unsigned int mdd; + int bd = adapter->bd_number; + u32 *aflags = &adapter->flags; + struct ixgbe_ring_feature *feature = adapter->ring_feature; + unsigned int vmdq; + + if (bd >= IXGBE_MAX_NIC) { + netdev_notice(adapter->netdev, + "Warning: no configuration for board #%d\n", bd); + netdev_notice(adapter->netdev, + "Using defaults for all values\n"); +#ifndef module_param_array + bd = IXGBE_MAX_NIC; +#endif + } + + + { /* Interrupt Mode */ + unsigned int int_mode; + static struct ixgbe_option opt = { + .type = range_option, + .name = "Interrupt Mode", + .err = + "using default of " __MODULE_STRING(IXGBE_INT_MSIX), + .def = IXGBE_INT_MSIX, + .arg = { .r = { .min = IXGBE_INT_LEGACY, + .max = IXGBE_INT_MSIX} } + }; + +#ifdef module_param_array + if (num_IntMode > bd || num_InterruptType > bd) { +#endif + int_mode = IntMode[bd]; + if (int_mode == OPTION_UNSET) + int_mode = InterruptType[bd]; + ixgbe_validate_option(adapter->netdev, + &int_mode, &opt); + switch (int_mode) { + case IXGBE_INT_MSIX: + if (!(*aflags & IXGBE_FLAG_MSIX_CAPABLE)) + netdev_info(adapter->netdev, + "Ignoring MSI-X setting; " + "support unavailable\n"); + break; + case IXGBE_INT_MSI: + if (!(*aflags & IXGBE_FLAG_MSI_CAPABLE)) { + netdev_info(adapter->netdev, + "Ignoring MSI setting; " + "support unavailable\n"); + } else { + *aflags &= ~IXGBE_FLAG_MSIX_CAPABLE; + } + break; + case IXGBE_INT_LEGACY: + default: + *aflags &= ~IXGBE_FLAG_MSIX_CAPABLE; + *aflags &= ~IXGBE_FLAG_MSI_CAPABLE; + break; + } +#ifdef module_param_array + } else { + /* default settings */ + if (*aflags & IXGBE_FLAG_MSIX_CAPABLE) { + *aflags |= IXGBE_FLAG_MSI_CAPABLE; + } else { + *aflags &= ~IXGBE_FLAG_MSIX_CAPABLE; + *aflags &= ~IXGBE_FLAG_MSI_CAPABLE; + } + } +#endif + } + { /* Multiple Queue Support */ + static struct ixgbe_option opt = { + .type = enable_option, + .name = "Multiple Queue Support", + .err = "defaulting to Enabled", + .def = OPTION_ENABLED + }; + +#ifdef module_param_array + if (num_MQ > bd) { +#endif + unsigned int mq = MQ[bd]; + ixgbe_validate_option(adapter->netdev, &mq, &opt); + if (mq) + *aflags |= IXGBE_FLAG_MQ_CAPABLE; + else + *aflags &= ~IXGBE_FLAG_MQ_CAPABLE; +#ifdef module_param_array + } else { + *aflags |= IXGBE_FLAG_MQ_CAPABLE; + } +#endif + /* Check Interoperability */ + if ((*aflags & IXGBE_FLAG_MQ_CAPABLE) && + !(*aflags & IXGBE_FLAG_MSIX_CAPABLE)) { + DPRINTK(PROBE, INFO, + "Multiple queues are not supported while MSI-X " + "is disabled. Disabling Multiple Queues.\n"); + *aflags &= ~IXGBE_FLAG_MQ_CAPABLE; + } + } +#if IS_ENABLED(CONFIG_DCA) + { /* Direct Cache Access (DCA) */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Direct Cache Access (DCA)", + .err = "defaulting to Enabled", + .def = IXGBE_MAX_DCA, + .arg = { .r = { .min = OPTION_DISABLED, + .max = IXGBE_MAX_DCA} } + }; + unsigned int dca = opt.def; + +#ifdef module_param_array + if (num_DCA > bd) { +#endif + dca = DCA[bd]; + ixgbe_validate_option(adapter->netdev, &dca, &opt); + if (!dca) + *aflags &= ~IXGBE_FLAG_DCA_CAPABLE; + + /* Check Interoperability */ + if (!(*aflags & IXGBE_FLAG_DCA_CAPABLE)) { + DPRINTK(PROBE, INFO, "DCA is disabled\n"); + *aflags &= ~IXGBE_FLAG_DCA_ENABLED; + } + + if (dca == IXGBE_MAX_DCA) { + DPRINTK(PROBE, INFO, + "DCA enabled for rx data\n"); + adapter->flags |= IXGBE_FLAG_DCA_ENABLED_DATA; + } +#ifdef module_param_array + } else { + /* make sure to clear the capability flag if the + * option is disabled by default above */ + if (opt.def == OPTION_DISABLED) + *aflags &= ~IXGBE_FLAG_DCA_CAPABLE; + } +#endif + if (dca == IXGBE_MAX_DCA) + adapter->flags |= IXGBE_FLAG_DCA_ENABLED_DATA; + } +#endif /* CONFIG_DCA */ + { /* Receive-Side Scaling (RSS) */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Receive-Side Scaling (RSS)", + .err = "using default.", + .def = 0, + .arg = { .r = { .min = 0, + .max = 16} } + }; + unsigned int rss = RSS[bd]; + /* adjust Max allowed RSS queues based on MAC type */ + opt.arg.r.max = ixgbe_max_rss_indices(adapter); + +#ifdef module_param_array + if (num_RSS > bd) { +#endif + ixgbe_validate_option(adapter->netdev, &rss, &opt); + /* base it off num_online_cpus() with hardware limit */ + if (!rss) + rss = min_t(int, opt.arg.r.max, + num_online_cpus()); + else + feature[RING_F_FDIR].limit = rss; + + feature[RING_F_RSS].limit = rss; +#ifdef module_param_array + } else if (opt.def == 0) { + rss = min_t(int, ixgbe_max_rss_indices(adapter), + num_online_cpus()); + feature[RING_F_RSS].limit = rss; + } +#endif + /* Check Interoperability */ + if (rss > 1) { + if (!(*aflags & IXGBE_FLAG_MQ_CAPABLE)) { + DPRINTK(PROBE, INFO, + "Multiqueue is disabled. " + "Limiting RSS.\n"); + feature[RING_F_RSS].limit = 1; + } + } + } + { /* Virtual Machine Device Queues (VMDQ) */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Virtual Machine Device Queues (VMDQ)", + .err = "defaulting to Disabled", + .def = OPTION_DISABLED, + .arg = { .r = { .min = OPTION_DISABLED, + .max = IXGBE_MAX_VMDQ_INDICES + } } + }; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + /* 82598 only supports up to 16 pools */ + opt.arg.r.max = 16; + break; + default: + break; + } + +#ifdef module_param_array + if (num_VMDQ > bd) { +#endif + vmdq = VMDQ[bd]; + + ixgbe_validate_option(adapter->netdev, &vmdq, &opt); + + /* zero or one both mean disabled from our driver's + * perspective */ + if (vmdq > 1) { + *aflags |= IXGBE_FLAG_VMDQ_ENABLED; + } else + *aflags &= ~IXGBE_FLAG_VMDQ_ENABLED; + + feature[RING_F_VMDQ].limit = vmdq; +#ifdef module_param_array + } else { + if (opt.def == OPTION_DISABLED) + *aflags &= ~IXGBE_FLAG_VMDQ_ENABLED; + else + *aflags |= IXGBE_FLAG_VMDQ_ENABLED; + + feature[RING_F_VMDQ].limit = opt.def; + } +#endif + /* Check Interoperability */ + if (*aflags & IXGBE_FLAG_VMDQ_ENABLED) { + if (!(*aflags & IXGBE_FLAG_MQ_CAPABLE)) { + DPRINTK(PROBE, INFO, + "VMDQ is not supported while multiple " + "queues are disabled. " + "Disabling VMDQ.\n"); + *aflags &= ~IXGBE_FLAG_VMDQ_ENABLED; + feature[RING_F_VMDQ].limit = 0; + } + } + } +#ifdef CONFIG_PCI_IOV + { /* Single Root I/O Virtualization (SR-IOV) */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "I/O Virtualization (IOV)", + .err = "defaulting to Disabled", + .def = OPTION_DISABLED, + .arg = { .r = { .min = OPTION_DISABLED, + .max = MAX_SRIOV_VFS} } + }; + +#ifdef module_param_array + if (num_max_vfs > bd) { +#endif + unsigned int vfs = max_vfs[bd]; + if (ixgbe_validate_option(adapter->netdev, + &vfs, &opt)) { + vfs = 0; + DPRINTK(PROBE, INFO, + "max_vfs out of range " + "Disabling SR-IOV.\n"); + } + + adapter->max_vfs = vfs; + + if (vfs) + *aflags |= IXGBE_FLAG_SRIOV_ENABLED; + else + *aflags &= ~IXGBE_FLAG_SRIOV_ENABLED; +#ifdef module_param_array + } else { + if (opt.def == OPTION_DISABLED) { + adapter->max_vfs = 0; + *aflags &= ~IXGBE_FLAG_SRIOV_ENABLED; + } else { + adapter->max_vfs = opt.def; + *aflags |= IXGBE_FLAG_SRIOV_ENABLED; + } + } +#endif + + /* Check Interoperability */ + if (*aflags & IXGBE_FLAG_SRIOV_ENABLED) { + if (!(*aflags & IXGBE_FLAG_SRIOV_CAPABLE)) { + DPRINTK(PROBE, INFO, + "IOV is not supported on this " + "hardware. Disabling IOV.\n"); + *aflags &= ~IXGBE_FLAG_SRIOV_ENABLED; + adapter->max_vfs = 0; + } else if (!(*aflags & IXGBE_FLAG_MQ_CAPABLE)) { + DPRINTK(PROBE, INFO, + "IOV is not supported while multiple " + "queues are disabled. " + "Disabling IOV.\n"); + *aflags &= ~IXGBE_FLAG_SRIOV_ENABLED; + adapter->max_vfs = 0; + } + } + } + { /* VEPA Bridge Mode enable for SR-IOV mode */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "VEPA Bridge Mode Enable", + .err = "defaulting to disabled", + .def = OPTION_DISABLED, + .arg = { .r = { .min = OPTION_DISABLED, + .max = OPTION_ENABLED} } + }; + +#ifdef module_param_array + if (num_VEPA > bd) { +#endif + unsigned int vepa = VEPA[bd]; + ixgbe_validate_option(adapter->netdev, &vepa, &opt); + if (vepa) + adapter->flags |= + IXGBE_FLAG_SRIOV_VEPA_BRIDGE_MODE; +#ifdef module_param_array + } else { + if (opt.def == OPTION_ENABLED) + adapter->flags |= + IXGBE_FLAG_SRIOV_VEPA_BRIDGE_MODE; + } +#endif + } +#endif /* CONFIG_PCI_IOV */ + { /* Interrupt Throttling Rate */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Interrupt Throttling Rate (ints/sec)", + .err = "using default of "__MODULE_STRING(DEFAULT_ITR), + .def = DEFAULT_ITR, + .arg = { .r = { .min = MIN_ITR, + .max = MAX_ITR } } + }; + +#ifdef module_param_array + if (num_InterruptThrottleRate > bd) { +#endif + u32 itr = InterruptThrottleRate[bd]; + switch (itr) { + case 0: + DPRINTK(PROBE, INFO, "%s turned off\n", + opt.name); + adapter->rx_itr_setting = 0; + break; + case 1: + DPRINTK(PROBE, INFO, "dynamic interrupt " + "throttling enabled\n"); + adapter->rx_itr_setting = 1; + break; + default: + ixgbe_validate_option(adapter->netdev, + &itr, &opt); + /* the first bit is used as control */ + adapter->rx_itr_setting = (1000000/itr) << 2; + break; + } + adapter->tx_itr_setting = adapter->rx_itr_setting; +#ifdef module_param_array + } else { + adapter->rx_itr_setting = opt.def; + adapter->tx_itr_setting = opt.def; + } +#endif + } +#ifndef IXGBE_NO_LLI + { /* Low Latency Interrupt TCP Port*/ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Low Latency Interrupt TCP Port", + .err = "using default of " + __MODULE_STRING(DEFAULT_LLIPORT), + .def = DEFAULT_LLIPORT, + .arg = { .r = { .min = MIN_LLIPORT, + .max = MAX_LLIPORT } } + }; + +#ifdef module_param_array + if (num_LLIPort > bd && ixgbe_lli_supported(adapter, &opt)) { +#endif + adapter->lli_port = LLIPort[bd]; + if (adapter->lli_port) { + ixgbe_validate_option(adapter->netdev, + &adapter->lli_port, &opt); + } else { + DPRINTK(PROBE, INFO, "%s turned off\n", + opt.name); + } +#ifdef module_param_array + } else { + adapter->lli_port = opt.def; + } +#endif + } + { /* Low Latency Interrupt on Packet Size */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Low Latency Interrupt on Packet Size", + .err = "using default of " + __MODULE_STRING(DEFAULT_LLISIZE), + .def = DEFAULT_LLISIZE, + .arg = { .r = { .min = MIN_LLISIZE, + .max = MAX_LLISIZE } } + }; + +#ifdef module_param_array + if (num_LLISize > bd && ixgbe_lli_supported(adapter, &opt)) { +#endif + adapter->lli_size = LLISize[bd]; + if (adapter->lli_size) { + ixgbe_validate_option(adapter->netdev, + &adapter->lli_size, &opt); + } else { + DPRINTK(PROBE, INFO, "%s turned off\n", + opt.name); + } +#ifdef module_param_array + } else { + adapter->lli_size = opt.def; + } +#endif + } + { /*Low Latency Interrupt on TCP Push flag*/ + static struct ixgbe_option opt = { + .type = enable_option, + .name = "Low Latency Interrupt on TCP Push flag", + .err = "defaulting to Disabled", + .def = OPTION_DISABLED + }; + +#ifdef module_param_array + if (num_LLIPush > bd && ixgbe_lli_supported(adapter, &opt)) { +#endif + unsigned int lli_push = LLIPush[bd]; + + ixgbe_validate_option(adapter->netdev, + &lli_push, &opt); + if (lli_push) + *aflags |= IXGBE_FLAG_LLI_PUSH; + else + *aflags &= ~IXGBE_FLAG_LLI_PUSH; +#ifdef module_param_array + } else { + *aflags &= ~IXGBE_FLAG_LLI_PUSH; + } +#endif + } + { /* Low Latency Interrupt EtherType*/ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Low Latency Interrupt on Ethernet Protocol " + "Type", + .err = "using default of " + __MODULE_STRING(DEFAULT_LLIETYPE), + .def = DEFAULT_LLIETYPE, + .arg = { .r = { .min = MIN_LLIETYPE, + .max = MAX_LLIETYPE } } + }; + +#ifdef module_param_array + if (num_LLIEType > bd && ixgbe_lli_supported(adapter, &opt)) { +#endif + adapter->lli_etype = LLIEType[bd]; + if (adapter->lli_etype) { + ixgbe_validate_option(adapter->netdev, + &adapter->lli_etype, + &opt); + } else { + DPRINTK(PROBE, INFO, "%s turned off\n", + opt.name); + } +#ifdef module_param_array + } else { + adapter->lli_etype = opt.def; + } +#endif + } + { /* LLI VLAN Priority */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Low Latency Interrupt on VLAN priority " + "threshold", + .err = "using default of " + __MODULE_STRING(DEFAULT_LLIVLANP), + .def = DEFAULT_LLIVLANP, + .arg = { .r = { .min = MIN_LLIVLANP, + .max = MAX_LLIVLANP } } + }; + +#ifdef module_param_array + if (num_LLIVLANP > bd && ixgbe_lli_supported(adapter, &opt)) { +#endif + adapter->lli_vlan_pri = LLIVLANP[bd]; + if (adapter->lli_vlan_pri) { + ixgbe_validate_option(adapter->netdev, + &adapter->lli_vlan_pri, + &opt); + } else { + DPRINTK(PROBE, INFO, "%s turned off\n", + opt.name); + } +#ifdef module_param_array + } else { + adapter->lli_vlan_pri = opt.def; + } +#endif + } +#endif /* IXGBE_NO_LLI */ +#ifdef HAVE_TX_MQ + { /* Flow Director packet buffer allocation */ + unsigned int fdir_pballoc_mode; + static struct ixgbe_option opt = { + .type = range_option, + .name = "Flow Director packet buffer allocation", + .err = "using default of " + __MODULE_STRING(IXGBE_DEFAULT_FDIR_PBALLOC), + .def = IXGBE_DEFAULT_FDIR_PBALLOC, + .arg = {.r = {.min = IXGBE_FDIR_PBALLOC_64K, + .max = IXGBE_FDIR_PBALLOC_256K} } + }; + char pstring[PSTR_LEN]; + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + adapter->fdir_pballoc = IXGBE_FDIR_PBALLOC_NONE; + } else if (num_FdirPballoc > bd) { + fdir_pballoc_mode = FdirPballoc[bd]; + ixgbe_validate_option(adapter->netdev, + &fdir_pballoc_mode, &opt); + switch (fdir_pballoc_mode) { + case IXGBE_FDIR_PBALLOC_256K: + adapter->fdir_pballoc = IXGBE_FDIR_PBALLOC_256K; + snprintf(pstring, PSTR_LEN, "256kB"); + break; + case IXGBE_FDIR_PBALLOC_128K: + adapter->fdir_pballoc = IXGBE_FDIR_PBALLOC_128K; + snprintf(pstring, PSTR_LEN, "128kB"); + break; + case IXGBE_FDIR_PBALLOC_64K: + default: + adapter->fdir_pballoc = IXGBE_FDIR_PBALLOC_64K; + snprintf(pstring, PSTR_LEN, "64kB"); + break; + } + DPRINTK(PROBE, INFO, "Flow Director will be allocated " + "%s of packet buffer\n", pstring); + } else { + adapter->fdir_pballoc = opt.def; + } + + } + { /* Flow Director ATR Tx sample packet rate */ + static struct ixgbe_option opt = { + .type = range_option, + .name = "Software ATR Tx packet sample rate", + .err = "using default of " + __MODULE_STRING(IXGBE_DEFAULT_ATR_SAMPLE_RATE), + .def = IXGBE_DEFAULT_ATR_SAMPLE_RATE, + .arg = {.r = {.min = IXGBE_ATR_SAMPLE_RATE_OFF, + .max = IXGBE_MAX_ATR_SAMPLE_RATE} } + }; + static const char atr_string[] = + "ATR Tx Packet sample rate set to"; + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + adapter->atr_sample_rate = IXGBE_ATR_SAMPLE_RATE_OFF; + } else if (num_AtrSampleRate > bd) { + adapter->atr_sample_rate = AtrSampleRate[bd]; + + if (adapter->atr_sample_rate) { + ixgbe_validate_option(adapter->netdev, + &adapter->atr_sample_rate, + &opt); + DPRINTK(PROBE, INFO, "%s %d\n", atr_string, + adapter->atr_sample_rate); + } + } else { + adapter->atr_sample_rate = opt.def; + } + } +#endif /* HAVE_TX_MQ */ +#if IS_ENABLED(CONFIG_FCOE) + { + *aflags &= ~IXGBE_FLAG_FCOE_CAPABLE; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_E610: + case ixgbe_mac_82599EB: { + struct ixgbe_option opt = { + .type = enable_option, + .name = "Enabled/Disable FCoE offload", + .err = "defaulting to Enabled", + .def = OPTION_ENABLED + }; +#ifdef module_param_array + if (num_FCoE > bd) { +#endif + unsigned int fcoe = FCoE[bd]; + + ixgbe_validate_option(adapter->netdev, + &fcoe, &opt); + if (fcoe) + *aflags |= IXGBE_FLAG_FCOE_CAPABLE; +#ifdef module_param_array + } else { + if (opt.def == OPTION_ENABLED) + *aflags |= IXGBE_FLAG_FCOE_CAPABLE; + } +#endif + DPRINTK(PROBE, INFO, "FCoE Offload feature %sabled\n", + (*aflags & IXGBE_FLAG_FCOE_CAPABLE) ? + "en" : "dis"); + } + break; + default: + break; + } + } +#endif /* CONFIG_FCOE */ + { /* LRO - Set Large Receive Offload */ + struct ixgbe_option opt = { + .type = enable_option, + .name = "LRO - Large Receive Offload", + .err = "defaulting to Disabled", + .def = OPTION_DISABLED + }; + struct net_device *netdev = adapter->netdev; + + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) + opt.def = OPTION_DISABLED; + +#ifdef module_param_array + if (num_LRO > bd) { +#endif + unsigned int lro = LRO[bd]; + ixgbe_validate_option(adapter->netdev, &lro, &opt); + if (lro) + netdev->features |= NETIF_F_LRO; + else + netdev->features &= ~NETIF_F_LRO; +#ifdef module_param_array + } else { + netdev->features &= ~NETIF_F_LRO; + } +#endif + if ((netdev->features & NETIF_F_LRO) && + !(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) { + DPRINTK(PROBE, INFO, + "RSC is not supported on this " + "hardware. Disabling RSC.\n"); + netdev->features &= ~NETIF_F_LRO; + } + } + { /* + * allow_unsupported_sfp - Enable/Disable support for unsupported + * and untested SFP+ modules. + */ + struct ixgbe_option opt = { + .type = enable_option, + .name = "allow_unsupported_sfp", + .err = "defaulting to Disabled", + .def = OPTION_DISABLED + }; +#ifdef module_param_array + if (num_allow_unsupported_sfp > bd) { +#endif + unsigned int enable_unsupported_sfp = + allow_unsupported_sfp[bd]; + ixgbe_validate_option(adapter->netdev, + &enable_unsupported_sfp, &opt); + if (enable_unsupported_sfp) { + adapter->hw.allow_unsupported_sfp = true; + } else { + adapter->hw.allow_unsupported_sfp = false; + } +#ifdef module_param_array + } else { + adapter->hw.allow_unsupported_sfp = false; + } +#endif + } + { /* DMA Coalescing */ + struct ixgbe_option opt = { + .type = range_option, + .name = "dmac_watchdog", + .err = "defaulting to 0 (disabled)", + .def = 0, + .arg = { .r = { .min = 41, .max = 10000 } }, + }; + const char *cmsg = "DMA coalescing not supported on this hardware"; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + if (adapter->rx_itr_setting || adapter->tx_itr_setting) + break; + opt.err = "interrupt throttling disabled also disables DMA coalescing"; + opt.arg.r.min = 0; + opt.arg.r.max = 0; + break; + default: + opt.err = cmsg; + opt.msg = cmsg; + opt.arg.r.min = 0; + opt.arg.r.max = 0; + } +#ifdef module_param_array + if (num_dmac_watchdog > bd) { +#endif + unsigned int dmac_wd = dmac_watchdog[bd]; + + ixgbe_validate_option(adapter->netdev, &dmac_wd, &opt); + adapter->hw.mac.dmac_config.watchdog_timer = dmac_wd; +#ifdef module_param_array + } else { + adapter->hw.mac.dmac_config.watchdog_timer = opt.def; + } +#endif + } + { /* VXLAN rx offload */ + struct ixgbe_option opt = { + .type = range_option, + .name = "vxlan_rx", + .err = "defaulting to 1 (enabled)", + .def = 1, + .arg = { .r = { .min = 0, .max = 1 } }, + }; + const char *cmsg = "VXLAN rx offload not supported on this hardware"; + const u32 flag = IXGBE_FLAG_VXLAN_OFFLOAD_ENABLE; + + if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) { + opt.err = cmsg; + opt.msg = cmsg; + opt.def = 0; + opt.arg.r.max = 0; + } +#ifdef module_param_array + if (num_vxlan_rx > bd) { +#endif + unsigned int enable_vxlan_rx = vxlan_rx[bd]; + + ixgbe_validate_option(adapter->netdev, + &enable_vxlan_rx, &opt); + if (enable_vxlan_rx) + adapter->flags |= flag; + else + adapter->flags &= ~flag; +#ifdef module_param_array + } else if (opt.def) { + adapter->flags |= flag; + } else { + adapter->flags &= ~flag; + } +#endif + } + { /* MDD support */ + struct ixgbe_option opt = { + .type = enable_option, + .name = "Malicious Driver Detection", + .err = "defaulting to Enabled", + .def = OPTION_ENABLED, + }; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: +#ifdef module_param_array + if (num_MDD > bd) { +#endif + mdd = MDD[bd]; + ixgbe_validate_option(adapter->netdev, + &mdd, &opt); + + if (mdd){ + *aflags |= IXGBE_FLAG_MDD_ENABLED; + + } else{ + *aflags &= ~IXGBE_FLAG_MDD_ENABLED; + } +#ifdef module_param_array + } else { + *aflags |= IXGBE_FLAG_MDD_ENABLED; + } +#endif + break; + default: + *aflags &= ~IXGBE_FLAG_MDD_ENABLED; + break; + } + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.c new file mode 100644 index 0000000000..08b55b9fb4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.c @@ -0,0 +1,2662 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_api.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" + +STATIC void ixgbe_i2c_start(struct ixgbe_hw *hw); +STATIC void ixgbe_i2c_stop(struct ixgbe_hw *hw); +STATIC void ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data); +STATIC s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data); +STATIC s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw); +STATIC void ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data); +STATIC s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data); +STATIC void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); +STATIC void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); +STATIC s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); +STATIC bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl); +STATIC s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data); + +/** + * ixgbe_out_i2c_byte_ack - Send I2C byte with ack + * @hw: pointer to the hardware structure + * @byte: byte to send + * + * Returns an error code on error. + */ +STATIC s32 ixgbe_out_i2c_byte_ack(struct ixgbe_hw *hw, u8 byte) +{ + s32 status; + + status = ixgbe_clock_out_i2c_byte(hw, byte); + if (status) + return status; + return ixgbe_get_i2c_ack(hw); +} + +/** + * ixgbe_in_i2c_byte_ack - Receive an I2C byte and send ack + * @hw: pointer to the hardware structure + * @byte: pointer to a u8 to receive the byte + * + * Returns an error code on error. + */ +STATIC s32 ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte) +{ + ixgbe_clock_in_i2c_byte(hw, byte); + /* ACK */ + return ixgbe_clock_out_i2c_bit(hw, false); +} + +/** + * ixgbe_ones_comp_byte_add - Perform one's complement addition + * @add1: addend 1 + * @add2: addend 2 + * + * Returns one's complement 8-bit sum. + */ +STATIC u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2) +{ + u16 sum = add1 + add2; + + sum = (sum & 0xFF) + (sum >> 8); + return sum & 0xFF; +} + +/** + * ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to read from + * @reg: I2C device register to read from + * @val: pointer to location to receive read value + * @lock: true if to take and release semaphore + * + * Returns an error code on error. + */ +s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg, + u16 *val, bool lock) +{ + u32 swfw_mask = hw->phy.phy_semaphore_mask; + int max_retry = 3; + int retry = 0; + u8 csum_byte; + u8 high_bits; + u8 low_bits; + u8 reg_high; + u8 csum; + + reg_high = ((reg >> 7) & 0xFE) | 1; /* Indicate read combined */ + csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF); + csum = ~csum; + do { + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) + return IXGBE_ERR_SWFW_SYNC; + ixgbe_i2c_start(hw); + /* Device Address and write indication */ + if (ixgbe_out_i2c_byte_ack(hw, addr)) + goto fail; + /* Write bits 14:8 */ + if (ixgbe_out_i2c_byte_ack(hw, reg_high)) + goto fail; + /* Write bits 7:0 */ + if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF)) + goto fail; + /* Write csum */ + if (ixgbe_out_i2c_byte_ack(hw, csum)) + goto fail; + /* Re-start condition */ + ixgbe_i2c_start(hw); + /* Device Address and read indication */ + if (ixgbe_out_i2c_byte_ack(hw, addr | 1)) + goto fail; + /* Get upper bits */ + if (ixgbe_in_i2c_byte_ack(hw, &high_bits)) + goto fail; + /* Get low bits */ + if (ixgbe_in_i2c_byte_ack(hw, &low_bits)) + goto fail; + /* Get csum */ + ixgbe_clock_in_i2c_byte(hw, &csum_byte); + /* NACK */ + if (ixgbe_clock_out_i2c_bit(hw, false)) + goto fail; + ixgbe_i2c_stop(hw); + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + *val = (high_bits << 8) | low_bits; + return 0; + +fail: + ixgbe_i2c_bus_clear(hw); + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + if (retry < max_retry) + hw_dbg(hw, "I2C byte read combined error - Retrying.\n"); + else + hw_dbg(hw, "I2C byte read combined error.\n"); + retry++; + } while (retry <= max_retry); + + return IXGBE_ERR_I2C; +} + +/** + * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to write to + * @reg: I2C device register to write to + * @val: value to write + * @lock: true if to take and release semaphore + * + * Returns an error code on error. + */ +s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg, + u16 val, bool lock) +{ + u32 swfw_mask = hw->phy.phy_semaphore_mask; + int max_retry = 1; + int retry = 0; + u8 reg_high; + u8 csum; + + reg_high = (reg >> 7) & 0xFE; /* Indicate write combined */ + csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF); + csum = ixgbe_ones_comp_byte_add(csum, val >> 8); + csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF); + csum = ~csum; + do { + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) + return IXGBE_ERR_SWFW_SYNC; + ixgbe_i2c_start(hw); + /* Device Address and write indication */ + if (ixgbe_out_i2c_byte_ack(hw, addr)) + goto fail; + /* Write bits 14:8 */ + if (ixgbe_out_i2c_byte_ack(hw, reg_high)) + goto fail; + /* Write bits 7:0 */ + if (ixgbe_out_i2c_byte_ack(hw, reg & 0xFF)) + goto fail; + /* Write data 15:8 */ + if (ixgbe_out_i2c_byte_ack(hw, val >> 8)) + goto fail; + /* Write data 7:0 */ + if (ixgbe_out_i2c_byte_ack(hw, val & 0xFF)) + goto fail; + /* Write csum */ + if (ixgbe_out_i2c_byte_ack(hw, csum)) + goto fail; + ixgbe_i2c_stop(hw); + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return 0; + +fail: + ixgbe_i2c_bus_clear(hw); + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + if (retry < max_retry) + hw_dbg(hw, "I2C byte write combined error - Retrying.\n"); + else + hw_dbg(hw, "I2C byte write combined error.\n"); + retry++; + } while (retry <= max_retry); + + return IXGBE_ERR_I2C; +} + +/** + * ixgbe_init_phy_ops_generic - Inits PHY function ptrs + * @hw: pointer to the hardware structure + * + * Initialize the function pointers. + **/ +s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) +{ + struct ixgbe_phy_info *phy = &hw->phy; + + DEBUGFUNC("ixgbe_init_phy_ops_generic"); + + /* PHY */ + phy->ops.identify = ixgbe_identify_phy_generic; + phy->ops.reset = ixgbe_reset_phy_generic; + phy->ops.read_reg = ixgbe_read_phy_reg_generic; + phy->ops.write_reg = ixgbe_write_phy_reg_generic; + phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi; + phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi; + phy->ops.setup_link = ixgbe_setup_phy_link_generic; + phy->ops.setup_link_speed = ixgbe_setup_phy_link_speed_generic; + phy->ops.check_link = NULL; + phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic; + phy->ops.read_i2c_byte = ixgbe_read_i2c_byte_generic; + phy->ops.write_i2c_byte = ixgbe_write_i2c_byte_generic; + phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_generic; + phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_generic; + phy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_generic; + phy->ops.i2c_bus_clear = ixgbe_i2c_bus_clear; + phy->ops.identify_sfp = ixgbe_identify_module_generic; + phy->sfp_type = ixgbe_sfp_type_unknown; + phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked; + phy->ops.write_i2c_byte_unlocked = + ixgbe_write_i2c_byte_generic_unlocked; + phy->ops.check_overtemp = ixgbe_tn_check_overtemp; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_probe_phy - Probe a single address for a PHY + * @hw: pointer to hardware structure + * @phy_addr: PHY address to probe + * + * Returns true if PHY found + */ +static bool ixgbe_probe_phy(struct ixgbe_hw *hw, u16 phy_addr) +{ + u16 ext_ability = 0; + + if (!ixgbe_validate_phy_addr(hw, phy_addr)) { + hw_dbg(hw, "Unable to validate PHY address 0x%04X\n", + phy_addr); + return false; + } + + if (ixgbe_get_phy_id(hw)) + return false; + + hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); + + if (hw->phy.type == ixgbe_phy_unknown) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & + (IXGBE_MDIO_PHY_10GBASET_ABILITY | + IXGBE_MDIO_PHY_1000BASET_ABILITY)) + hw->phy.type = ixgbe_phy_cu_unknown; + else + hw->phy.type = ixgbe_phy_generic; + } + + return true; +} + +/** + * ixgbe_identify_phy_generic - Get physical layer module + * @hw: pointer to hardware structure + * + * Determines the physical layer module found on the current adapter. + **/ +s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + u16 phy_addr; + + DEBUGFUNC("ixgbe_identify_phy_generic"); + + if (!hw->phy.phy_semaphore_mask) { + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; + } + + if (hw->phy.type != ixgbe_phy_unknown) + return IXGBE_SUCCESS; + + if (hw->phy.nw_mng_if_sel) { + phy_addr = (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; + if (ixgbe_probe_phy(hw, phy_addr)) + return IXGBE_SUCCESS; + else + return IXGBE_ERR_PHY_ADDR_INVALID; + } + + for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { + if (ixgbe_probe_phy(hw, phy_addr)) { + status = IXGBE_SUCCESS; + break; + } + } + + /* Certain media types do not have a phy so an address will not + * be found and the code will take this path. Caller has to + * decide if it is an error or not. + */ + if (status != IXGBE_SUCCESS) + hw->phy.addr = 0; + + return status; +} + +/** + * ixgbe_check_reset_blocked - check status of MNG FW veto bit + * @hw: pointer to the hardware structure + * + * This function checks the MMNGC.MNG_VETO bit to see if there are + * any constraints on link from manageability. For MAC's that don't + * have this bit just return faluse since the link can not be blocked + * via this method. + **/ +s32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw) +{ + u32 mmngc; + + DEBUGFUNC("ixgbe_check_reset_blocked"); + + /* If we don't have this bit, it can't be blocking */ + if (hw->mac.type == ixgbe_mac_82598EB) + return false; + + mmngc = IXGBE_READ_REG(hw, IXGBE_MMNGC); + if (mmngc & IXGBE_MMNGC_MNG_VETO) { + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, + "MNG_VETO bit detected.\n"); + return true; + } + + return false; +} + +/** + * ixgbe_validate_phy_addr - Determines phy address is valid + * @hw: pointer to hardware structure + * @phy_addr: PHY address + * + **/ +bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) +{ + u16 phy_id = 0; + bool valid = false; + + DEBUGFUNC("ixgbe_validate_phy_addr"); + + hw->phy.addr = phy_addr; + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); + + if (phy_id != 0xFFFF && phy_id != 0x0) + valid = true; + + hw_dbg(hw, "PHY ID HIGH is 0x%04X\n", phy_id); + + return valid; +} + +/** + * ixgbe_get_phy_id - Get the phy type + * @hw: pointer to hardware structure + * + **/ +s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) +{ + s32 status; + u16 phy_id_high = 0; + u16 phy_id_low = 0; + + DEBUGFUNC("ixgbe_get_phy_id"); + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &phy_id_high); + + if (status == IXGBE_SUCCESS) { + hw->phy.id = (u32)(phy_id_high << 16); + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &phy_id_low); + hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); + hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); + } + hw_dbg(hw, "PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n", + phy_id_high, phy_id_low); + + return status; +} + +/** + * ixgbe_get_phy_type_from_id - Get the phy type + * @phy_id: PHY ID information + * + **/ +enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) +{ + enum ixgbe_phy_type phy_type; + + DEBUGFUNC("ixgbe_get_phy_type_from_id"); + + switch (phy_id) { + case TN1010_PHY_ID: + phy_type = ixgbe_phy_tn; + break; + case X550_PHY_ID: + case X540_PHY_ID: + phy_type = ixgbe_phy_aq; + break; + case QT2022_PHY_ID: + phy_type = ixgbe_phy_qt; + break; + case ATH_PHY_ID: + phy_type = ixgbe_phy_nl; + break; + case X557_PHY_ID: + case X557_PHY_ID2: + phy_type = ixgbe_phy_x550em_ext_t; + break; + case IXGBE_M88E1500_E_PHY_ID: + case IXGBE_M88E1543_E_PHY_ID: + phy_type = ixgbe_phy_ext_1g_t; + break; + default: + phy_type = ixgbe_phy_unknown; + break; + } + return phy_type; +} + +/** + * ixgbe_reset_phy_generic - Performs a PHY reset + * @hw: pointer to hardware structure + **/ +s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) +{ + u32 i; + u16 ctrl = 0; + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_reset_phy_generic"); + + if (hw->phy.type == ixgbe_phy_unknown) + status = ixgbe_identify_phy_generic(hw); + + if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none) + goto out; + + /* Don't reset PHY if it's shut down due to overtemp. */ + if (!hw->phy.reset_if_overtemp && + (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) + goto out; + + /* Blocked by MNG FW so bail */ + if (ixgbe_check_reset_blocked(hw)) + goto out; + + /* + * Perform soft PHY reset to the PHY_XS. + * This will cause a soft reset to the PHY + */ + hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, + IXGBE_MDIO_PHY_XS_RESET); + + /* + * Poll for reset bit to self-clear indicating reset is complete. + * Some PHYs could take up to 3 seconds to complete and need about + * 1.7 usec delay after the reset is complete. + */ + for (i = 0; i < 30; i++) { + msec_delay(100); + if (hw->phy.type == ixgbe_phy_x550em_ext_t) { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_TX_VENDOR_ALARMS_3, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &ctrl); + if (status != IXGBE_SUCCESS) + return status; + + if (ctrl & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) { + usec_delay(2); + break; + } + } else { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, + &ctrl); + if (status != IXGBE_SUCCESS) + return status; + + if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) { + usec_delay(2); + break; + } + } + } + + if (ctrl & IXGBE_MDIO_PHY_XS_RESET) { + status = IXGBE_ERR_RESET_FAILED; + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PHY reset polling failed to complete.\n"); + } + +out: + return status; +} + +/** + * ixgbe_restart_auto_neg - Restart auto negotiation on the PHY + * @hw: pointer to hardware structure + **/ +void ixgbe_restart_auto_neg(struct ixgbe_hw *hw) +{ + u16 autoneg_reg; + + /* Check if PHY reset is blocked by MNG FW */ + if (ixgbe_check_reset_blocked(hw)) + return; + + /* Restart PHY auto-negotiation. */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); + autoneg_reg |= IXGBE_MII_RESTART; + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); +} + +/** + * ixgbe_read_phy_reg_mdi - Reads a value from a specified PHY register without + * the SWFW lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: 5 bit device type + * @phy_data: Pointer to read data from PHY register + **/ +s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data) +{ + u32 i, data, command; + + /* Setup and write the address cycle command */ + command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* + * Check every 10 usec to see if the address cycle completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) + break; + } + + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address command did not complete.\n"); + hw_dbg(hw, "PHY address command did not complete, returning IXGBE_ERR_PHY\n"); + return IXGBE_ERR_PHY; + } + + /* + * Address cycle complete, setup and write the read + * command + */ + command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* + * Check every 10 usec to see if the address cycle + * completed. The MDI Command bit will clear when the + * operation is complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) + break; + } + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY read command didn't complete\n"); + hw_dbg(hw, "PHY read command didn't complete, returning IXGBE_ERR_PHY\n"); + return IXGBE_ERR_PHY; + } + + /* + * Read operation is complete. Get the data + * from MSRWD + */ + data = IXGBE_READ_REG(hw, IXGBE_MSRWD); + data >>= IXGBE_MSRWD_READ_DATA_SHIFT; + *phy_data = (u16)(data); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register + * using the SWFW lock - this function is needed in most cases + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: 5 bit device type + * @phy_data: Pointer to read data from PHY register + **/ +s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) +{ + s32 status; + u32 gssr = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ixgbe_read_phy_reg_generic"); + + if (hw->mac.ops.acquire_swfw_sync(hw, gssr)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); + + hw->mac.ops.release_swfw_sync(hw, gssr); + + return status; +} + +/** + * ixgbe_write_phy_reg_mdi - Writes a value to specified PHY register + * without SWFW lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 5 bit device type + * @phy_data: Data to write to the PHY register + **/ +s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + u32 i, command; + + /* Put the data in the MDI single read and write data register*/ + IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); + + /* Setup and write the address cycle command */ + command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* + * Check every 10 usec to see if the address cycle completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) + break; + } + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY address cmd didn't complete\n"); + return IXGBE_ERR_PHY; + } + + /* + * Address cycle complete, setup and write the write + * command + */ + command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* + * Check every 10 usec to see if the address cycle + * completed. The MDI Command bit will clear when the + * operation is complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) + break; + } + + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "PHY write cmd didn't complete\n"); + return IXGBE_ERR_PHY; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register + * using SWFW lock- this function is needed in most cases + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 5 bit device type + * @phy_data: Data to write to the PHY register + **/ +s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + s32 status; + u32 gssr = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ixgbe_write_phy_reg_generic"); + + if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { + status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type, + phy_data); + hw->mac.ops.release_swfw_sync(hw, gssr); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_setup_phy_link_generic - Set and restart auto-neg + * @hw: pointer to hardware structure + * + * Restart auto-negotiation and PHY and waits for completion. + **/ +s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + bool autoneg = false; + ixgbe_link_speed speed; + + DEBUGFUNC("ixgbe_setup_phy_link_generic"); + + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); + + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) && + (speed & IXGBE_LINK_SPEED_10GB_FULL)) + autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + if (hw->mac.type == ixgbe_mac_X550 || + ixgbe_is_mac_E6xx(hw->mac.type)) { + /* Set or unset auto-negotiation 5G advertisement */ + autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) && + (speed & IXGBE_LINK_SPEED_5GB_FULL)) + autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE; + + /* Set or unset auto-negotiation 2.5G advertisement */ + autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & + IXGBE_LINK_SPEED_2_5GB_FULL) && + (speed & IXGBE_LINK_SPEED_2_5GB_FULL)) + autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE; + } + + /* Set or unset auto-negotiation 1G advertisement */ + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) && + (speed & IXGBE_LINK_SPEED_1GB_FULL)) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE | + IXGBE_MII_100BASE_T_ADVERTISE_HALF); + if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) && + (speed & IXGBE_LINK_SPEED_100_FULL)) + autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + + ixgbe_restart_auto_neg(hw); + return status; +} + +/** + * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: unused + **/ +s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); + + DEBUGFUNC("ixgbe_setup_phy_link_speed_generic"); + + /* + * Clear autoneg_advertised and set new values based on input link + * speed. + */ + hw->phy.autoneg_advertised = 0; + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + + if (speed & IXGBE_LINK_SPEED_5GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL; + + if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL; + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + + if (speed & IXGBE_LINK_SPEED_100_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + + if (speed & IXGBE_LINK_SPEED_10_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL; + + /* Setup link based on the new speed settings */ + ixgbe_setup_phy_link(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_copper_speeds_supported - Get copper link speeds from phy + * @hw: pointer to hardware structure + * + * Determines the supported link capabilities by reading the PHY auto + * negotiation register. + **/ +static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw) +{ + s32 status; + u16 speed_ability; + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &speed_ability); + if (status) + return status; + + if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL; + if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL; + + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_E610: + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL; + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL; + break; + default: + break; + } + + return status; +} + +/** + * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: boolean auto-negotiation value + **/ +s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic"); + + *autoneg = true; + if (!hw->phy.speeds_supported) + status = ixgbe_get_copper_speeds_supported(hw); + + *speed = hw->phy.speeds_supported; + return status; +} + +/** + * ixgbe_check_phy_link_tnx - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: current link speed + * @link_up: true is link is up, false otherwise + * + * Reads the VS1 register to determine if link is up and the current speed for + * the PHY. + **/ +s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up) +{ + s32 status = IXGBE_SUCCESS; + u32 time_out; + u32 max_time_out = 10; + u16 phy_link = 0; + u16 phy_speed = 0; + u16 phy_data = 0; + + DEBUGFUNC("ixgbe_check_phy_link_tnx"); + + /* Initialize speed and link to default case */ + *link_up = false; + *speed = IXGBE_LINK_SPEED_10GB_FULL; + + /* + * Check current speed and link status of the PHY register. + * This is a vendor specific register and may have to + * be changed for other copper PHYs. + */ + for (time_out = 0; time_out < max_time_out; time_out++) { + usec_delay(10); + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + &phy_data); + phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; + phy_speed = phy_data & + IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; + if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { + *link_up = true; + if (phy_speed == + IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + } + } + + return status; +} + +/** + * ixgbe_setup_phy_link_tnx - Set and restart auto-neg + * @hw: pointer to hardware structure + * + * Restart auto-negotiation and PHY and waits for completion. + **/ +s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + bool autoneg = false; + ixgbe_link_speed speed; + + DEBUGFUNC("ixgbe_setup_phy_link_tnx"); + + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + /* Set or unset auto-negotiation 1G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_100_FULL) { + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + autoneg_reg); + } + + ixgbe_restart_auto_neg(hw); + return status; +} + +/** + * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + **/ +s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + s32 status; + + DEBUGFUNC("ixgbe_get_phy_firmware_version_tnx"); + + status = hw->phy.ops.read_reg(hw, TNX_FW_REV, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + firmware_version); + + return status; +} + +/** + * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + **/ +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + s32 status; + + DEBUGFUNC("ixgbe_get_phy_firmware_version_generic"); + + status = hw->phy.ops.read_reg(hw, AQ_FW_REV, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + firmware_version); + + return status; +} + +/** + * ixgbe_reset_phy_nl - Performs a PHY reset + * @hw: pointer to hardware structure + **/ +s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) +{ + u16 phy_offset, control, eword, edata, block_crc; + bool end_data = false; + u16 list_offset, data_offset; + u16 phy_data = 0; + s32 ret_val = IXGBE_SUCCESS; + u32 i; + + DEBUGFUNC("ixgbe_reset_phy_nl"); + + /* Blocked by MNG FW so bail */ + if (ixgbe_check_reset_blocked(hw)) + goto out; + + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); + + /* reset the PHY and poll for completion */ + hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, + (phy_data | IXGBE_MDIO_PHY_XS_RESET)); + + for (i = 0; i < 100; i++) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); + if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0) + break; + msec_delay(10); + } + + if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) { + hw_dbg(hw, "PHY reset did not complete.\n"); + ret_val = IXGBE_ERR_PHY; + goto out; + } + + /* Get init offsets */ + ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset, + &data_offset); + if (ret_val != IXGBE_SUCCESS) + goto out; + + ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc); + data_offset++; + while (!end_data) { + /* + * Read control word from PHY init contents offset + */ + ret_val = hw->eeprom.ops.read(hw, data_offset, &eword); + if (ret_val) + goto err_eeprom; + control = (eword & IXGBE_CONTROL_MASK_NL) >> + IXGBE_CONTROL_SHIFT_NL; + edata = eword & IXGBE_DATA_MASK_NL; + switch (control) { + case IXGBE_DELAY_NL: + data_offset++; + hw_dbg(hw, "DELAY: %d MS\n", edata); + msec_delay(edata); + break; + case IXGBE_DATA_NL: + hw_dbg(hw, "DATA:\n"); + data_offset++; + ret_val = hw->eeprom.ops.read(hw, data_offset, + &phy_offset); + if (ret_val) + goto err_eeprom; + data_offset++; + for (i = 0; i < edata; i++) { + ret_val = hw->eeprom.ops.read(hw, data_offset, + &eword); + if (ret_val) + goto err_eeprom; + hw->phy.ops.write_reg(hw, phy_offset, + IXGBE_TWINAX_DEV, eword); + hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword, + phy_offset); + data_offset++; + phy_offset++; + } + break; + case IXGBE_CONTROL_NL: + data_offset++; + hw_dbg(hw, "CONTROL:\n"); + if (edata == IXGBE_CONTROL_EOL_NL) { + hw_dbg(hw, "EOL\n"); + end_data = true; + } else if (edata == IXGBE_CONTROL_SOL_NL) { + hw_dbg(hw, "SOL\n"); + } else { + hw_dbg(hw, "Bad control value\n"); + ret_val = IXGBE_ERR_PHY; + goto out; + } + break; + default: + hw_dbg(hw, "Bad control type\n"); + ret_val = IXGBE_ERR_PHY; + goto out; + } + } + +out: + return ret_val; + +err_eeprom: + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", data_offset); + return IXGBE_ERR_PHY; +} + +/** + * ixgbe_identify_module_generic - Identifies module type + * @hw: pointer to hardware structure + * + * Determines HW type and calls appropriate function. + **/ +s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_SFP_NOT_PRESENT; + + DEBUGFUNC("ixgbe_identify_module_generic"); + + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + status = ixgbe_identify_sfp_module_generic(hw); + break; + + case ixgbe_media_type_fiber_qsfp: + status = ixgbe_identify_qsfp_module_generic(hw); + break; + + default: + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + status = IXGBE_ERR_SFP_NOT_PRESENT; + break; + } + + return status; +} + +/** + * ixgbe_identify_sfp_module_generic - Identifies SFP modules + * @hw: pointer to hardware structure + * + * Searches for and identifies the SFP module and assigns appropriate PHY type. + **/ +s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + u32 vendor_oui = 0; + enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; + u8 identifier = 0; + u8 comp_codes_1g = 0; + u8 comp_codes_10g = 0; + u8 oui_bytes[3] = {0, 0, 0}; + u8 cable_tech = 0; + u8 cable_spec = 0; + u16 enforce_sfp = 0; + + DEBUGFUNC("ixgbe_identify_sfp_module_generic"); + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + status = IXGBE_ERR_SFP_NOT_PRESENT; + goto out; + } + + /* LAN ID is needed for I2C access */ + hw->mac.ops.set_lan_id(hw); + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_IDENTIFIER, + &identifier); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + if (identifier != IXGBE_SFF_IDENTIFIER_SFP) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } else { + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_1GBE_COMP_CODES, + &comp_codes_1g); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_10GBE_COMP_CODES, + &comp_codes_10g); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_CABLE_TECHNOLOGY, + &cable_tech); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + /* ID Module + * ========= + * 0 SFP_DA_CU + * 1 SFP_SR + * 2 SFP_LR + * 3 SFP_DA_CORE0 - 82599-specific + * 4 SFP_DA_CORE1 - 82599-specific + * 5 SFP_SR/LR_CORE0 - 82599-specific + * 6 SFP_SR/LR_CORE1 - 82599-specific + * 7 SFP_act_lmt_DA_CORE0 - 82599-specific + * 8 SFP_act_lmt_DA_CORE1 - 82599-specific + * 9 SFP_1g_cu_CORE0 - 82599-specific + * 10 SFP_1g_cu_CORE1 - 82599-specific + * 11 SFP_1g_sx_CORE0 - 82599-specific + * 12 SFP_1g_sx_CORE1 - 82599-specific + */ + if (hw->mac.type == ixgbe_mac_82598EB) { + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) + hw->phy.sfp_type = ixgbe_sfp_type_da_cu; + else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + hw->phy.sfp_type = ixgbe_sfp_type_sr; + else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + hw->phy.sfp_type = ixgbe_sfp_type_lr; + else + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } else { + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_da_cu_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_da_cu_core1; + } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) { + hw->phy.ops.read_i2c_eeprom( + hw, IXGBE_SFF_CABLE_SPEC_COMP, + &cable_spec); + if (cable_spec & + IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core1; + } else { + hw->phy.sfp_type = + ixgbe_sfp_type_unknown; + } + } else if (comp_codes_10g & + (IXGBE_SFF_10GBASESR_CAPABLE | + IXGBE_SFF_10GBASELR_CAPABLE)) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_srlr_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_srlr_core1; + } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_1g_cu_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_cu_core1; + } else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_1g_sx_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_sx_core1; + } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core1; + } else { + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } + } + + if (hw->phy.sfp_type != stored_sfp_type) + hw->phy.sfp_setup_needed = true; + + /* Determine if the SFP+ PHY is dual speed or not. */ + hw->phy.multispeed_fiber = false; + if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || + ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) + hw->phy.multispeed_fiber = true; + + /* Determine PHY vendor */ + if (hw->phy.type != ixgbe_phy_nl) { + hw->phy.id = identifier; + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_VENDOR_OUI_BYTE0, + &oui_bytes[0]); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_VENDOR_OUI_BYTE1, + &oui_bytes[1]); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_VENDOR_OUI_BYTE2, + &oui_bytes[2]); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + vendor_oui = + ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) | + (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) | + (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT)); + + switch (vendor_oui) { + case IXGBE_SFF_VENDOR_OUI_TYCO: + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_passive_tyco; + break; + case IXGBE_SFF_VENDOR_OUI_FTL: + if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = ixgbe_phy_sfp_ftl_active; + else + hw->phy.type = ixgbe_phy_sfp_ftl; + break; + case IXGBE_SFF_VENDOR_OUI_AVAGO: + hw->phy.type = ixgbe_phy_sfp_avago; + break; + case IXGBE_SFF_VENDOR_OUI_INTEL: + hw->phy.type = ixgbe_phy_sfp_intel; + break; + default: + if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_passive_unknown; + else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) + hw->phy.type = + ixgbe_phy_sfp_active_unknown; + else + hw->phy.type = ixgbe_phy_sfp_unknown; + break; + } + } + + /* Allow any DA cable vendor */ + if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | + IXGBE_SFF_DA_ACTIVE_CABLE)) { + status = IXGBE_SUCCESS; + goto out; + } + + /* Verify supported 1G SFP modules */ + if (comp_codes_10g == 0 && + !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + + /* Anything else 82598-based is supported */ + if (hw->mac.type == ixgbe_mac_82598EB) { + status = IXGBE_SUCCESS; + goto out; + } + + ixgbe_get_device_caps(hw, &enforce_sfp); + if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && + !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { + /* Make sure we're a supported PHY type */ + if (hw->phy.type == ixgbe_phy_sfp_intel) { + status = IXGBE_SUCCESS; + } else { + if (hw->allow_unsupported_sfp == true) { + EWARN(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n"); + status = IXGBE_SUCCESS; + } else { + hw_dbg(hw, "SFP+ module not supported\n"); + hw->phy.type = + ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } + } + } else { + status = IXGBE_SUCCESS; + } + } + +out: + return status; + +err_read_i2c_eeprom: + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + if (hw->phy.type != ixgbe_phy_nl) { + hw->phy.id = 0; + hw->phy.type = ixgbe_phy_unknown; + } + return IXGBE_ERR_SFP_NOT_PRESENT; +} + +/** + * ixgbe_get_supported_phy_sfp_layer_generic - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current SFP. + */ +u64 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw) +{ + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u8 comp_codes_10g = 0; + u8 comp_codes_1g = 0; + + DEBUGFUNC("ixgbe_get_supported_phy_sfp_layer_generic"); + + hw->phy.ops.identify_sfp(hw); + if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) + return physical_layer; + + switch (hw->phy.type) { + case ixgbe_phy_sfp_passive_tyco: + case ixgbe_phy_sfp_passive_unknown: + case ixgbe_phy_qsfp_passive_unknown: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + break; + case ixgbe_phy_sfp_ftl_active: + case ixgbe_phy_sfp_active_unknown: + case ixgbe_phy_qsfp_active_unknown: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA; + break; + case ixgbe_phy_sfp_avago: + case ixgbe_phy_sfp_ftl: + case ixgbe_phy_sfp_intel: + case ixgbe_phy_sfp_unknown: + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g); + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g); + if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T; + else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX; + break; + case ixgbe_phy_qsfp_intel: + case ixgbe_phy_qsfp_unknown: + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_10GBE_COMP, &comp_codes_10g); + if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + break; + default: + break; + } + + return physical_layer; +} + +/** + * ixgbe_identify_qsfp_module_generic - Identifies QSFP modules + * @hw: pointer to hardware structure + * + * Searches for and identifies the QSFP module and assigns appropriate PHY type + **/ +s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + u32 vendor_oui = 0; + enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; + u8 identifier = 0; + u8 comp_codes_1g = 0; + u8 comp_codes_10g = 0; + u8 oui_bytes[3] = {0, 0, 0}; + u16 enforce_sfp = 0; + u8 connector = 0; + u8 cable_length = 0; + u8 device_tech = 0; + bool active_cable = false; + + DEBUGFUNC("ixgbe_identify_qsfp_module_generic"); + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) { + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + status = IXGBE_ERR_SFP_NOT_PRESENT; + goto out; + } + + /* LAN ID is needed for I2C access */ + hw->mac.ops.set_lan_id(hw); + + status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER, + &identifier); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + + hw->phy.id = identifier; + + status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP, + &comp_codes_10g); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_1GBE_COMP, + &comp_codes_1g); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + if (comp_codes_10g & IXGBE_SFF_QSFP_DA_PASSIVE_CABLE) { + hw->phy.type = ixgbe_phy_qsfp_passive_unknown; + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core0; + else + hw->phy.sfp_type = ixgbe_sfp_type_da_cu_core1; + } else if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE | + IXGBE_SFF_10GBASELR_CAPABLE)) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0; + else + hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1; + } else { + if (comp_codes_10g & IXGBE_SFF_QSFP_DA_ACTIVE_CABLE) + active_cable = true; + + if (!active_cable) { + /* check for active DA cables that pre-date + * SFF-8436 v3.6 */ + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_CONNECTOR, + &connector); + + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_CABLE_LENGTH, + &cable_length); + + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_DEVICE_TECH, + &device_tech); + + if ((connector == + IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE) && + (cable_length > 0) && + ((device_tech >> 4) == + IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL)) + active_cable = true; + } + + if (active_cable) { + hw->phy.type = ixgbe_phy_qsfp_active_unknown; + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_da_act_lmt_core1; + } else { + /* unsupported module type */ + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + } + + if (hw->phy.sfp_type != stored_sfp_type) + hw->phy.sfp_setup_needed = true; + + /* Determine if the QSFP+ PHY is dual speed or not. */ + hw->phy.multispeed_fiber = false; + if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || + ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) + hw->phy.multispeed_fiber = true; + + /* Determine PHY vendor for optical modules */ + if (comp_codes_10g & (IXGBE_SFF_10GBASESR_CAPABLE | + IXGBE_SFF_10GBASELR_CAPABLE)) { + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0, + &oui_bytes[0]); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1, + &oui_bytes[1]); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2, + &oui_bytes[2]); + + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + + vendor_oui = + ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) | + (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) | + (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT)); + + if (vendor_oui == IXGBE_SFF_VENDOR_OUI_INTEL) + hw->phy.type = ixgbe_phy_qsfp_intel; + else + hw->phy.type = ixgbe_phy_qsfp_unknown; + + ixgbe_get_device_caps(hw, &enforce_sfp); + if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) { + /* Make sure we're a supported PHY type */ + if (hw->phy.type == ixgbe_phy_qsfp_intel) { + status = IXGBE_SUCCESS; + } else { + if (hw->allow_unsupported_sfp == true) { + EWARN(hw, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n"); + status = IXGBE_SUCCESS; + } else { + hw_dbg(hw, "QSFP module not supported\n"); + hw->phy.type = + ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } + } + } else { + status = IXGBE_SUCCESS; + } + } + +out: + return status; + +err_read_i2c_eeprom: + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + hw->phy.id = 0; + hw->phy.type = ixgbe_phy_unknown; + + return IXGBE_ERR_SFP_NOT_PRESENT; +} + +/** + * ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence + * @hw: pointer to hardware structure + * @list_offset: offset to the SFP ID list + * @data_offset: offset to the SFP data block + * + * Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if + * so it returns the offsets to the phy init sequence block. + **/ +s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + u16 *list_offset, + u16 *data_offset) +{ + u16 sfp_id; + u16 sfp_type = hw->phy.sfp_type; + + DEBUGFUNC("ixgbe_get_sfp_init_sequence_offsets"); + + if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) + return IXGBE_ERR_SFP_NOT_SUPPORTED; + + if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) + return IXGBE_ERR_SFP_NOT_PRESENT; + + if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) && + (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) + return IXGBE_ERR_SFP_NOT_SUPPORTED; + + /* + * Limiting active cables and 1G Phys must be initialized as + * SR modules + */ + if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || + sfp_type == ixgbe_sfp_type_1g_lx_core0 || + sfp_type == ixgbe_sfp_type_1g_cu_core0 || + sfp_type == ixgbe_sfp_type_1g_sx_core0) + sfp_type = ixgbe_sfp_type_srlr_core0; + else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || + sfp_type == ixgbe_sfp_type_1g_lx_core1 || + sfp_type == ixgbe_sfp_type_1g_cu_core1 || + sfp_type == ixgbe_sfp_type_1g_sx_core1) + sfp_type = ixgbe_sfp_type_srlr_core1; + + /* Read offset to PHY init contents */ + if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", + IXGBE_PHY_INIT_OFFSET_NL); + return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; + } + + if ((!*list_offset) || (*list_offset == 0xFFFF)) + return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; + + /* Shift offset to first ID word */ + (*list_offset)++; + + /* + * Find the matching SFP ID in the EEPROM + * and program the init sequence + */ + if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id)) + goto err_phy; + + while (sfp_id != IXGBE_PHY_INIT_END_NL) { + if (sfp_id == sfp_type) { + (*list_offset)++; + if (hw->eeprom.ops.read(hw, *list_offset, data_offset)) + goto err_phy; + if ((!*data_offset) || (*data_offset == 0xFFFF)) { + hw_dbg(hw, "SFP+ module not supported\n"); + return IXGBE_ERR_SFP_NOT_SUPPORTED; + } else { + break; + } + } else { + (*list_offset) += 2; + if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id)) + goto err_phy; + } + } + + if (sfp_id == IXGBE_PHY_INIT_END_NL) { + hw_dbg(hw, "No matching SFP+ module found\n"); + return IXGBE_ERR_SFP_NOT_SUPPORTED; + } + + return IXGBE_SUCCESS; + +err_phy: + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "eeprom read at offset %d failed", *list_offset); + return IXGBE_ERR_PHY; +} + +/** + * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to read + * @eeprom_data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data) +{ + DEBUGFUNC("ixgbe_read_i2c_eeprom_generic"); + + return hw->phy.ops.read_i2c_byte(hw, byte_offset, + IXGBE_I2C_EEPROM_DEV_ADDR, + eeprom_data); +} + +/** + * ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: byte offset at address 0xA2 + * @sff8472_data: value read + * + * Performs byte read operation to SFP module's SFF-8472 data over I2C + **/ +STATIC s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *sff8472_data) +{ + return hw->phy.ops.read_i2c_byte(hw, byte_offset, + IXGBE_I2C_EEPROM_DEV_ADDR2, + sff8472_data); +} + +/** + * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to write + * @eeprom_data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data) +{ + DEBUGFUNC("ixgbe_write_i2c_eeprom_generic"); + + return hw->phy.ops.write_i2c_byte(hw, byte_offset, + IXGBE_I2C_EEPROM_DEV_ADDR, + eeprom_data); +} + +/** + * ixgbe_is_sfp_probe - Returns true if SFP is being detected + * @hw: pointer to hardware structure + * @offset: eeprom offset to be read + * @addr: I2C address to be read + */ +STATIC bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr) +{ + if (addr == IXGBE_I2C_EEPROM_DEV_ADDR && + offset == IXGBE_SFF_IDENTIFIER && + hw->phy.sfp_type == ixgbe_sfp_type_not_present) + return true; + return false; +} + +/** + * ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: address to read from + * @data: value read + * @lock: true if to take and release semaphore + * + * Performs byte read operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +STATIC s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data, bool lock) +{ + s32 status; + u32 max_retry = 10; + u32 retry = 0; + u32 swfw_mask = hw->phy.phy_semaphore_mask; + bool nack = 1; + *data = 0; + + DEBUGFUNC("ixgbe_read_i2c_byte_generic"); + + if (hw->mac.type >= ixgbe_mac_X550) + max_retry = 3; + if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr)) + max_retry = IXGBE_SFP_DETECT_RETRIES; + + do { + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) + return IXGBE_ERR_SWFW_SYNC; + + ixgbe_i2c_start(hw); + + /* Device Address and write indication */ + status = ixgbe_clock_out_i2c_byte(hw, dev_addr); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_byte(hw, byte_offset); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_i2c_start(hw); + + /* Device Address and read indication */ + status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1)); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_clock_in_i2c_byte(hw, data); + + status = ixgbe_clock_out_i2c_bit(hw, nack); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_i2c_stop(hw); + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return IXGBE_SUCCESS; + +fail: + ixgbe_i2c_bus_clear(hw); + if (lock) { + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + msec_delay(100); + } + if (retry < max_retry) + hw_dbg(hw, "I2C byte read error - Retrying.\n"); + else + hw_dbg(hw, "I2C byte read error.\n"); + retry++; + + } while (retry <= max_retry); + + return status; +} + +/** + * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: address to read from + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr, + data, true); +} + +/** + * ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: address to read from + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr, + data, false); +} + +/** + * ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: address to write to + * @data: value to write + * @lock: true if to take and release semaphore + * + * Performs byte write operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +STATIC s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data, bool lock) +{ + s32 status; + u32 max_retry = 1; + u32 retry = 0; + u32 swfw_mask = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ixgbe_write_i2c_byte_generic"); + + if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != + IXGBE_SUCCESS) + return IXGBE_ERR_SWFW_SYNC; + + do { + ixgbe_i2c_start(hw); + + status = ixgbe_clock_out_i2c_byte(hw, dev_addr); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_byte(hw, byte_offset); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_byte(hw, data); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_i2c_stop(hw); + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return IXGBE_SUCCESS; + +fail: + ixgbe_i2c_bus_clear(hw); + if (retry < max_retry) + hw_dbg(hw, "I2C byte write error - Retrying.\n"); + else + hw_dbg(hw, "I2C byte write error.\n"); + retry++; + } while (retry <= max_retry); + + if (lock) + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + + return status; +} + +/** + * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: address to write to + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr, + data, true); +} + +/** + * ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: address to write to + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr, + data, false); +} + +/** + * ixgbe_i2c_start - Sets I2C start condition + * @hw: pointer to hardware structure + * + * Sets I2C start condition (High -> Low on SDA while SCL is High) + * Set bit-bang mode on X550 hardware. + **/ +STATIC void ixgbe_i2c_start(struct ixgbe_hw *hw) +{ + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + + DEBUGFUNC("ixgbe_i2c_start"); + + i2cctl |= IXGBE_I2C_BB_EN_BY_MAC(hw); + + /* Start condition must begin with data and clock high */ + ixgbe_set_i2c_data(hw, &i2cctl, 1); + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Setup time for start condition (4.7us) */ + usec_delay(IXGBE_I2C_T_SU_STA); + + ixgbe_set_i2c_data(hw, &i2cctl, 0); + + /* Hold time for start condition (4us) */ + usec_delay(IXGBE_I2C_T_HD_STA); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(IXGBE_I2C_T_LOW); + +} + +/** + * ixgbe_i2c_stop - Sets I2C stop condition + * @hw: pointer to hardware structure + * + * Sets I2C stop condition (Low -> High on SDA while SCL is High) + * Disables bit-bang mode and negates data output enable on X550 + * hardware. + **/ +STATIC void ixgbe_i2c_stop(struct ixgbe_hw *hw) +{ + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); + u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw); + u32 bb_en_bit = IXGBE_I2C_BB_EN_BY_MAC(hw); + + DEBUGFUNC("ixgbe_i2c_stop"); + + /* Stop condition must begin with data low and clock high */ + ixgbe_set_i2c_data(hw, &i2cctl, 0); + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Setup time for stop condition (4us) */ + usec_delay(IXGBE_I2C_T_SU_STO); + + ixgbe_set_i2c_data(hw, &i2cctl, 1); + + /* bus free time between stop and start (4.7us)*/ + usec_delay(IXGBE_I2C_T_BUF); + + if (bb_en_bit || data_oe_bit || clk_oe_bit) { + i2cctl &= ~bb_en_bit; + i2cctl |= data_oe_bit | clk_oe_bit; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); + IXGBE_WRITE_FLUSH(hw); + } +} + +/** + * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C + * @hw: pointer to hardware structure + * @data: data byte to clock in + * + * Clocks in one byte data via I2C data/clock + **/ +STATIC void ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data) +{ + s32 i; + bool bit = 0; + + DEBUGFUNC("ixgbe_clock_in_i2c_byte"); + + *data = 0; + for (i = 7; i >= 0; i--) { + ixgbe_clock_in_i2c_bit(hw, &bit); + *data |= bit << i; + } +} + +/** + * ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C + * @hw: pointer to hardware structure + * @data: data byte clocked out + * + * Clocks out one byte data via I2C data/clock + **/ +STATIC s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data) +{ + s32 status = IXGBE_SUCCESS; + s32 i; + u32 i2cctl; + bool bit; + + DEBUGFUNC("ixgbe_clock_out_i2c_byte"); + + for (i = 7; i >= 0; i--) { + bit = (data >> i) & 0x1; + status = ixgbe_clock_out_i2c_bit(hw, bit); + + if (status != IXGBE_SUCCESS) + break; + } + + /* Release SDA line (set high) */ + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); + i2cctl |= IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); + IXGBE_WRITE_FLUSH(hw); + + return status; +} + +/** + * ixgbe_get_i2c_ack - Polls for I2C ACK + * @hw: pointer to hardware structure + * + * Clocks in/out one bit via I2C data/clock + **/ +STATIC s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) +{ + u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); + s32 status = IXGBE_SUCCESS; + u32 i = 0; + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + u32 timeout = 10; + bool ack = 1; + + DEBUGFUNC("ixgbe_get_i2c_ack"); + + if (data_oe_bit) { + i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); + i2cctl |= data_oe_bit; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); + IXGBE_WRITE_FLUSH(hw); + } + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + /* Poll for ACK. Note that ACK in I2C spec is + * transition from 1 to 0 */ + for (i = 0; i < timeout; i++) { + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + ack = ixgbe_get_i2c_data(hw, &i2cctl); + + usec_delay(1); + if (!ack) + break; + } + + if (ack) { + hw_dbg(hw, "I2C ack was not received.\n"); + status = IXGBE_ERR_I2C; + } + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(IXGBE_I2C_T_LOW); + + return status; +} + +/** + * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock + * @hw: pointer to hardware structure + * @data: read data value + * + * Clocks in one bit via I2C data/clock + **/ +STATIC void ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data) +{ + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); + + DEBUGFUNC("ixgbe_clock_in_i2c_bit"); + + if (data_oe_bit) { + i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); + i2cctl |= data_oe_bit; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); + IXGBE_WRITE_FLUSH(hw); + } + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + *data = ixgbe_get_i2c_data(hw, &i2cctl); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(IXGBE_I2C_T_LOW); +} + +/** + * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock + * @hw: pointer to hardware structure + * @data: data value to write + * + * Clocks out one bit via I2C data/clock + **/ +STATIC s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data) +{ + s32 status; + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + + DEBUGFUNC("ixgbe_clock_out_i2c_bit"); + + status = ixgbe_set_i2c_data(hw, &i2cctl, data); + if (status == IXGBE_SUCCESS) { + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us. + * This also takes care of the data hold time. + */ + usec_delay(IXGBE_I2C_T_LOW); + } else { + status = IXGBE_ERR_I2C; + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "I2C data was not set to %X\n", data); + } + + return status; +} + +/** + * ixgbe_raise_i2c_clk - Raises the I2C SCL clock + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Raises the I2C clock line '0'->'1' + * Negates the I2C clock output enable on X550 hardware. + **/ +STATIC void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) +{ + u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw); + u32 i = 0; + u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT; + u32 i2cctl_r = 0; + + DEBUGFUNC("ixgbe_raise_i2c_clk"); + + if (clk_oe_bit) { + *i2cctl |= clk_oe_bit; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); + } + + for (i = 0; i < timeout; i++) { + *i2cctl |= IXGBE_I2C_CLK_OUT_BY_MAC(hw); + + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); + IXGBE_WRITE_FLUSH(hw); + /* SCL rise time (1000ns) */ + usec_delay(IXGBE_I2C_T_RISE); + + i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + if (i2cctl_r & IXGBE_I2C_CLK_IN_BY_MAC(hw)) + break; + } +} + +/** + * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Lowers the I2C clock line '1'->'0' + * Asserts the I2C clock output enable on X550 hardware. + **/ +STATIC void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) +{ + DEBUGFUNC("ixgbe_lower_i2c_clk"); + + *i2cctl &= ~(IXGBE_I2C_CLK_OUT_BY_MAC(hw)); + *i2cctl &= ~IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw); + + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); + IXGBE_WRITE_FLUSH(hw); + + /* SCL fall time (300ns) */ + usec_delay(IXGBE_I2C_T_FALL); +} + +/** + * ixgbe_set_i2c_data - Sets the I2C data bit + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * @data: I2C data value (0 or 1) to set + * + * Sets the I2C data bit + * Asserts the I2C data output enable on X550 hardware. + **/ +STATIC s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) +{ + u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_set_i2c_data"); + + if (data) + *i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); + else + *i2cctl &= ~(IXGBE_I2C_DATA_OUT_BY_MAC(hw)); + *i2cctl &= ~data_oe_bit; + + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); + IXGBE_WRITE_FLUSH(hw); + + /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ + usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA); + + if (!data) /* Can't verify data in this case */ + return IXGBE_SUCCESS; + if (data_oe_bit) { + *i2cctl |= data_oe_bit; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); + IXGBE_WRITE_FLUSH(hw); + } + + /* Verify data was set correctly */ + *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + if (data != ixgbe_get_i2c_data(hw, i2cctl)) { + status = IXGBE_ERR_I2C; + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "Error - I2C data was not set to %X.\n", + data); + } + + return status; +} + +/** + * ixgbe_get_i2c_data - Reads the I2C SDA data bit + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Returns the I2C data bit value + * Negates the I2C data output enable on X550 hardware. + **/ +STATIC bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl) +{ + u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw); + bool data; + + DEBUGFUNC("ixgbe_get_i2c_data"); + + if (data_oe_bit) { + *i2cctl |= data_oe_bit; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); + IXGBE_WRITE_FLUSH(hw); + usec_delay(IXGBE_I2C_T_FALL); + } + + if (*i2cctl & IXGBE_I2C_DATA_IN_BY_MAC(hw)) + data = 1; + else + data = 0; + + return data; +} + +/** + * ixgbe_i2c_bus_clear - Clears the I2C bus + * @hw: pointer to hardware structure + * + * Clears the I2C bus by sending nine clock pulses. + * Used when data line is stuck low. + **/ +void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) +{ + u32 i2cctl; + u32 i; + + DEBUGFUNC("ixgbe_i2c_bus_clear"); + + ixgbe_i2c_start(hw); + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + + ixgbe_set_i2c_data(hw, &i2cctl, 1); + + for (i = 0; i < 9; i++) { + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Min high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Min low period of clock is 4.7us*/ + usec_delay(IXGBE_I2C_T_LOW); + } + + ixgbe_i2c_start(hw); + + /* Put the i2c bus back to default state */ + ixgbe_i2c_stop(hw); +} + +/** + * ixgbe_tn_check_overtemp - Checks if an overtemp occurred. + * @hw: pointer to hardware structure + * + * Checks if the LASI temp alarm status was triggered due to overtemp + **/ +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u16 phy_data = 0; + + DEBUGFUNC("ixgbe_tn_check_overtemp"); + + if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) + goto out; + + /* Check that the LASI temp alarm status was triggered */ + hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data); + + if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) + goto out; + + status = IXGBE_ERR_OVERTEMP; + ERROR_REPORT1(IXGBE_ERROR_CAUTION, "Device over temperature"); +out: + return status; +} + +/** + * ixgbe_set_copper_phy_power - Control power for copper phy + * @hw: pointer to hardware structure + * @on: true for on, false for off + */ +s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on) +{ + s32 status; + u16 reg; + + if (!on && ixgbe_mng_present(hw)) + return 0; + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + if (status) + return status; + + if (on) { + reg &= ~IXGBE_MDIO_PHY_SET_LOW_POWER_MODE; + } else { + if (ixgbe_check_reset_blocked(hw)) + return 0; + reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE; + } + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + reg); + return status; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.h new file mode 100644 index 0000000000..d4d5f63342 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_phy.h @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_PHY_H_ +#define _IXGBE_PHY_H_ + +#include "ixgbe_type.h" +#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0 +#define IXGBE_I2C_EEPROM_DEV_ADDR2 0xA2 +#define IXGBE_I2C_EEPROM_BANK_LEN 0xFF + +/* EEPROM byte offsets */ +#define IXGBE_SFF_IDENTIFIER 0x0 +#define IXGBE_SFF_IDENTIFIER_SFP 0x3 +#define IXGBE_SFF_VENDOR_OUI_BYTE0 0x25 +#define IXGBE_SFF_VENDOR_OUI_BYTE1 0x26 +#define IXGBE_SFF_VENDOR_OUI_BYTE2 0x27 +#define IXGBE_SFF_1GBE_COMP_CODES 0x6 +#define IXGBE_SFF_10GBE_COMP_CODES 0x3 +#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8 +#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C +#define IXGBE_SFF_SFF_8472_SWAP 0x5C +#define IXGBE_SFF_SFF_8472_COMP 0x5E +#define IXGBE_SFF_SFF_8472_OSCB 0x6E +#define IXGBE_SFF_SFF_8472_ESCB 0x76 +#define IXGBE_SFF_IDENTIFIER_QSFP_PLUS 0xD +#define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0 0xA5 +#define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1 0xA6 +#define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2 0xA7 +#define IXGBE_SFF_QSFP_CONNECTOR 0x82 +#define IXGBE_SFF_QSFP_10GBE_COMP 0x83 +#define IXGBE_SFF_QSFP_1GBE_COMP 0x86 +#define IXGBE_SFF_QSFP_CABLE_LENGTH 0x92 +#define IXGBE_SFF_QSFP_DEVICE_TECH 0x93 + +/* Bitmasks */ +#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4 +#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8 +#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4 +#define IXGBE_SFF_1GBASESX_CAPABLE 0x1 +#define IXGBE_SFF_1GBASELX_CAPABLE 0x2 +#define IXGBE_SFF_1GBASET_CAPABLE 0x8 +#define IXGBE_SFF_10GBASESR_CAPABLE 0x10 +#define IXGBE_SFF_10GBASELR_CAPABLE 0x20 +#define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8 +#define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8 +#define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0 +#define IXGBE_SFF_ADDRESSING_MODE 0x4 +#define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE 0x1 +#define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE 0x8 +#define IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE 0x23 +#define IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL 0x0 +#define IXGBE_I2C_EEPROM_READ_MASK 0x100 +#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3 +#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0 +#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1 +#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 +#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 + +#define IXGBE_CS4227 0xBE /* CS4227 address */ +#define IXGBE_CS4227_GLOBAL_ID_LSB 0 +#define IXGBE_CS4227_GLOBAL_ID_MSB 1 +#define IXGBE_CS4227_SCRATCH 2 +#define IXGBE_CS4227_GLOBAL_ID_VALUE 0x03E5 +#define IXGBE_CS4227_EFUSE_PDF_SKU 0x19F +#define IXGBE_CS4223_SKU_ID 0x0010 /* Quad port */ +#define IXGBE_CS4227_SKU_ID 0x0014 /* Dual port */ +#define IXGBE_CS4227_RESET_PENDING 0x1357 +#define IXGBE_CS4227_RESET_COMPLETE 0x5AA5 +#define IXGBE_CS4227_RETRIES 15 +#define IXGBE_CS4227_EFUSE_STATUS 0x0181 +#define IXGBE_CS4227_LINE_SPARE22_MSB 0x12AD /* Reg to program speed */ +#define IXGBE_CS4227_LINE_SPARE24_LSB 0x12B0 /* Reg to program EDC */ +#define IXGBE_CS4227_HOST_SPARE22_MSB 0x1AAD /* Reg to program speed */ +#define IXGBE_CS4227_HOST_SPARE24_LSB 0x1AB0 /* Reg to program EDC */ +#define IXGBE_CS4227_EEPROM_STATUS 0x5001 +#define IXGBE_CS4227_EEPROM_LOAD_OK 0x0001 +#define IXGBE_CS4227_SPEED_1G 0x8000 +#define IXGBE_CS4227_SPEED_10G 0 +#define IXGBE_CS4227_EDC_MODE_CX1 0x0002 +#define IXGBE_CS4227_EDC_MODE_SR 0x0004 +#define IXGBE_CS4227_EDC_MODE_DIAG 0x0008 +#define IXGBE_CS4227_RESET_HOLD 500 /* microseconds */ +#define IXGBE_CS4227_RESET_DELAY 450 /* milliseconds */ +#define IXGBE_CS4227_CHECK_DELAY 30 /* milliseconds */ +#define IXGBE_PE 0xE0 /* Port expander address */ +#define IXGBE_PE_OUTPUT 1 /* Output register offset */ +#define IXGBE_PE_CONFIG 3 /* Config register offset */ +#define IXGBE_PE_BIT1 (1 << 1) + +/* Flow control defines */ +#define IXGBE_TAF_SYM_PAUSE 0x400 +#define IXGBE_TAF_ASM_PAUSE 0x800 + +/* Bit-shift macros */ +#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24 +#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16 +#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 8 + +/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */ +#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600 +#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500 +#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00 +#define IXGBE_SFF_VENDOR_OUI_INTEL 0x001B2100 + +/* I2C SDA and SCL timing parameters for standard mode */ +#define IXGBE_I2C_T_HD_STA 4 +#define IXGBE_I2C_T_LOW 5 +#define IXGBE_I2C_T_HIGH 4 +#define IXGBE_I2C_T_SU_STA 5 +#define IXGBE_I2C_T_HD_DATA 5 +#define IXGBE_I2C_T_SU_DATA 1 +#define IXGBE_I2C_T_RISE 1 +#define IXGBE_I2C_T_FALL 1 +#define IXGBE_I2C_T_SU_STO 4 +#define IXGBE_I2C_T_BUF 5 + +#ifndef IXGBE_SFP_DETECT_RETRIES +#define IXGBE_SFP_DETECT_RETRIES 10 + +#endif /* IXGBE_SFP_DETECT_RETRIES */ +#define IXGBE_TN_LASI_STATUS_REG 0x9005 +#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008 + +/* SFP+ SFF-8472 Compliance */ +#define IXGBE_SFF_SFF_8472_UNSUP 0x00 + +s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw); +bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); +enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); +s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); +s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw); +s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw); +void ixgbe_restart_auto_neg(struct ixgbe_hw *hw); +s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 *phy_data); +s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, + u16 phy_data); +s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); +s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); +s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw); +s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); +s32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw); + +/* PHY specific */ +s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *link_up); +s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw); +s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, + u16 *firmware_version); +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, + u16 *firmware_version); + +s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); +s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on); +s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw); +s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw); +s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw); +s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + u16 *list_offset, + u16 *data_offset); +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); +s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data); +s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data); +s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data); +s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data); +s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data); +s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data); +void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); +s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg, + u16 *val, bool lock); +s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg, + u16 val, bool lock); +#endif /* _IXGBE_PHY_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_procfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_procfs.c new file mode 100644 index 0000000000..18f0bff597 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_procfs.c @@ -0,0 +1,917 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" +#include "ixgbe_common.h" +#include "ixgbe_type.h" + +#ifdef IXGBE_PROCFS +#ifndef IXGBE_SYSFS + +#include +#include +#include +#include +#include + +static struct proc_dir_entry *ixgbe_top_dir = NULL; + +static struct net_device_stats *procfs_get_stats(struct net_device *netdev) +{ +#ifndef HAVE_NETDEV_STATS_IN_NETDEV + struct ixgbe_adapter *adapter; +#endif + if (netdev == NULL) + return NULL; + +#ifdef HAVE_NETDEV_STATS_IN_NETDEV + /* only return the current stats */ + return &netdev->stats; +#else + adapter = netdev_priv(netdev); + + /* only return the current stats */ + return &adapter->net_stats; +#endif /* HAVE_NETDEV_STATS_IN_NETDEV */ +} + +bool ixgbe_thermal_present(struct ixgbe_adapter *adapter) +{ + s32 status; + if (adapter == NULL) + return false; + status = ixgbe_init_thermal_sensor_thresh_generic(&(adapter->hw)); + if (status != IXGBE_SUCCESS) + return false; + + return true; +} + +static int ixgbe_fwbanner(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + return snprintf(page, count, "%s\n", adapter->eeprom_id); +} + +static int ixgbe_porttype(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + return snprintf(page, count, "%d\n", + test_bit(__IXGBE_DOWN, adapter->state)); +} + +static int ixgbe_portspeed(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + int speed = 0; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + speed = 1; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + speed = 10; + break; + case IXGBE_LINK_SPEED_10GB_FULL: + speed = 100; + break; + } + return snprintf(page, count, "%d\n", speed); +} + +static int ixgbe_wqlflag(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + return snprintf(page, count, "%d\n", adapter->wol); +} + +static int ixgbe_xflowctl(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct ixgbe_hw *hw; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", hw->fc.current_mode); +} + +static int ixgbe_rxdrops(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->rx_dropped); +} + +static int ixgbe_rxerrors(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", net_stats->rx_errors); +} + +static int ixgbe_rxupacks(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", IXGBE_READ_REG(hw, IXGBE_TPR)); +} + +static int ixgbe_rxmpacks(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", IXGBE_READ_REG(hw, IXGBE_MPRC)); +} + +static int ixgbe_rxbpacks(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", IXGBE_READ_REG(hw, IXGBE_BPRC)); +} + +static int ixgbe_txupacks(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", IXGBE_READ_REG(hw, IXGBE_TPT)); +} + +static int ixgbe_txmpacks(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", IXGBE_READ_REG(hw, IXGBE_MPTC)); +} + +static int ixgbe_txbpacks(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "%d\n", IXGBE_READ_REG(hw, IXGBE_BPTC)); +} + +static int ixgbe_txerrors(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->tx_errors); +} + +static int ixgbe_txdrops(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->tx_dropped); +} + +static int ixgbe_rxframes(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->rx_packets); +} + +static int ixgbe_rxbytes(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->rx_bytes); +} + +static int ixgbe_txframes(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->tx_packets); +} + +static int ixgbe_txbytes(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device_stats *net_stats; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + net_stats = procfs_get_stats(adapter->netdev); + if (net_stats == NULL) + return snprintf(page, count, "error: no net stats\n"); + + return snprintf(page, count, "%lu\n", + net_stats->tx_bytes); +} + +static int ixgbe_linkstat(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + int bitmask = 0; + u32 link_speed; + bool link_up = false; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + if (!test_bit(__IXGBE_DOWN, adapter->state)) + bitmask |= 1; + + if (hw->mac.ops.check_link) + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + else + /* always assume link is up, if no check link function */ + link_up = true; + if (link_up) + bitmask |= 2; + + if (adapter->old_lsc != adapter->lsc_int) { + bitmask |= 4; + adapter->old_lsc = adapter->lsc_int; + } + + return snprintf(page, count, "0x%X\n", bitmask); +} + +static int ixgbe_funcid(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct ixgbe_hw *hw; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "0x%X\n", hw->bus.func); +} + +static int ixgbe_funcvers(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void __always_unused *data) +{ + return snprintf(page, count, "%s\n", ixgbe_driver_version); +} + +static int ixgbe_macburn(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "0x%02X%02X%02X%02X%02X%02X\n", + (unsigned int)hw->mac.perm_addr[0], + (unsigned int)hw->mac.perm_addr[1], + (unsigned int)hw->mac.perm_addr[2], + (unsigned int)hw->mac.perm_addr[3], + (unsigned int)hw->mac.perm_addr[4], + (unsigned int)hw->mac.perm_addr[5]); +} + +static int ixgbe_macadmn(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_hw *hw; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + return snprintf(page, count, "0x%02X%02X%02X%02X%02X%02X\n", + (unsigned int)hw->mac.addr[0], + (unsigned int)hw->mac.addr[1], + (unsigned int)hw->mac.addr[2], + (unsigned int)hw->mac.addr[3], + (unsigned int)hw->mac.addr[4], + (unsigned int)hw->mac.addr[5]); +} + +static int ixgbe_maclla1(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct ixgbe_hw *hw; + int rc; + u16 eeprom_buff[6]; + u16 first_word = 0x37; + const u16 word_count = ARRAY_SIZE(eeprom_buff); + + if (!adapter) + return snprintf(page, count, "error: no adapter\n"); + + hw = &adapter->hw; + + rc = hw->eeprom.ops.read_buffer(hw, first_word, 1, &first_word); + if (rc != 0) + return snprintf(page, count, "error: reading pointer to the EEPROM\n"); + + if (first_word != 0x0000 && first_word != 0xFFFF) { + rc = hw->eeprom.ops.read_buffer(hw, first_word, word_count, + eeprom_buff); + if (rc != 0) + return snprintf(page, count, "error: reading buffer\n"); + } else { + memset(eeprom_buff, 0, sizeof(eeprom_buff)); + } + + switch (hw->bus.func) { + case 0: + return snprintf(page, count, "0x%04X%04X%04X\n", + eeprom_buff[0], + eeprom_buff[1], + eeprom_buff[2]); + case 1: + return snprintf(page, count, "0x%04X%04X%04X\n", + eeprom_buff[3], + eeprom_buff[4], + eeprom_buff[5]); + } + return snprintf(page, count, "unexpected port %d\n", hw->bus.func); +} + +static int ixgbe_mtusize(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device *netdev; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + netdev = adapter->netdev; + if (netdev == NULL) + return snprintf(page, count, "error: no net device\n"); + + return snprintf(page, count, "%d\n", netdev->mtu); +} + +static int ixgbe_featflag(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + int bitmask = 0; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device *netdev; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + netdev = adapter->netdev; + if (netdev == NULL) + return snprintf(page, count, "error: no net device\n"); + if (adapter->netdev->features & NETIF_F_RXCSUM) + bitmask |= 1; + return snprintf(page, count, "%d\n", bitmask); +} + +static int ixgbe_lsominct(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void __always_unused *data) +{ + return snprintf(page, count, "%d\n", 1); +} + +static int ixgbe_prommode(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + struct net_device *netdev; + + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + netdev = adapter->netdev; + if (netdev == NULL) + return snprintf(page, count, "error: no net device\n"); + + return snprintf(page, count, "%d\n", + netdev->flags & IFF_PROMISC); +} + +static int ixgbe_txdscqsz(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + return snprintf(page, count, "%d\n", adapter->tx_ring[0]->count); +} + +static int ixgbe_rxdscqsz(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + return snprintf(page, count, "%d\n", adapter->rx_ring[0]->count); +} + +static int ixgbe_rxqavg(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + int index; + int diff = 0; + u16 ntc; + u16 ntu; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + for (index = 0; index < adapter->num_rx_queues; index++) { + ntc = adapter->rx_ring[index]->next_to_clean; + ntu = adapter->rx_ring[index]->next_to_use; + + if (ntc >= ntu) + diff += (ntc - ntu); + else + diff += (adapter->rx_ring[index]->count - ntu + ntc); + } + if (adapter->num_rx_queues <= 0) + return snprintf(page, count, + "can't calculate, number of queues %d\n", + adapter->num_rx_queues); + return snprintf(page, count, "%d\n", diff/adapter->num_rx_queues); +} + +static int ixgbe_txqavg(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + int index; + int diff = 0; + u16 ntc; + u16 ntu; + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + for (index = 0; index < adapter->num_tx_queues; index++) { + ntc = adapter->tx_ring[index]->next_to_clean; + ntu = adapter->tx_ring[index]->next_to_use; + + if (ntc >= ntu) + diff += (ntc - ntu); + else + diff += (adapter->tx_ring[index]->count - ntu + ntc); + } + if (adapter->num_tx_queues <= 0) + return snprintf(page, count, + "can't calculate, number of queues %d\n", + adapter->num_tx_queues); + return snprintf(page, count, "%d\n", + diff/adapter->num_tx_queues); +} + +static int ixgbe_iovotype(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void __always_unused *data) +{ + return snprintf(page, count, "2\n"); +} + +static int ixgbe_funcnbr(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + return snprintf(page, count, "%d\n", adapter->num_vfs); +} + +static int ixgbe_pciebnbr(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; + if (adapter == NULL) + return snprintf(page, count, "error: no adapter\n"); + + return snprintf(page, count, "%d\n", adapter->pdev->bus->number); +} + +static int ixgbe_therm_location(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_therm_proc_data *therm_data = + (struct ixgbe_therm_proc_data *)data; + + if (therm_data == NULL) + return snprintf(page, count, "error: no therm_data\n"); + + return snprintf(page, count, "%d\n", therm_data->sensor_data->location); +} + + +static int ixgbe_therm_maxopthresh(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_therm_proc_data *therm_data = + (struct ixgbe_therm_proc_data *)data; + + if (therm_data == NULL) + return snprintf(page, count, "error: no therm_data\n"); + + return snprintf(page, count, "%d\n", + therm_data->sensor_data->max_op_thresh); +} + + +static int ixgbe_therm_cautionthresh(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + struct ixgbe_therm_proc_data *therm_data = + (struct ixgbe_therm_proc_data *)data; + + if (therm_data == NULL) + return snprintf(page, count, "error: no therm_data\n"); + + return snprintf(page, count, "%d\n", + therm_data->sensor_data->caution_thresh); +} + +static int ixgbe_therm_temp(char *page, char __always_unused **start, + off_t __always_unused off, int count, + int __always_unused *eof, void *data) +{ + s32 status; + struct ixgbe_therm_proc_data *therm_data = + (struct ixgbe_therm_proc_data *)data; + + if (therm_data == NULL) + return snprintf(page, count, "error: no therm_data\n"); + + status = ixgbe_get_thermal_sensor_data_generic(therm_data->hw); + if (status != IXGBE_SUCCESS) + snprintf(page, count, "error: status %d returned\n", status); + + return snprintf(page, count, "%d\n", therm_data->sensor_data->temp); +} + + +struct ixgbe_proc_type { + char name[32]; + int (*read)(char*, char**, off_t, int, int*, void*); +}; + +struct ixgbe_proc_type ixgbe_proc_entries[] = { + {"fwbanner", &ixgbe_fwbanner}, + {"porttype", &ixgbe_porttype}, + {"portspeed", &ixgbe_portspeed}, + {"wqlflag", &ixgbe_wqlflag}, + {"xflowctl", &ixgbe_xflowctl}, + {"rxdrops", &ixgbe_rxdrops}, + {"rxerrors", &ixgbe_rxerrors}, + {"rxupacks", &ixgbe_rxupacks}, + {"rxmpacks", &ixgbe_rxmpacks}, + {"rxbpacks", &ixgbe_rxbpacks}, + {"txdrops", &ixgbe_txdrops}, + {"txerrors", &ixgbe_txerrors}, + {"txupacks", &ixgbe_txupacks}, + {"txmpacks", &ixgbe_txmpacks}, + {"txbpacks", &ixgbe_txbpacks}, + {"rxframes", &ixgbe_rxframes}, + {"rxbytes", &ixgbe_rxbytes}, + {"txframes", &ixgbe_txframes}, + {"txbytes", &ixgbe_txbytes}, + {"linkstat", &ixgbe_linkstat}, + {"funcid", &ixgbe_funcid}, + {"funcvers", &ixgbe_funcvers}, + {"macburn", &ixgbe_macburn}, + {"macadmn", &ixgbe_macadmn}, + {"maclla1", &ixgbe_maclla1}, + {"mtusize", &ixgbe_mtusize}, + {"featflag", &ixgbe_featflag}, + {"lsominct", &ixgbe_lsominct}, + {"prommode", &ixgbe_prommode}, + {"txdscqsz", &ixgbe_txdscqsz}, + {"rxdscqsz", &ixgbe_rxdscqsz}, + {"txqavg", &ixgbe_txqavg}, + {"rxqavg", &ixgbe_rxqavg}, + {"iovotype", &ixgbe_iovotype}, + {"funcnbr", &ixgbe_funcnbr}, + {"pciebnbr", &ixgbe_pciebnbr}, + {"", NULL} +}; + +struct ixgbe_proc_type ixgbe_internal_entries[] = { + {"location", &ixgbe_therm_location}, + {"temp", &ixgbe_therm_temp}, + {"cautionthresh", &ixgbe_therm_cautionthresh}, + {"maxopthresh", &ixgbe_therm_maxopthresh}, + {"", NULL} +}; + +void ixgbe_del_proc_entries(struct ixgbe_adapter *adapter) +{ + int index; + int i; + char buf[16]; /* much larger than the sensor number will ever be */ + + if (ixgbe_top_dir == NULL) + return; + + for (i = 0; i < IXGBE_MAX_SENSORS; i++) { + if (adapter->therm_dir[i] == NULL) + continue; + + for (index = 0; ; index++) { + if (ixgbe_internal_entries[index].read == NULL) + break; + + remove_proc_entry(ixgbe_internal_entries[index].name, + adapter->therm_dir[i]); + } + snprintf(buf, sizeof(buf), "sensor_%d", i); + remove_proc_entry(buf, adapter->info_dir); + } + + if (adapter->info_dir != NULL) { + for (index = 0; ; index++) { + if (ixgbe_proc_entries[index].read == NULL) + break; + remove_proc_entry(ixgbe_proc_entries[index].name, + adapter->info_dir); + } + remove_proc_entry("info", adapter->eth_dir); + } + + if (adapter->eth_dir != NULL) + remove_proc_entry(pci_name(adapter->pdev), ixgbe_top_dir); +} + +/* called from ixgbe_main.c */ +void ixgbe_procfs_exit(struct ixgbe_adapter *adapter) +{ + ixgbe_del_proc_entries(adapter); +} + +int ixgbe_procfs_topdir_init() +{ + ixgbe_top_dir = proc_mkdir("driver/ixgbe", NULL); + if (ixgbe_top_dir == NULL) + return -ENOMEM; + + return 0; +} + +void ixgbe_procfs_topdir_exit() +{ + remove_proc_entry("driver/ixgbe", NULL); +} + +/* called from ixgbe_main.c */ +int ixgbe_procfs_init(struct ixgbe_adapter *adapter) +{ + int rc = 0; + int index; + int i; + char buf[16]; /* much larger than the sensor number will ever be */ + + adapter->eth_dir = NULL; + adapter->info_dir = NULL; + for (i = 0; i < IXGBE_MAX_SENSORS; i++) + adapter->therm_dir[i] = NULL; + + if (ixgbe_top_dir == NULL) { + rc = -ENOMEM; + goto fail; + } + + adapter->eth_dir = proc_mkdir(pci_name(adapter->pdev), ixgbe_top_dir); + if (adapter->eth_dir == NULL) { + rc = -ENOMEM; + goto fail; + } + + adapter->info_dir = proc_mkdir("info", adapter->eth_dir); + if (adapter->info_dir == NULL) { + rc = -ENOMEM; + goto fail; + } + for (index = 0; ; index++) { + if (ixgbe_proc_entries[index].read == NULL) + break; + if (!(create_proc_read_entry(ixgbe_proc_entries[index].name, + 0444, + adapter->info_dir, + ixgbe_proc_entries[index].read, + adapter))) { + + rc = -ENOMEM; + goto fail; + } + } + if (ixgbe_thermal_present(adapter) == false) + goto exit; + + for (i = 0; i < IXGBE_MAX_SENSORS; i++) { + + if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == + 0) + continue; + + snprintf(buf, sizeof(buf), "sensor_%d", i); + adapter->therm_dir[i] = proc_mkdir(buf, adapter->info_dir); + if (adapter->therm_dir[i] == NULL) { + rc = -ENOMEM; + goto fail; + } + for (index = 0; ; index++) { + if (ixgbe_internal_entries[index].read == NULL) + break; + /* + * therm_data struct contains pointer the read func + * will be needing + */ + adapter->therm_data[i].hw = &adapter->hw; + adapter->therm_data[i].sensor_data = + &adapter->hw.mac.thermal_sensor_data.sensor[i]; + + if (!(create_proc_read_entry( + ixgbe_internal_entries[index].name, + 0444, + adapter->therm_dir[i], + ixgbe_internal_entries[index].read, + &adapter->therm_data[i]))) { + rc = -ENOMEM; + goto fail; + } + } + } + goto exit; + +fail: + ixgbe_del_proc_entries(adapter); +exit: + return rc; +} + +#endif /* !IXGBE_SYSFS */ +#endif /* IXGBE_PROCFS */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp.c new file mode 100644 index 0000000000..c1e7a94581 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp.c @@ -0,0 +1,1644 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" +#include "ixgbe_ptp_e600.h" +#include +#include + +/* + * The 82599 and the X540 do not have true 64bit nanosecond scale + * counter registers. Instead, SYSTIME is defined by a fixed point + * system which allows the user to define the scale counter increment + * value at every level change of the oscillator driving the SYSTIME + * value. For both devices the TIMINCA:IV field defines this + * increment. On the X540 device, 31 bits are provided. However on the + * 82599 only provides 24 bits. The time unit is determined by the + * clock frequency of the oscillator in combination with the TIMINCA + * register. When these devices link at 10Gb the oscillator has a + * period of 6.4ns. In order to convert the scale counter into + * nanoseconds the cyclecounter and timecounter structures are + * used. The SYSTIME registers need to be converted to ns values by use + * of only a right shift (division by power of 2). The following math + * determines the largest incvalue that will fit into the available + * bits in the TIMINCA register. + * + * PeriodWidth: Number of bits to store the clock period + * MaxWidth: The maximum width value of the TIMINCA register + * Period: The clock period for the oscillator + * round(): discard the fractional portion of the calculation + * + * Period * [ 2 ^ ( MaxWidth - PeriodWidth ) ] + * + * For the X540, MaxWidth is 31 bits, and the base period is 6.4 ns + * For the 82599, MaxWidth is 24 bits, and the base period is 6.4 ns + * + * The period also changes based on the link speed: + * At 10Gb link or no link, the period remains the same. + * At 1Gb link, the period is multiplied by 10. (64ns) + * At 100Mb link, the period is multiplied by 100. (640ns) + * + * The calculated value allows us to right shift the SYSTIME register + * value in order to quickly convert it into a nanosecond clock, + * while allowing for the maximum possible adjustment value. + * + * These diagrams are only for the 10Gb link period + * + * SYSTIMEH SYSTIMEL + * +--------------+ +--------------+ + * X540 | 32 | | 1 | 3 | 28 | + * *--------------+ +--------------+ + * \________ 36 bits ______/ fract + * + * +--------------+ +--------------+ + * 82599 | 32 | | 8 | 3 | 21 | + * *--------------+ +--------------+ + * \________ 43 bits ______/ fract + * + * The 36 bit X540 SYSTIME overflows every + * 2^36 * 10^-9 / 60 = 1.14 minutes or 69 seconds + * + * The 43 bit 82599 SYSTIME overflows every + * 2^43 * 10^-9 / 3600 = 2.4 hours + */ +#define IXGBE_INCVAL_10GB 0x66666666 +#define IXGBE_INCVAL_1GB 0x40000000 +#define IXGBE_INCVAL_100 0x50000000 + +#define IXGBE_INCVAL_SHIFT_10GB 28 +#define IXGBE_INCVAL_SHIFT_1GB 24 +#define IXGBE_INCVAL_SHIFT_100 21 + +#define IXGBE_INCVAL_SHIFT_82599 7 +#define IXGBE_INCPER_SHIFT_82599 24 + +#define IXGBE_OVERFLOW_PERIOD (HZ * 30) +#define IXGBE_PTP_TX_TIMEOUT (HZ) + +/* We use our own definitions instead of NSEC_PER_SEC because we want to mark + * the value as a ULL to force precision when bit shifting. + */ +#define NS_PER_SEC 1000000000ULL +#define NS_PER_HALF_SEC 500000000ULL + +/* In contrast, the X550 controller has two registers, SYSTIMEH and SYSTIMEL + * which contain measurements of seconds and nanoseconds respectively. This + * matches the standard linux representation of time in the kernel. In addition, + * the X550 also has a SYSTIMER register which represents residue, or + * subnanosecond overflow adjustments. To control clock adjustment, the TIMINCA + * register is used, but it is unlike the X540 and 82599 devices. TIMINCA + * represents units of 2^-32 nanoseconds, and uses 31 bits for this, with the + * high bit representing whether the adjustent is positive or negative. Every + * clock cycle, the X550 will add 12.5 ns + TIMINCA which can result in a range + * of 12 to 13 nanoseconds adjustment. Unlike the 82599 and X540 devices, the + * X550's clock for purposes of SYSTIME generation is constant and not dependent + * on the link speed. + * + * SYSTIMEH SYSTIMEL SYSTIMER + * +--------------+ +--------------+ +-------------+ + * X550 | 32 | | 32 | | 32 | + * *--------------+ +--------------+ +-------------+ + * \____seconds___/ \_nanoseconds_/ \__2^-32 ns__/ + * + * This results in a full 96 bits to represent the clock, with 32 bits for + * seconds, 32 bits for nanoseconds (largest value is 0d999999999 or just under + * 1 second) and an additional 32 bits to measure sub nanosecond adjustments for + * underflow of adjustments. + * + * The 32 bits of seconds for the X550 overflows every + * 2^32 / ( 365.25 * 24 * 60 * 60 ) = ~136 years. + * + * In order to adjust the clock frequency for the X550, the TIMINCA register is + * provided. This register represents a + or minus nearly 0.5 ns adjustment to + * the base frequency. It is measured in 2^-32 ns units, with the high bit being + * the sign bit. This register enables software to calculate frequency + * adjustments and apply them directly to the clock rate. + * + * The math for converting ppb into TIMINCA values is fairly straightforward. + * TIMINCA value = ( Base_Frequency * ppb ) / 1000000000ULL + * + * This assumes that ppb is never high enough to create a value bigger than + * TIMINCA's 31 bits can store. This is ensured by the stack. Calculating this + * value is also simple. + * Max ppb = ( Max Adjustment / Base Frequency ) / 1000000000ULL + * + * For the X550, the Max adjustment is +/- 0.5 ns, and the base frequency is + * 12.5 nanoseconds. This means that the Max ppb is 39999999 + * Note: We subtract one in order to ensure no overflow, because the TIMINCA + * register can only hold slightly under 0.5 nanoseconds. + * + * Because TIMINCA is measured in 2^-32 ns units, we have to convert 12.5 ns + * into 2^-32 units, which is + * + * 12.5 * 2^32 = C80000000 + * + * Some revisions of hardware have a faster base frequency than the registers + * were defined for. To fix this, we use a timecounter structure with the + * proper mult and shift to convert the cycles into nanoseconds of time. + */ +#define IXGBE_X550_BASE_PERIOD 0xC80000000ULL +#define INCVALUE_MASK 0x7FFFFFFF +#define ISGN 0x80000000 +#define MAX_TIMADJ 0x7FFFFFFF + +/** + * ixgbe_ptp_setup_sdp_X540 + * @adapter: private adapter structure + * + * this function enables or disables the clock out feature on SDP0 for + * the X540 device. It will create a 1 second periodic output that can + * be used as the PPS (via an interrupt). + * + * It calculates when the system time will be on an exact second, and then + * aligns the start of the PPS signal to that value. + * + * This works by using the cycle counter shift and mult values in reverse, and + * assumes that the values we're shifting will not overflow. + */ +static void ixgbe_ptp_setup_sdp_X540(struct ixgbe_adapter *adapter) +{ + struct cyclecounter *cc = &adapter->hw_cc; + struct ixgbe_hw *hw = &adapter->hw; + u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem; + u64 ns = 0, clock_edge = 0, clock_period; + unsigned long flags; + + /* disable the pin first */ + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); + IXGBE_WRITE_FLUSH(hw); + + if (!(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) + return; + + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* enable the SDP0 pin as output, and connected to the + * native function for Timesync (ClockOut) + */ + esdp |= IXGBE_ESDP_SDP0_DIR | + IXGBE_ESDP_SDP0_NATIVE; + + /* enable the Clock Out feature on SDP0, and allow + * interrupts to occur when the pin changes + */ + tsauxc = (IXGBE_TSAUXC_EN_CLK | + IXGBE_TSAUXC_SYNCLK | + IXGBE_TSAUXC_SDP0_INT); + + /* Determine the clock time period to use. This assumes that the + * cycle counter shift is small enough to avoid overflow. + */ + clock_period = div_u64((NS_PER_HALF_SEC << cc->shift), cc->mult); + clktiml = (u32)(clock_period); + clktimh = (u32)(clock_period >> 32); + + /* Read the current clock time, and save the cycle counter value */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_read(&adapter->hw_tc); + clock_edge = adapter->hw_tc.cycle_last; + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + /* Figure out how many seconds to add in order to round up */ + div_u64_rem(ns, NS_PER_SEC, &rem); + + /* Figure out how many nanoseconds to add to round the clock edge up + * to the next full second + */ + rem = (NS_PER_SEC - rem); + + /* Adjust the clock edge to align with the next full second. */ + clock_edge += div_u64(((u64)rem << cc->shift), cc->mult); + trgttiml = (u32)clock_edge; + trgttimh = (u32)(clock_edge >> 32); + + IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml); + IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); + + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); + + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_ptp_setup_sdp_X550 + * @adapter: private adapter structure + * + * Enable or disable a clock output signal on SDP 0 for X550 hardware. + * + * Use the target time feature to align the output signal on the next full + * second. + * + * This works by using the cycle counter shift and mult values in reverse, and + * assumes that the values we're shifting will not overflow. + */ +static void ixgbe_ptp_setup_sdp_X550(struct ixgbe_adapter *adapter) +{ + struct cyclecounter *cc = &adapter->hw_cc; + struct ixgbe_hw *hw = &adapter->hw; + u32 esdp, tsauxc, freqout, trgttiml, trgttimh, rem, tssdp; + u64 ns = 0, clock_edge = 0; + struct timespec64 ts; + unsigned long flags; + + /* disable the pin first */ + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); + IXGBE_WRITE_FLUSH(hw); + + if (!(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) + return; + + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + + /* enable the SDP0 pin as output, and connected to the + * native function for Timesync (ClockOut) + */ + esdp |= IXGBE_ESDP_SDP0_DIR | + IXGBE_ESDP_SDP0_NATIVE; + + /* enable the Clock Out feature on SDP0, and use Target Time 0 to + * enable generation of interrupts on the clock change. + */ +#define IXGBE_TSAUXC_DIS_TS_CLEAR 0x40000000 + tsauxc = (IXGBE_TSAUXC_EN_CLK | IXGBE_TSAUXC_ST0 | + IXGBE_TSAUXC_EN_TT0 | IXGBE_TSAUXC_SDP0_INT | + IXGBE_TSAUXC_DIS_TS_CLEAR); + + tssdp = (IXGBE_TSSDP_TS_SDP0_EN | + IXGBE_TSSDP_TS_SDP0_CLK0); + + /* Determine the clock time period to use. This assumes that the + * cycle counter shift is small enough to avoid overflowing a 32bit + * value. + */ + freqout = (NS_PER_HALF_SEC << cc->shift) / cc->mult; + + /* Read the current clock time, and save the cycle counter value */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_read(&adapter->hw_tc); + clock_edge = adapter->hw_tc.cycle_last; + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + /* Figure out how far past the next second we are */ + div_u64_rem(ns, NS_PER_SEC, &rem); + + /* Figure out how many nanoseconds to add to round the clock edge up + * to the next full second + */ + rem = (NS_PER_SEC - rem); + + /* Adjust the clock edge to align with the next full second. */ + clock_edge += div_u64(((u64)rem << cc->shift), cc->mult); + + /* X550 hardware stores the time in 32bits of 'billions of cycles' and + * 32bits of 'cycles'. There's no guarantee that cycles represents + * nanoseconds. However, we can use the math from a timespec64 to + * convert into the hardware representation. + * + * See ixgbe_ptp_read_X550() for more details. + */ + ts = ns_to_timespec64(clock_edge); + trgttiml = (u32)ts.tv_nsec; + trgttimh = (u32)ts.tv_sec; + + IXGBE_WRITE_REG(hw, IXGBE_FREQOUT0, freqout); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); + + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_REG(hw, IXGBE_TSSDP, tssdp); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); + + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_ptp_read_X550 - read cycle counter value + * @cc: cyclecounter structure + * + * This function reads SYSTIME registers. It is called by the cyclecounter + * structure to convert from internal representation into nanoseconds. We need + * this for X550 since some skews do not have expected clock frequency and + * result of SYSTIME is 32bits of "billions of cycles" and 32 bits of + * "cycles", rather than seconds and nanoseconds. + */ +#ifdef HAVE_NON_CONST_CYCLECOUNTER +static u64 ixgbe_ptp_read_X550(struct cyclecounter *cc) +#else +static u64 ixgbe_ptp_read_X550(const struct cyclecounter *cc) +#endif +{ + struct ixgbe_adapter *adapter = + container_of(cc, struct ixgbe_adapter, hw_cc); + struct ixgbe_hw *hw = &adapter->hw; + struct timespec64 ts; + + /* storage is 32 bits of 'billions of cycles' and 32 bits of 'cycles'. + * Some revisions of hardware run at a higher frequency and so the + * cycles are not guaranteed to be nanoseconds. The timespec64 created + * here is used for its math/conversions but does not necessarily + * represent nominal time. + * + * It should be noted that this cyclecounter will overflow at a + * non-bitmask field since we have to convert our billions of cycles + * into an actual cycles count. This results in some possible weird + * situations at high cycle counter stamps. However given that 32 bits + * of "seconds" is ~138 years this isn't a problem. Even at the + * increased frequency of some revisions, this is still ~103 years. + * Since the SYSTIME values start at 0 and we never write them, it is + * highly unlikely for the cyclecounter to overflow in practice. + */ + IXGBE_READ_REG(hw, IXGBE_SYSTIMR); + ts.tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML); + ts.tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH); + + return (u64)timespec64_to_ns(&ts); +} + +/** + * ixgbe_ptp_read_82599 - read raw cycle counter (to be used by time counter) + * @cc: the cyclecounter structure + * + * this function reads the cyclecounter registers and is called by the + * cyclecounter structure used to construct a ns counter from the + * arbitrary fixed point registers + */ +#ifdef HAVE_NON_CONST_CYCLECOUNTER +static u64 ixgbe_ptp_read_82599(struct cyclecounter *cc) +#else +static u64 ixgbe_ptp_read_82599(const struct cyclecounter *cc) +#endif +{ + struct ixgbe_adapter *adapter = + container_of(cc, struct ixgbe_adapter, hw_cc); + struct ixgbe_hw *hw = &adapter->hw; + u64 stamp = 0; + + stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); + stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; + + return stamp; +} + +/** + * ixgbe_ptp_convert_to_hwtstamp - convert register value to hw timestamp + * @adapter: private adapter structure + * @hwtstamp: stack timestamp structure + * @timestamp: unsigned 64bit system time value + * + * We need to convert the adapter's RX/TXSTMP registers into a hwtstamp value + * which can be used by the stack's ptp functions. + * + * The lock is used to protect consistency of the cyclecounter and the SYSTIME + * registers. However, it does not need to protect against the Rx or Tx + * timestamp registers, as there can't be a new timestamp until the old one is + * unlatched by reading. + * + * In addition to the timestamp in hardware, some controllers need a software + * overflow cyclecounter, and this function takes this into account as well. + **/ +static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter, + struct skb_shared_hwtstamps *hwtstamp, + u64 timestamp) +{ + unsigned long flags; + struct timespec64 systime; + u64 ns; + + memset(hwtstamp, 0, sizeof(*hwtstamp)); + + switch (adapter->hw.mac.type) { + /* X550 and later hardware supposedly represent time using a seconds + * and nanoseconds counter, instead of raw 64bits nanoseconds. We need + * to convert the timestamp into cycles before it can be fed to the + * cyclecounter. We need an actual cyclecounter because some revisions + * of hardware run at a higher frequency and thus the counter does + * not represent seconds/nanoseconds. Instead it can be thought of as + * cycles and billions of cycles. + */ + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + case ixgbe_mac_E610: + /* Upper 32 bits represent billions of cycles, lower 32 bits + * represent cycles. However, we use timespec64_to_ns for the + * correct math even though the units haven't been corrected + * yet. + */ + systime.tv_sec = timestamp >> 32; + systime.tv_nsec = timestamp & 0xFFFFFFFF; + + timestamp = timespec64_to_ns(&systime); + break; + default: + break; + } + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_cyc2time(&adapter->hw_tc, timestamp); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + hwtstamp->hwtstamp = ns_to_ktime(ns); +} + +/** + * ixgbe_ptp_adjfine_82599 + * @ptp: the ptp clock structure + * @scaled_ppm: scaled parts per million adjustment from base + * + * Adjust the frequency of the SYSTIME registers by the indicated scaled_ppm + * from base frequency. + * + * Scaled parts per million is ppm with a 16-bit binary fractional field. + */ +static int ixgbe_ptp_adjfine_82599(struct ptp_clock_info *ptp, long scaled_ppm) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + struct ixgbe_hw *hw = &adapter->hw; + u64 incval; + + smp_mb(); + incval = READ_ONCE(adapter->base_incval); + incval = adjust_by_scaled_ppm(incval, scaled_ppm); + + switch (hw->mac.type) { + case ixgbe_mac_X540: + if (incval > 0xFFFFFFFFULL) + e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (u32)incval); + break; + case ixgbe_mac_82599EB: + if (incval > 0x00FFFFFFULL) + e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, + BIT(IXGBE_INCPER_SHIFT_82599) | + ((u32)incval & 0x00FFFFFFUL)); + break; + default: + break; + } + + return 0; +} + +#ifndef HAVE_PTP_CLOCK_INFO_ADJFINE +/** + * ixgbe_ptp_adjfreq_82599 - Adjust the frequency of the clock + * @info: the driver's PTP info structure + * @ppb: Parts per billion adjustment from the base + * + * Adjust the frequency of the clock by the indicated parts per billion from the + * base frequency. + */ +static int ixgbe_ptp_adjfreq_82599(struct ptp_clock_info *info, s32 ppb) +{ + long scaled_ppm; + + /* + * We want to calculate + * + * scaled_ppm = ppb * 2^16 / 1000 + * + * which simplifies to + * + * scaled_ppm = ppb * 2^13 / 125 + */ + scaled_ppm = ((long)ppb << 13) / 125; + return ixgbe_ptp_adjfine_82599(info, scaled_ppm); +} +#endif + +/** + * ixgbe_ptp_adjfine_X550 + * @ptp: the ptp clock structure + * @scaled_ppm: scaled parts per million adjustment from base + * + * Adjust the frequency of the ptp cycle counter by the + * indicated scaled_ppm from the base frequency. + * + * Scaled parts per million is ppm with a 16-bit binary fractional field. + */ +static int ixgbe_ptp_adjfine_X550(struct ptp_clock_info *ptp, long scaled_ppm) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + struct ixgbe_hw *hw = &adapter->hw; + bool neg_adj; + u64 rate; + u32 inca; + + neg_adj = diff_by_scaled_ppm(IXGBE_X550_BASE_PERIOD, scaled_ppm, &rate); + + /* warn if rate is too large */ + if (rate >= INCVALUE_MASK) + e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); + + inca = rate & INCVALUE_MASK; + if (neg_adj) + inca |= ISGN; + + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, inca); + + return 0; +} + +#ifndef HAVE_PTP_CLOCK_INFO_ADJFINE +/** + * ixgbe_ptp_adjfreq_X550 - Adjust the frequency of the clock + * @info: the driver's PTP info structure + * @ppb: Parts per billion adjustment from the base + * + * Adjust the frequency of the clock by the indicated parts per billion from the + * base frequency. + */ +static int ixgbe_ptp_adjfreq_X550(struct ptp_clock_info *info, s32 ppb) +{ + long scaled_ppm; + + /* + * We want to calculate + * + * scaled_ppm = ppb * 2^16 / 1000 + * + * which simplifies to + * + * scaled_ppm = ppb * 2^13 / 125 + */ + scaled_ppm = ((long)ppb << 13) / 125; + return ixgbe_ptp_adjfine_X550(info, scaled_ppm); +} +#endif + +/** + * ixgbe_ptp_adjtime + * @ptp: the ptp clock structure + * @delta: offset to adjust the cycle counter by + * + * adjust the timer by resetting the timecounter structure. + */ +static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + unsigned long flags; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_adjtime(&adapter->hw_tc, delta); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + if (adapter->ptp_setup_sdp) + adapter->ptp_setup_sdp(adapter); + + return 0; +} + +/** + * ixgbe_ptp_gettimex + * @ptp: the ptp clock structure + * @ts: timespec to hold the PHC timestamp + * @sts: structure to hold the system time before and after reading the PHC + * + * read the timecounter and return the correct value on ns, + * after converting it into a struct timespec. + */ +static int ixgbe_ptp_gettimex(struct ptp_clock_info *ptp, + struct timespec64 *ts, + struct ptp_system_timestamp *sts) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + struct ixgbe_hw *hw = &adapter->hw; + unsigned long flags; + u64 ns, stamp; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + /* Upper 32 bits represent billions of cycles, lower 32 bits + * represent cycles. However, we use timespec64_to_ns for the + * correct math even though the units haven't been corrected + * yet. + */ + ptp_read_system_prets(sts); + IXGBE_READ_REG(hw, IXGBE_SYSTIMR); + ptp_read_system_postts(sts); + ts->tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML); + ts->tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH); + stamp = timespec64_to_ns(ts); + break; + default: + ptp_read_system_prets(sts); + stamp = IXGBE_READ_REG(hw, IXGBE_SYSTIML); + ptp_read_system_postts(sts); + stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; + break; + } + + ns = timecounter_cyc2time(&adapter->hw_tc, stamp); + + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + *ts = ns_to_timespec64(ns); + + return 0; +} + +/** + * ixgbe_ptp_gettime + * @ptp: the ptp clock structure + * @ts: timespec64 structure to hold the current time value + * + * read the timecounter and return the correct value on ns, + * after converting it into a struct timespec64. + */ +static int __maybe_unused ixgbe_ptp_gettime(struct ptp_clock_info *ptp, + struct timespec64 *ts) +{ + return ixgbe_ptp_gettimex(ptp, ts, NULL); +} + +/** + * ixgbe_ptp_settime + * @ptp: the ptp clock structure + * @ts: the timespec containing the new time for the cycle counter + * + * reset the timecounter to use a new base value instead of the kernel + * wall timer value. + */ +static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, + ptp_caps); + unsigned long flags; + u64 ns = timespec64_to_ns(ts); + + /* reset the timecounter */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ns); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + if (adapter->ptp_setup_sdp) + adapter->ptp_setup_sdp(adapter); + + return 0; +} + +#ifndef HAVE_PTP_CLOCK_INFO_GETTIME64 +static int ixgbe_ptp_gettime32(struct ptp_clock_info *ptp, struct timespec *ts) +{ + struct timespec64 ts64; + int err; + + err = ixgbe_ptp_gettime(ptp, &ts64); + if (err) + return err; + + *ts = timespec64_to_timespec(ts64); + + return 0; +} + +static int ixgbe_ptp_settime32(struct ptp_clock_info *ptp, + const struct timespec *ts) +{ + struct timespec64 ts64; + + ts64 = timespec_to_timespec64(*ts); + return ixgbe_ptp_settime(ptp, &ts64); +} +#endif + +/** + * ixgbe_ptp_feature_enable + * @ptp: the ptp clock structure + * @rq: the requested feature to change + * @on: whether to enable or disable the feature + * + * enable (or disable) ancillary features of the phc subsystem. + * our driver only supports the PPS feature on the X540 + */ +static int ixgbe_ptp_feature_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + struct ixgbe_adapter *adapter = + container_of(ptp, struct ixgbe_adapter, ptp_caps); + + /** + * When PPS is enabled, unmask the interrupt for the ClockOut + * feature, so that the interrupt handler can send the PPS + * event when the clock SDP triggers. Clear mask when PPS is + * disabled + */ + if (rq->type != PTP_CLK_REQ_PPS || !adapter->ptp_setup_sdp) + return -ENOTSUPP; + + if (on) + adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; + else + adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; + + adapter->ptp_setup_sdp(adapter); + return 0; +} + +/** + * ixgbe_ptp_check_pps_event + * @adapter: the private adapter structure + * + * This function is called by the interrupt routine when checking for + * interrupts. It will check and handle a pps event. + */ +void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ptp_clock_event event; + + event.type = PTP_CLOCK_PPS; + + /* this check is necessary in case the interrupt was enabled via some + * alternative means (ex. debug_fs). Better to check here than + * everywhere that calls this function. + */ + if (!adapter->ptp_clock) + return; + + switch (hw->mac.type) { + case ixgbe_mac_X540: + ptp_clock_event(adapter->ptp_clock, &event); + break; + default: + break; + } +} + +/** + * ixgbe_ptp_overflow_check - watchdog task to detect SYSTIME overflow + * @adapter: private adapter struct + * + * this watchdog task periodically reads the timecounter + * in order to prevent missing when the system time registers wrap + * around. This needs to be run approximately twice a minute for the fastest + * overflowing hardware. We run it for all hardware since it shouldn't have a + * large impact. + */ +void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) +{ + bool timeout = time_is_before_jiffies(adapter->last_overflow_check + + IXGBE_OVERFLOW_PERIOD); + unsigned long flags; + + if (timeout) { + /* Update the timecounter */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_read(&adapter->hw_tc); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + adapter->last_overflow_check = jiffies; + } +} + +/** + * ixgbe_ptp_rx_hang - detect error case when Rx timestamp registers latched + * @adapter: private network adapter structure + * + * this watchdog task is scheduled to detect error case where hardware has + * dropped an Rx packet that was timestamped when the ring is full. The + * particular error is rare but leaves the device in a state unable to timestamp + * any future packets. + */ +void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + struct ixgbe_ring *rx_ring; + unsigned long rx_event; + int n; + + /* if we don't have a valid timestamp in the registers, just update the + * timeout counter and exit + */ + if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) { + adapter->last_rx_ptp_check = jiffies; + return; + } + + /* determine the most recent watchdog or rx_timestamp event */ + rx_event = adapter->last_rx_ptp_check; + for (n = 0; n < adapter->num_rx_queues; n++) { + rx_ring = adapter->rx_ring[n]; + if (time_after(rx_ring->last_rx_timestamp, rx_event)) + rx_event = rx_ring->last_rx_timestamp; + } + + /* only need to read the high RXSTMP register to clear the lock */ + if (time_is_before_jiffies(rx_event + 5*HZ)) { + IXGBE_READ_REG(hw, IXGBE_RXSTMPH); + adapter->last_rx_ptp_check = jiffies; + + adapter->rx_hwtstamp_cleared++; + e_warn(drv, "clearing RX Timestamp hang\n"); + } +} + +/** + * ixgbe_ptp_clear_tx_timestamp - utility function to clear Tx timestamp state + * @adapter: the private adapter structure + * + * This function should be called whenever the state related to a Tx timestamp + * needs to be cleared. This helps ensure that all related bits are reset for + * the next Tx timestamp event. + */ +static void ixgbe_ptp_clear_tx_timestamp(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + IXGBE_READ_REG(hw, IXGBE_TXSTMPH); + if (adapter->ptp_tx_skb) { + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb = NULL; + } + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state); +} + +/** + * ixgbe_ptp_tx_hang - detect error case where Tx timestamp never finishes + * @adapter: private network adapter structure + */ +void ixgbe_ptp_tx_hang(struct ixgbe_adapter *adapter) +{ + bool timeout = time_is_before_jiffies(adapter->ptp_tx_start + + IXGBE_PTP_TX_TIMEOUT); + + if (!adapter->ptp_tx_skb) + return; + + if (!test_bit(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state)) + return; + + /* If we haven't received a timestamp within the timeout, it is + * reasonable to assume that it will never occur, so we can unlock the + * timestamp bit when this occurs. + */ + if (timeout) { + cancel_work_sync(&adapter->ptp_tx_work); + ixgbe_ptp_clear_tx_timestamp(adapter); + adapter->tx_hwtstamp_timeouts++; + e_warn(drv, "clearing Tx timestamp hang\n"); + } +} + +/** + * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp + * @adapter: the private adapter struct + * + * if the timestamp is valid, we convert it into the timecounter ns + * value, then store that result into the shhwtstamps structure which + * is passed up the network stack + */ +static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter) +{ + struct sk_buff *skb = adapter->ptp_tx_skb; + struct ixgbe_hw *hw = &adapter->hw; + struct skb_shared_hwtstamps shhwtstamps; + u64 regval = 0; + + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL); + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32; + ixgbe_ptp_convert_to_hwtstamp(adapter, &shhwtstamps, regval); + + /* Handle cleanup of the ptp_tx_skb ourselves, and unlock the state + * bit prior to notifying the stack via skb_tstamp_tx(). This prevents + * well behaved applications from attempting to timestamp again prior + * to the lock bit being clear. + */ + adapter->ptp_tx_skb = NULL; + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state); + + /* Notify the stack and then free the skb after we've unlocked */ + skb_tstamp_tx(skb, &shhwtstamps); + dev_kfree_skb_any(skb); +} + +/** + * ixgbe_ptp_tx_hwtstamp_work + * @work: pointer to the work struct + * + * This work item polls TSYNCTXCTL valid bit to determine when a Tx hardware + * timestamp has been taken for the current skb. It is necessary, because the + * descriptor's "done" bit does not correlate with the timestamp event. + */ +void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) +{ + struct ixgbe_adapter *adapter = container_of(work, struct ixgbe_adapter, + ptp_tx_work); + struct ixgbe_hw *hw = &adapter->hw; + bool timeout = time_is_before_jiffies(adapter->ptp_tx_start + + IXGBE_PTP_TX_TIMEOUT); + u32 tsynctxctl; + + /* we have to have a valid skb to poll for a timestamp */ + if (!adapter->ptp_tx_skb) { + ixgbe_ptp_clear_tx_timestamp(adapter); + return; + } + + /* stop polling once we have a valid timestamp */ + tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); + if (tsynctxctl & IXGBE_TSYNCTXCTL_VALID) { + ixgbe_ptp_tx_hwtstamp(adapter); + return; + } + + /* check timeout last in case timestamp event just occurred */ + if (timeout) { + ixgbe_ptp_clear_tx_timestamp(adapter); + adapter->tx_hwtstamp_timeouts++; + e_warn(drv, "clearing Tx Timestamp hang\n"); + } else { + /* reschedule to keep checking if it's not available yet */ + schedule_work(&adapter->ptp_tx_work); + } +} + +/** + * ixgbe_ptp_rx_pktstamp - utility function to get RX time stamp from buffer + * @q_vector: structure containing interrupt and ring information + * @skb: the packet + * + * This function will be called by the Rx routine of the timestamp for this + * packet is stored in the buffer. The value is stored in little endian format + * starting at the end of the packet data. + */ +void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb) +{ + __le64 regval; + + /* copy the bits out of the skb, and then trim the skb length */ + skb_copy_bits(skb, skb->len - IXGBE_TS_HDR_LEN, ®val, + IXGBE_TS_HDR_LEN); + __pskb_trim(skb, skb->len - IXGBE_TS_HDR_LEN); + + /* The timestamp is recorded in little endian format, and is stored at + * the end of the packet. + * + * DWORD: N N + 1 N + 2 + * Field: End of Packet SYSTIMH SYSTIML + */ + ixgbe_ptp_convert_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb), + le64_to_cpu(regval)); +} + +/** + * ixgbe_ptp_rx_rgtstamp - utility function which checks for RX time stamp + * @q_vector: structure containing interrupt and ring information + * @skb: particular skb to send timestamp with + * + * if the timestamp is valid, we convert it into the timecounter ns + * value, then store that result into the shhwtstamps structure which + * is passed up the network stack + */ +void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb) +{ + struct ixgbe_adapter *adapter; + struct ixgbe_hw *hw; + u64 regval = 0; + u32 tsyncrxctl; + + /* we cannot process timestamps on a ring without a q_vector */ + if (!q_vector || !q_vector->adapter) + return; + + adapter = q_vector->adapter; + hw = &adapter->hw; + + /* Read the tsyncrxctl register afterwards in order to prevent taking an + * I/O hit on every packet. + */ + tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) + return; + + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); + regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; + + ixgbe_ptp_convert_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); +} + +/** + * ixgbe_ptp_get_ts_config - get current hardware timestamping configuration + * @adapter: pointer to adapter structure + * @ifr: ioctl data + * + * This function returns the current timestamping settings. Rather than + * attempt to deconstruct registers to fill in the values, simply keep a copy + * of the old settings around, and return a copy when requested. + */ +int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) +{ + struct hwtstamp_config *config = &adapter->tstamp_config; + + return copy_to_user(ifr->ifr_data, config, + sizeof(*config)) ? -EFAULT : 0; +} + +/** + * ixgbe_ptp_set_timestamp_mode - setup the hardware for the requested mode + * @adapter: the private ixgbe adapter structure + * @config: the hwtstamp configuration requested + * + * Outgoing time stamping can be enabled and disabled. Play nice and + * disable it when requested, although it shouldn't cause any overhead + * when no packet needs it. At most one packet in the queue may be + * marked for time stamping, otherwise it would be impossible to tell + * for sure to which packet the hardware time stamp belongs. + * + * Incoming time stamping has to be configured via the hardware + * filters. Not all combinations are supported, in particular event + * type has to be specified. Matching the kind of event packet is + * not supported, with the exception of "all V2 events regardless of + * level 2 or 4". + * + * Since hardware always timestamps Path delay packets when timestamping V2 + * packets, regardless of the type specified in the register, only use V2 + * Event mode. This more accurately tells the user what the hardware is going + * to do anyways. + * + * Note: this may modify the hwtstamp configuration towards a more general + * mode, if required to support the specifically requested mode. + */ +static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, + struct hwtstamp_config *config) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; + u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; + u32 tsync_rx_mtrl = PTP_EV_PORT << 16; + bool is_l2 = false; + u32 regval; + + /* reserved for future extensions */ + if (config->flags) + return -EINVAL; + + switch (config->tx_type) { + case HWTSTAMP_TX_OFF: + tsync_tx_ctl = 0; + fallthrough; + case HWTSTAMP_TX_ON: + break; + default: + return -ERANGE; + } + + switch (config->rx_filter) { + case HWTSTAMP_FILTER_NONE: + tsync_rx_ctl = 0; + tsync_rx_mtrl = 0; + adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + break; + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; + tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; + adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + break; + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; + tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; + adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + break; + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; + is_l2 = true; + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; + adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + break; + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: +#ifdef HAVE_HWTSTAMP_FILTER_NTP_ALL + case HWTSTAMP_FILTER_NTP_ALL: +#endif /* HAVE_HWTSTAMP_FILTER_NTP_ALL */ + case HWTSTAMP_FILTER_ALL: + /* The X550 controller is capable of timestamping all packets, + * which allows it to accept any filter. + */ + if (hw->mac.type >= ixgbe_mac_X550) { + tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; + config->rx_filter = HWTSTAMP_FILTER_ALL; + adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + break; + } + fallthrough; + default: + /* register RXMTRL must be set in order to do V1 packets, + * therefore it is not possible to time stamp both V1 Sync and + * Delay_Req messages unless hardware supports timestamping all + * packets => return error + */ + adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + config->rx_filter = HWTSTAMP_FILTER_NONE; + return -ERANGE; + } + + if (hw->mac.type == ixgbe_mac_82598EB) { + adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + if (tsync_rx_ctl | tsync_tx_ctl) + return -ERANGE; + return 0; + } + + /* Per-packet timestamping only works if the filter is set to all + * packets. Since this is desired, always timestamp all packets as long + * as any Rx filter was configured. + */ + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + /* enable timestamping all packets only if at least some + * packets were requested. Otherwise, play nice and disable + * timestamping + */ + if (config->rx_filter == HWTSTAMP_FILTER_NONE) + break; + + tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED | + IXGBE_TSYNCRXCTL_TYPE_ALL | + IXGBE_TSYNCRXCTL_TSIP_UT_EN; + config->rx_filter = HWTSTAMP_FILTER_ALL; + adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; + is_l2 = true; + break; + default: + break; + } + + /* define ethertype filter for timestamping L2 packets */ + if (is_l2) + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), + (IXGBE_ETQF_FILTER_EN | /* enable filter */ + IXGBE_ETQF_1588 | /* enable timestamping */ + ETH_P_1588)); /* 1588 eth protocol type */ + else + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), 0); + + /* enable/disable TX */ + regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); + regval &= ~IXGBE_TSYNCTXCTL_ENABLED; + regval |= tsync_tx_ctl; + IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval); + + /* enable/disable RX */ + regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK); + regval |= tsync_rx_ctl; + IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval); + + /* define which PTP packets are time stamped */ + IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, tsync_rx_mtrl); + + IXGBE_WRITE_FLUSH(hw); + + /* clear TX/RX time stamp registers, just to be sure */ + ixgbe_ptp_clear_tx_timestamp(adapter); + IXGBE_READ_REG(hw, IXGBE_RXSTMPH); + + return 0; +} + +/** + * ixgbe_ptp_set_ts_config - user entry point for timestamp mode + * @adapter: pointer to adapter struct + * @ifr: ioctl data + * + * Set hardware to requested mode. If unsupported, return an error with no + * changes. Otherwise, store the mode for future reference. + */ +int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) +{ + struct hwtstamp_config config; + int err; + + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) + return -EFAULT; + + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) + err = ixgbe_ptp_set_timestamp_mode_e600(adapter, &config); + else + err = ixgbe_ptp_set_timestamp_mode(adapter, &config); + if (err) + return err; + + /* save these settings for future reference */ + memcpy(&adapter->tstamp_config, &config, + sizeof(adapter->tstamp_config)); + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? + -EFAULT : 0; +} + +static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter, + u32 *shift, u32 *incval) +{ + /** + * Scale the NIC cycle counter by a large factor so that + * relatively small corrections to the frequency can be added + * or subtracted. The drawbacks of a large factor include + * (a) the clock register overflows more quickly, (b) the cycle + * counter structure must be able to convert the systime value + * to nanoseconds using only a multiplier and a right-shift, + * and (c) the value must fit within the timinca register space + * => math based on internal DMA clock rate and available bits + * + * Note that when there is no link, internal DMA clock is same as when + * link speed is 10Gb. Set the registers correctly even when link is + * down to preserve the clock setting + */ + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + *shift = IXGBE_INCVAL_SHIFT_100; + *incval = IXGBE_INCVAL_100; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + *shift = IXGBE_INCVAL_SHIFT_1GB; + *incval = IXGBE_INCVAL_1GB; + break; + case IXGBE_LINK_SPEED_10GB_FULL: + default: + *shift = IXGBE_INCVAL_SHIFT_10GB; + *incval = IXGBE_INCVAL_10GB; + break; + } +} + +/** + * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw + * @adapter: pointer to the adapter structure + * + * This function should be called to set the proper values for the TIMINCA + * register and tell the cyclecounter structure what the tick rate of SYSTIME + * is. It does not directly modify SYSTIME registers or the timecounter + * structure. It should be called whenever a new TIMINCA value is necessary, + * such as during initialization or when the link speed changes. + */ +void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct cyclecounter cc; + unsigned long flags; + u32 incval = 0; + u32 tsauxc = 0; + u32 fuse0 = 0; + + /* For some of the boards below this mask is technically incorrect. + * The timestamp mask overflows at approximately 61bits. However the + * particular hardware does not overflow on an even bitmask value. + * Instead, it overflows due to conversion of upper 32bits billions of + * cycles. Timecounters are not really intended for this purpose so + * they do not properly function if the overflow point isn't 2^N-1. + * However, the actual SYSTIME values in question take ~138 years to + * overflow. In practice this means they won't actually overflow. A + * proper fix to this problem would require modification of the + * timecounter delta calculations. + */ + cc.mask = CLOCKSOURCE_MASK(64); + cc.mult = 1; + cc.shift = 0; + + switch (hw->mac.type) { + case ixgbe_mac_X550EM_x: + /* SYSTIME assumes X550EM_x board frequency is 300Mhz, and is + * designed to represent seconds and nanoseconds when this is + * the case. However, some revisions of hardware have a 400Mhz + * clock and we have to compensate for this frequency + * variation using corrected mult and shift values. + */ + fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)); + if (!(fuse0 & IXGBE_FUSES0_300MHZ)) { + cc.mult = 3; + cc.shift = 2; + } + fallthrough; + case ixgbe_mac_X550EM_a: + case ixgbe_mac_X550: + cc.read = ixgbe_ptp_read_X550; + + /* enable SYSTIME counter */ + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); + tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, + tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); + IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); + + IXGBE_WRITE_FLUSH(hw); + + break; + case ixgbe_mac_X540: + cc.read = ixgbe_ptp_read_82599; + + ixgbe_ptp_link_speed_adjust(adapter, &cc.shift, &incval); + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); + break; + case ixgbe_mac_82599EB: + cc.read = ixgbe_ptp_read_82599; + + ixgbe_ptp_link_speed_adjust(adapter, &cc.shift, &incval); + incval >>= IXGBE_INCVAL_SHIFT_82599; + cc.shift -= IXGBE_INCVAL_SHIFT_82599; + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, + BIT(IXGBE_INCPER_SHIFT_82599) | incval); + break; + default: + /* other devices aren't supported */ + return; + } + + /* update the base incval used to calculate frequency adjustment */ + WRITE_ONCE(adapter->base_incval, incval); + smp_mb(); + + /* need lock to prevent incorrect read while modifying cyclecounter */ + spin_lock_irqsave(&adapter->tmreg_lock, flags); + memcpy(&adapter->hw_cc, &cc, sizeof(adapter->hw_cc)); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); +} + +/** + * ixgbe_ptp_reset + * @adapter: the ixgbe private board structure + * + * When the MAC resets, all the hardware bits for timesync are reset. This + * function is used to re-enable the device for PTP based on current settings. + * We do lose the current clock time, so just reset the cyclecounter to the + * system real clock time. + * + * This function will maintain hwtstamp_config settings, and resets the SDP + * output if it was enabled. + */ +void ixgbe_ptp_reset(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + unsigned long flags; + + /* reset the hardware timestamping mode */ + ixgbe_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); + + /* 82598 does not support PTP */ + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + ixgbe_ptp_start_cyclecounter(adapter); + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_init(&adapter->hw_tc, &adapter->hw_cc, + ktime_get_real_ns()); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + adapter->last_overflow_check = jiffies; + + /* Now that the shift has been calculated and the systime + * registers reset, (re-)enable the Clock out feature + */ + if (adapter->ptp_setup_sdp) + adapter->ptp_setup_sdp(adapter); +} + +/** + * ixgbe_ptp_create_clock + * @adapter: the ixgbe private adapter structure + * + * This function performs setup of the user entry point function table and + * initializes the PTP clock device, which is used to access the clock-like + * features of the PTP core. It will be called by ixgbe_ptp_init, and may + * reuse a previously initialized clock (such as during a suspend/resume + * cycle). + */ +static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + long err; + + /* do nothing if we already have a clock device */ + if (!IS_ERR_OR_NULL(adapter->ptp_clock)) + return 0; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + snprintf(adapter->ptp_caps.name, + sizeof(adapter->ptp_caps.name), + "%s", netdev->name); + adapter->ptp_caps.owner = THIS_MODULE; + adapter->ptp_caps.max_adj = 250000000; + adapter->ptp_caps.n_alarm = 0; + adapter->ptp_caps.n_ext_ts = 0; + adapter->ptp_caps.n_per_out = 0; + adapter->ptp_caps.pps = 1; +#ifdef HAVE_PTP_CLOCK_INFO_ADJFINE + adapter->ptp_caps.adjfine = ixgbe_ptp_adjfine_82599; +#else + adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; +#endif + adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; +#ifdef HAVE_PTP_CLOCK_INFO_GETTIME64 +#ifdef HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL + adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; +#else + adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; +#endif /* HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL */ + adapter->ptp_caps.settime64 = ixgbe_ptp_settime; +#else /* HAVE_PTP_CLOCK_INFO_GETTIME64 */ + adapter->ptp_caps.gettime = ixgbe_ptp_gettime32; + adapter->ptp_caps.settime = ixgbe_ptp_settime32; +#endif /* !HAVE_PTP_CLOCK_INFO_GETTIME64 */ + adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; + adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_X540; + break; + case ixgbe_mac_82599EB: + snprintf(adapter->ptp_caps.name, + sizeof(adapter->ptp_caps.name), + "%s", netdev->name); + adapter->ptp_caps.owner = THIS_MODULE; + adapter->ptp_caps.max_adj = 250000000; + adapter->ptp_caps.n_alarm = 0; + adapter->ptp_caps.n_ext_ts = 0; + adapter->ptp_caps.n_per_out = 0; + adapter->ptp_caps.pps = 0; +#ifdef HAVE_PTP_CLOCK_INFO_ADJFINE + adapter->ptp_caps.adjfine = ixgbe_ptp_adjfine_82599; +#else + adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; +#endif + adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; +#ifdef HAVE_PTP_CLOCK_INFO_GETTIME64 +#ifdef HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL + adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; +#else + adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; +#endif /* HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL */ + adapter->ptp_caps.settime64 = ixgbe_ptp_settime; +#else /* HAVE_PTP_CLOCK_INFO_GETTIME64 */ + adapter->ptp_caps.gettime = ixgbe_ptp_gettime32; + adapter->ptp_caps.settime = ixgbe_ptp_settime32; +#endif /* !HAVE_PTP_CLOCK_INFO_GETTIME64 */ + adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; + break; + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name); + adapter->ptp_caps.owner = THIS_MODULE; + adapter->ptp_caps.max_adj = 30000000; + adapter->ptp_caps.n_alarm = 0; + adapter->ptp_caps.n_ext_ts = 0; + adapter->ptp_caps.n_per_out = 0; + adapter->ptp_caps.pps = 1; +#ifdef HAVE_PTP_CLOCK_INFO_ADJFINE + adapter->ptp_caps.adjfine = ixgbe_ptp_adjfine_X550; +#else + adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550; +#endif + adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; +#ifdef HAVE_PTP_CLOCK_INFO_GETTIME64 +#ifdef HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL + adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; +#else + adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; +#endif /* HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL */ + adapter->ptp_caps.settime64 = ixgbe_ptp_settime; +#else /* HAVE_PTP_CLOCK_INFO_GETTIME64 */ + adapter->ptp_caps.gettime = ixgbe_ptp_gettime32; + adapter->ptp_caps.settime = ixgbe_ptp_settime32; +#endif /* !HAVE_PTP_CLOCK_INFO_GETTIME64 */ + adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; + adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_X550; + break; + default: + adapter->ptp_clock = NULL; + adapter->ptp_setup_sdp = NULL; + return -EOPNOTSUPP; + } + + adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, + ixgbe_pf_to_dev(adapter)); + if (IS_ERR(adapter->ptp_clock)) { + err = PTR_ERR(adapter->ptp_clock); + adapter->ptp_clock = NULL; + e_dev_err("ptp_clock_register failed\n"); + return err; + } else if (adapter->ptp_clock) + e_dev_info("registered PHC device on %s\n", netdev->name); + + /* set default timestamp mode to disabled here. We do this in + * create_clock instead of init, because we don't want to override the + * previous settings during a resume cycle. + */ + adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; + adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; + + return 0; +} + +/** + * ixgbe_ptp_init + * @adapter: the ixgbe private adapter structure + * + * This function performs the required steps for enabling PTP + * support. If PTP support has already been loaded it simply calls the + * cyclecounter init routine and exits. + */ +void ixgbe_ptp_init(struct ixgbe_adapter *adapter) +{ + /* initialize the spin lock first since we can't control when a user + * will call the entry functions once we have initialized the clock + * device + */ + spin_lock_init(&adapter->tmreg_lock); + + /* obtain a PTP device, or re-use an existing device */ + if (ixgbe_ptp_create_clock(adapter)) + return; + + /* we have a clock so we can initialize work now */ + INIT_WORK(&adapter->ptp_tx_work, ixgbe_ptp_tx_hwtstamp_work); + + /* reset the PTP related hardware bits */ + ixgbe_ptp_reset(adapter); + + /* enter the IXGBE_PTP_RUNNING state */ + set_bit(__IXGBE_PTP_RUNNING, adapter->state); + + return; +} + +/** + * ixgbe_ptp_suspend - stop PTP work items + * @adapter: pointer to adapter struct + * + * this function suspends PTP activity, and prevents more PTP work from being + * generated, but does not destroy the PTP clock device. + */ +void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter) +{ + /* Leave the IXGBE_PTP_RUNNING state. */ + if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, adapter->state)) + return; + + adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; + if (adapter->ptp_setup_sdp) + adapter->ptp_setup_sdp(adapter); + + /* ensure that we cancel any pending PTP Tx work item in progress */ + cancel_work_sync(&adapter->ptp_tx_work); + ixgbe_ptp_clear_tx_timestamp(adapter); +} + +/** + * ixgbe_ptp_stop - close the PTP device + * @adapter: pointer to adapter struct + * + * completely destroy the PTP device, should only be called when the device is + * being fully closed. + */ +void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) +{ + if (ixgbe_is_mac_E6xx(adapter->hw.mac.type)) { + ixgbe_ptp_release_e600(adapter); + return; + } + + /* first, suspend PTP activity */ + ixgbe_ptp_suspend(adapter); + + /* disable the PTP clock device */ + if (adapter->ptp_clock) { + ptp_clock_unregister(adapter->ptp_clock); + adapter->ptp_clock = NULL; + e_dev_info("removed PHC on %s\n", + adapter->netdev->name); + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.c new file mode 100644 index 0000000000..8e57d9704e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.c @@ -0,0 +1,1308 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#include +#include +#include "ixgbe_ptp_e600.h" + +#define IXGBE_E600_CC_SHIFT 31 +#define IXGBE_E600_CC_MULT BIT(IXGBE_E600_CC_SHIFT) +#define IXGBE_E600_FADJ_SHIFT 9 +#define IXGBE_E600_FADJ_DENOMINATOR 15625ULL +#define IXGBE_E600_REFRESH_INTERVAL HZ +#define TSAUXC_DIS_TS_CLEAR 0x40000000 + +static const struct ptp_pin_desc e600_pin_cfg[] = { + { "SDP0", 0, 0, 0 } +}; + +/** + * ixgbe_ptp_read_phc_e600 - read PHC value + * @cc: cyclecounter structure + * + * Return: PHC nanosecond time. + */ +#ifdef HAVE_NON_CONST_CYCLECOUNTER +static u64 ixgbe_ptp_read_phc_e600(struct cyclecounter *cc) +#else +static u64 ixgbe_ptp_read_phc_e600(const struct cyclecounter *cc) +#endif +{ + struct ixgbe_adapter *adapter = + container_of(cc, struct ixgbe_adapter, hw_cc); + struct ixgbe_hw *hw = &adapter->hw; + struct timespec64 ts; + + IXGBE_READ_REG(hw, IXGBE_SYSTIMR); + ts.tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML); + ts.tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH); + + return (u64)timespec64_to_ns(&ts); +} + +/** + * ixgbe_ptp_update_1pps_e600 - update 1PPS start and frequency + * @adapter: the private adapter struct + */ +static void ixgbe_ptp_update_1pps_e600(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 period; + u64 start; + + period = (NSEC_PER_SEC << adapter->hw_cc.shift) / adapter->hw_cc.mult; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FREQOUT0, period / 2); + + start = IXGBE_READ_REG(hw, IXGBE_TRGTTIML0) + + IXGBE_READ_REG(hw, IXGBE_TRGTTIMH0) * NSEC_PER_SEC; + + /* Start the timer at the closest multiple of period. + * If it happens in the past, round it up. + */ + start = DIV_U64_ROUND_CLOSEST(start, period) * period; + if (start < ixgbe_ptp_read_phc_e600(&adapter->hw_cc)) + start = roundup_u64(start, period); + + start = (start << adapter->hw_cc.shift) / adapter->hw_cc.mult + + adapter->hw_tc.frac; + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, start % NSEC_PER_SEC); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, start / NSEC_PER_SEC); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_ptp_adjfine_e600 - adjust PHC increment rate + * @ptp: the ptp clock structure + * @scaled_ppm: scaled parts per million adjustment from base + * + * Adjust the frequency of the PTP timecounter by the indicated scaled_ppm + * from the base frequency. + * + * Scaled parts per million is ppm with a 16-bit binary fractional field. + * + * Return: 0 on success. + */ +static int ixgbe_ptp_adjfine_e600(struct ptp_clock_info *ptp, long scaled_ppm) +{ + struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, + ptp_caps); + unsigned long flags; + s64 adj; + + adj = (s64)scaled_ppm << IXGBE_E600_FADJ_SHIFT; + adj = div_s64(adj, IXGBE_E600_FADJ_DENOMINATOR); + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_read(&adapter->hw_tc); + adapter->hw_cc.mult = IXGBE_E600_CC_MULT + adj; + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + ixgbe_ptp_update_1pps_e600(adapter); + + return 0; +} + +#ifndef HAVE_PTP_CLOCK_INFO_ADJFINE +/** + * ixgbe_ptp_adjfreq_e600 - Adjust the frequency of the clock + * @info: the driver's PTP info structure + * @ppb: Parts per billion adjustment from the base + * + * Adjust the frequency of the clock by the indicated parts per billion from the + * base frequency. + * + * Return: 0 on success. + */ +static int ixgbe_ptp_adjfreq_e600(struct ptp_clock_info *info, s32 ppb) +{ + long scaled_ppm; + + /* + * We want to calculate + * + * scaled_ppm = ppb * 2^16 / 1000 + * + * which simplifies to + * + * scaled_ppm = ppb * 2^13 / 125 + */ + scaled_ppm = ((long)ppb << 13) / 125; + return ixgbe_ptp_adjfine_e600(info, scaled_ppm); +} + +#endif +/** + * ixgbe_ptp_gettime_e600 - get PHC time and optional system timestamp + * @ptp: the ptp clock structure + * @ts: timespec64 structure to hold the current time value + * + * Return: 0 on success. + */ +static int ixgbe_ptp_gettime_e600(struct ptp_clock_info *ptp, + struct timespec64 *ts) +{ + struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, + ptp_caps); + unsigned long flags; + u64 ns; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_read(&adapter->hw_tc); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + *ts = ns_to_timespec64(ns); + + return 0; +} + +/** + * ixgbe_ptp_setup_sdp_e600 + * @adapter: private adapter structure + * @rq: periodic output request + * @on: true to enable SDP output, false otherwise + * + * Enable or disable a clock output signal on SDP0 for E600 hardware. + * + * Use the target time feature to align the output signal on the next full + * second. + * + * Return: 0 on success, negative error code otherwise + */ +static int ixgbe_ptp_setup_sdp_e600(struct ixgbe_adapter *adapter, + struct ptp_perout_request *rq, bool on) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 period, esdp, tsauxc, tssdp; + u64 clk, start, phase; + struct timespec64 ts; + int err; + +#ifdef PTP_PEROUT_PHASE + if (rq->flags & ~PTP_PEROUT_PHASE) + return -EOPNOTSUPP; +#else /* !PTP_PEROUT_PHASE */ + if (rq->flags) + return -EOPNOTSUPP; +#endif /* PTP_PEROUT_PHASE */ + + /* Disable the pin first. */ + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); + IXGBE_WRITE_FLUSH(hw); + + period = rq->period.sec * NSEC_PER_SEC + rq->period.nsec; + if (!on || !period) + return 0; + + if (period != NSEC_PER_SEC) { + e_dev_err("CLK Period != 1s is not supported\n"); + return -EINVAL; + } + + start = rq->start.sec * NSEC_PER_SEC + rq->start.nsec; + +#ifdef PTP_PEROUT_PHASE + /* If PTP_PEROUT_PHASE is set, rq has phase instead of start time. */ + if (rq->flags & PTP_PEROUT_PHASE) + phase = start; + else +#endif /* PTP_PEROUT_PHASE */ + div64_u64_rem(start, period, &phase); + + if (phase % NSEC_PER_SEC != 0) { + e_dev_err("Start/phase not on a second boundary is not supported\n"); + return -EINVAL; + } + + /* Convert 1PPS output frequency and start time with cyclecounter + * params. + */ + period = (NSEC_PER_SEC << adapter->hw_cc.shift) / adapter->hw_cc.mult; + start = (start << adapter->hw_cc.shift) / adapter->hw_cc.mult + + adapter->hw_tc.frac; + + /* If we have only phase or start time is in the past, start the timer + * at the next multiple of period, maintaining phase at least 0.1 second + * from now, so we have time to write it to HW. + */ + err = ixgbe_ptp_gettime_e600(&adapter->ptp_caps, &ts); + if (err) + return err; + clk = (u64)timespec64_to_ns(&ts) + NSEC_PER_MSEC * 100; +#ifdef PTP_PEROUT_PHASE + if (rq->flags & PTP_PEROUT_PHASE || start <= clk) +#else /* !PTP_PEROUT_PHASE */ + if (start <= clk) +#endif /* PTP_PEROUT_PHASE */ + start = roundup_u64(clk, period) + phase; + + /* Write half of the period (50% duty cycle). */ + IXGBE_WRITE_REG(hw, IXGBE_FREQOUT0, period / 2); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, start % NSEC_PER_SEC); + IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, start / NSEC_PER_SEC); + + /* Enable the SDP0 pin as output. */ + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + esdp |= IXGBE_ESDP_SDP0_DIR | IXGBE_ESDP_SDP0_NATIVE; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + + tssdp = IXGBE_TSSDP_TS_SDP0_EN | IXGBE_TSSDP_TS_SDP0_CLK0; + IXGBE_WRITE_REG(hw, IXGBE_TSSDP, tssdp); + + /* Enable the Clock Out feature on SDP0, and use Target Time 0 to + * enable generation of interrupts on the clock change. + */ + tsauxc = IXGBE_TSAUXC_EN_CLK | IXGBE_TSAUXC_ST0 | IXGBE_TSAUXC_EN_TT0 | + IXGBE_TSAUXC_SDP0_INT | TSAUXC_DIS_TS_CLEAR; + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); + + IXGBE_WRITE_FLUSH(hw); + + return 0; +} + +/** + * ixgbe_ptp_verify_pin_e600 - verify if pin supports requested pin function + * @info: the driver's PTP info structure + * @pin: pin index + * @func: assigned function + * @chan: assigned channel + * + * Return: 0 on success, -EOPNOTSUPP when function is not supported. + */ +static int ixgbe_ptp_verify_pin_e600(struct ptp_clock_info *info, + unsigned int pin, + enum ptp_pin_function func, + unsigned int chan) +{ + /* Is assigned function allowed? */ + switch (func) { + case PTP_PF_PEROUT: + case PTP_PF_NONE: + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +/** + * ixgbe_ptp_gpio_enable_e600 - Enable/disable ancillary features of PHC + * @info: the driver's PTP info structure + * @rq: the requested feature to change + * @on: enable/disable flag + * + * Return: 0 on success, negative error code otherwise. + */ +static int ixgbe_ptp_gpio_enable_e600(struct ptp_clock_info *info, + struct ptp_clock_request *rq, int on) +{ + struct ixgbe_adapter *adapter = container_of(info, struct ixgbe_adapter, + ptp_caps); + + switch (rq->type) { + case PTP_CLK_REQ_PEROUT: + { + int err = ixgbe_ptp_setup_sdp_e600(adapter, &rq->perout, on); + + if (!err && on) + adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; + else + adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; + + return err; + } + default: + return -EOPNOTSUPP; + } +} + +/** + * ixgbe_ptp_settime_e600 - set PHC time + * @ptp: the ptp clock structure + * @ts: the timespec containing the new time + * + * Return: 0 on success. + */ +static int ixgbe_ptp_settime_e600(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, + ptp_caps); + u64 ns = timespec64_to_ns(ts); + unsigned long flags; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ns); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + ixgbe_ptp_update_1pps_e600(adapter); + + return 0; +} + +#ifndef HAVE_PTP_CLOCK_INFO_GETTIME64 +/** + * ixgbe_ptp_gettime32_e600 - get PHC time + * @ptp: the ptp clock structure + * @ts: timespec64 structure to hold the current time value + * + * Return: 0 on success. + */ +static int ixgbe_ptp_gettime32_e600(struct ptp_clock_info *ptp, + struct timespec *ts) +{ + struct timespec64 ts64; + int err; + + err = ixgbe_ptp_gettime_e600(ptp, &ts64); + if (err) + return err; + + *ts = timespec64_to_timespec(ts64); + + return 0; +} + +/** + * ixgbe_ptp_settime_e600 - set PHC time + * @ptp: the ptp clock structure + * @ts: the timespec containing the new time + * + * Return: 0 on success. + */ +static int ixgbe_ptp_settime32_e600(struct ptp_clock_info *ptp, + const struct timespec *ts) +{ + struct timespec64 ts64 = timespec_to_timespec64(*ts); + + return ixgbe_ptp_settime_e600(ptp, &ts64); +} +#endif + +/** + * ixgbe_ptp_adjtime_e600 - adjust time by a specified delta + * @ptp: the ptp clock structure + * @delta: offset to adjust the cycle counter by + * + * Return: 0 on success. + */ +static int ixgbe_ptp_adjtime_e600(struct ptp_clock_info *ptp, s64 delta) +{ + struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, + ptp_caps); + unsigned long flags; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_adjtime(&adapter->hw_tc, delta); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + ixgbe_ptp_update_1pps_e600(adapter); + + return 0; +} + +/** + * ixgbe_ptp_cfg_phy_timestamping_e610 - configure PTP timestamping on the PHY + * @adapter: pointer to the adapter structure + * + * This function is intended only for E610 PHY. + */ +static void ixgbe_ptp_cfg_phy_timestamping_e610(struct ixgbe_adapter *adapter) +{ + struct ixgbe_ptp_e600 *ptp = &adapter->ptp; + struct ixgbe_hw *hw = &adapter->hw; + u8 ptp_request, flags; + bool enable; + s32 status; + + /* Enable only for <= 1 GB. */ + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_10_FULL: + case IXGBE_LINK_SPEED_100_FULL: + case IXGBE_LINK_SPEED_1GB_FULL: + enable = true; + break; + default: + enable = false; + break; + } + + status = ixgbe_get_ptp_by_phy(hw, &ptp_request, &flags, + &ptp->max_drift_threshold); + if (status) { + e_dev_err("PTP by PHY get failed, status=%d\n", status); + return; + } + + ptp->ptp_by_phy_ena = ptp_request; + + /* Don't reconfigure if already set correctly. */ + if (enable == ptp_request) + goto skip_set; + + if (adapter->ptp.vlan_ena) + flags = FIELD_PREP(IXGBE_SET_PTP_BY_PHY_ETHERTYPE_M, + IXGBE_SET_PTP_BY_PHY_ETHERTYPE_VLAN_TAG); + else + flags = FIELD_PREP(IXGBE_SET_PTP_BY_PHY_ETHERTYPE_M, + IXGBE_SET_PTP_BY_PHY_ETHERTYPE_NO_VLAN_TAG); + + status = ixgbe_set_ptp_by_phy(hw, enable, flags); + if (status) { + e_dev_err("PTP by PHY set failed, status=%d\n", status); + return; + } + +skip_set: + if (!enable) { + ptp->ptp_by_phy_ena = false; + return; + } + + /* Clear timestamping status registers. */ + IXGBE_WRITE_REG(hw, PROXY_TX_STS, 0); + IXGBE_WRITE_REG(hw, PROXY_RX_STS, 0); + + ptp_request = IXGBE_SET_PTP_BY_PHY_PTP_REQ_SET_PHY_PARAMS; + status = ixgbe_set_ptp_by_phy(hw, ptp_request, flags); + if (status) + e_dev_err("PTP by PHY set PHY params failed, status=%d\n", + status); + + ptp_request = IXGBE_SET_PTP_BY_PHY_PTP_REQ_TOD_INIT; + status = ixgbe_set_ptp_by_phy(hw, ptp_request, 0); + if (status) { + e_dev_err("PTP by PHY ToD init failed, status=%d\n", status); + } else { + ptp->ptp_by_phy_ena = true; +#ifdef HAVE_PTP_CANCEL_WORKER_SYNC + ptp_schedule_worker(adapter->ptp_clock, 0); +#else /* HAVE_PTP_CANCEL_WORKER_SYNC */ + kthread_mod_delayed_work(ptp->ptp_kworker, &ptp->ptp_aux_work, + 0); +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ + } +} + +/** + * ixgbe_ptp_clear_tx_timestamp_e600 - clear Tx timestamp state + * @adapter: the private adapter structure + * + * This function should be called whenever the state related to a Tx timestamp + * needs to be cleared. This helps ensure that all related bits are reset for + * the next Tx timestamp event. + */ +static void ixgbe_ptp_clear_tx_timestamp_e600(struct ixgbe_adapter *adapter) +{ + IXGBE_READ_REG(&adapter->hw, IXGBE_TXSTMPH); + if (adapter->ptp_tx_skb) { + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb = NULL; + } + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state); +} + +/** + * ixgbe_ptp_is_tx_ptp - check if packet is a PTP packet + * @adapter: the private adapter struct + * @skb: the packet + * + * Return: true if packet is a PTP packet, false otherwise. + */ +bool ixgbe_ptp_is_tx_ptp(struct ixgbe_adapter *adapter, struct sk_buff *skb) +{ + unsigned int ptp_class; + struct ptp_header *hdr; + + if (likely(!adapter->ptp.ptp_by_phy_ena)) + return false; + + ptp_class = ptp_classify_raw(skb); + if (likely(ptp_class == PTP_CLASS_NONE)) + return false; + + skb_reset_mac_header(skb); + hdr = ptp_parse_header(skb, ptp_class); + + /* Clear Tx TS bit if it's a PTP packet with invalid header. */ + if (!hdr) + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state); + else + adapter->ptp.ptp_seq_id = ntohs(hdr->sequence_id); + + return true; +} + +/** + * ixgbe_ptp_tx_phytstamp_e600 - read the PHY Tx timestamp from the register + * @adapter: the private adapter struct + * @sts: value of the status register + * + * Return: + * * %0 - success + * * %-ENXIO - Tx TS not in progress + * * %-EINVAL - invalid sequence ID + * * %other - FW error code + */ +static int ixgbe_ptp_tx_phytstamp_e600(struct ixgbe_adapter *adapter, u32 sts) +{ + struct sk_buff *skb = adapter->ptp_tx_skb; + struct skb_shared_hwtstamps shhwtstamps; + struct ixgbe_hw *hw = &adapter->hw; + u64 tstamp; + int err; + + /* Return error if PTP Tx TS not in progress. */ + if (!test_bit(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state)) { + err = -ENXIO; + goto err; + } + + err = FIELD_GET(PROXY_STS_ERR, sts); + if (err) + goto err; + + /* Incorrect sequence ID, discard the timestamp. */ + if (FIELD_GET(PROXY_STS_SEQ_ID, sts) != adapter->ptp.ptp_seq_id) { + err = -EINVAL; + goto err; + } + + tstamp = IXGBE_READ_REG(hw, PROXY_TX_TS_LOW); + tstamp |= (u64)IXGBE_READ_REG(hw, PROXY_TX_TS_HIGH) << 32; + spin_lock(&adapter->tmreg_lock); + tstamp = timecounter_cyc2time(&adapter->hw_tc, tstamp); + spin_unlock(&adapter->tmreg_lock); + + /* Notify the stack and then free the skb after we've unlocked. */ + shhwtstamps.hwtstamp = ns_to_ktime(tstamp); + skb_tstamp_tx(skb, &shhwtstamps); +err: + adapter->ptp_tx_skb = NULL; + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, adapter->state); + dev_kfree_skb_any(skb); + if (err) + adapter->tx_hwtstamp_skipped++; + + return err; +} + +/** + * ixgbe_ptp_rx_find_skb_e600 - find skb for a specified sequence ID and add + * Rx timestamp if found + * @adapter: the private adapter struct + * @seq_id: PTP packet sequence ID + * @ns: Rx timestamp + * + * Return: true if skb found, false otherwise. + */ +static bool ixgbe_ptp_rx_find_skb_e600(struct ixgbe_adapter *adapter, + u16 seq_id, u64 tstamp) +{ + struct ixgbe_rx_phy_ts_skb_e610 *rx_skb; + bool skb_found = false; + unsigned int i; + + for (i = 0; i < adapter->num_q_vectors; i++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; + + spin_lock(&q_vector->ptp_skbs_lock_e600); + list_for_each_entry(rx_skb, &q_vector->ptp_skbs_e600, list) { + if (rx_skb->seq_id != seq_id) + continue; + + skb_hwtstamps(rx_skb->skb)->hwtstamp = + ns_to_ktime(tstamp); + napi_schedule(&q_vector->napi); + skb_found = true; + break; + } + spin_unlock(&q_vector->ptp_skbs_lock_e600); + + if (skb_found) + return true; + } + + return false; +} + +/** + * ixgbe_ptp_rx_complete_tstamp_e600 - complete cached PHY Rx timestamps + * @adapter: the private adapter struct + * @sts: value of the status register + * + * Return: + * * %0 - success + * * %-ENOMEM - no memory left on the device + */ +static int ixgbe_ptp_rx_complete_tstamp_e600(struct ixgbe_adapter *adapter, + u32 sts) +{ + u16 seq_id = FIELD_GET(PROXY_STS_SEQ_ID, sts); + u64 ns; + + ns = IXGBE_READ_REG(&adapter->hw, PROXY_RX_TS_LOW); + ns |= (u64)IXGBE_READ_REG(&adapter->hw, PROXY_RX_TS_HIGH) << 32; + spin_lock(&adapter->tmreg_lock); + ns = timecounter_cyc2time(&adapter->hw_tc, ns); + spin_unlock(&adapter->tmreg_lock); + + /* Try to find matching skb. If not found, cache the timestamp. */ + if (!ixgbe_ptp_rx_find_skb_e600(adapter, seq_id, ns)) { + struct ixgbe_rx_phy_ts_skb_e610 *tstamp; + + tstamp = kzalloc(sizeof(*tstamp), GFP_KERNEL); + if (!tstamp) + return -ENOMEM; + + tstamp->ns = ns; + tstamp->seq_id = seq_id; + tstamp->acquired = jiffies; + spin_lock(&adapter->ptp.rx_tstamps_lock); + list_add_tail(&tstamp->list, &adapter->ptp.rx_tstamps); + spin_unlock(&adapter->ptp.rx_tstamps_lock); + } + + return 0; +} + +/** + * ixgbe_ptp_fw_intr_e600 - handle PTP by PHY FW interrupt + * @adapter: the private adapter struct + * + * Return: + * * %0 - success + * * %-EINTR - not a Tx/Rx TS interrupt cause + * * %-ENXIO - Tx TS not in progress + * * %-ENOMEM - no memory left on the device + * * %-EINVAL - invalid sequence ID + * * %other - FW error code + */ +int ixgbe_ptp_fw_intr_e600(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 tx_sts, rx_sts; + int err = -EINTR; + + /* Handle FW Tx interrupt if status register indicates it. */ + tx_sts = IXGBE_READ_REG(hw, PROXY_TX_STS); + if (tx_sts & PROXY_STS_TS_RDY && tx_sts & PROXY_STS_TS_INT) { + err = ixgbe_ptp_tx_phytstamp_e600(adapter, tx_sts); + IXGBE_WRITE_REG(hw, PROXY_TX_STS, 0); + } else if (!(tx_sts & PROXY_STS_TS_RDY) && tx_sts & PROXY_STS_TS_INT) { + atomic_set(&adapter->ptp.reinit_phy_tod, true); +#ifdef HAVE_PTP_CANCEL_WORKER_SYNC + ptp_schedule_worker(adapter->ptp_clock, 0); +#else /* HAVE_PTP_CANCEL_WORKER_SYNC */ + kthread_mod_delayed_work(adapter->ptp.ptp_kworker, + &adapter->ptp.ptp_aux_work, 0); +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ + err = 0; + IXGBE_WRITE_REG(hw, PROXY_TX_STS, 0); + } + + /* Handle FW Rx interrupt if status register indicates it. */ + rx_sts = IXGBE_READ_REG(hw, PROXY_RX_STS); + if (rx_sts & PROXY_STS_TS_RDY && rx_sts & PROXY_STS_TS_INT) { + err = ixgbe_ptp_rx_complete_tstamp_e600(adapter, rx_sts); + IXGBE_WRITE_REG(hw, PROXY_RX_STS, 0); + } else if (!(rx_sts & PROXY_STS_TS_RDY) && rx_sts & PROXY_STS_TS_INT) { + IXGBE_WRITE_REG(hw, PROXY_RX_STS, 0); + } + + IXGBE_WRITE_FLUSH(hw); + return err; +} + +/** + * ixgbe_ptp_rx_complete_skb_e600 - complete held PTP skbs + * @q_vector: structure containing interrupt and ring information + * @budget: amount of work driver is allowed to do this pass, in packets + * + * This function takes PTP skbs, which were held in order to add Rx timestamp to + * them. This is necessary due to the interrupt with Rx TS coming usually after + * the driver receives the packet. + * When skb has the timestamp added it's sent further up the stack. Otherwise, + * it's removed after 500 ms timeout. + * + * Return: number of completed skbs. + */ +unsigned int ixgbe_ptp_rx_complete_skb_e600(struct ixgbe_q_vector *q_vector, + int *budget) +{ + struct ixgbe_rx_phy_ts_skb_e610 *rx_skb, *n; + unsigned int cleaned = 0; + unsigned long flags; + + spin_lock_irqsave(&q_vector->ptp_skbs_lock_e600, flags); + list_for_each_entry_safe(rx_skb, n, &q_vector->ptp_skbs_e600, list) { + unsigned long acquired = rx_skb->acquired; + + /* Flush skbs without timestamps after 500 ms. */ + if (time_is_before_jiffies(acquired + msecs_to_jiffies(500))) { + consume_skb(rx_skb->skb); + list_del(&rx_skb->list); + kfree(rx_skb); + continue; + } + + if (skb_hwtstamps(rx_skb->skb)->hwtstamp) { + napi_gro_receive(&q_vector->napi, rx_skb->skb); + list_del(&rx_skb->list); + kfree(rx_skb); + (*budget)--; + cleaned++; + if (*budget <= 0) + break; + } + } + spin_unlock_irqrestore(&q_vector->ptp_skbs_lock_e600, flags); + + return cleaned; +} + +/** + * ixgbe_ptp_rx_phytstamp_e600 - utility function to get RX tstamp PTP reserved + * field + * @q_vector: structure containing interrupt and ring information + * @skb: the packet + * @ptp_class: class of the PTP packet + * + * This function will be called by the Rx routine of the timestamp for this + * packet is stored in the buffer. + */ +void ixgbe_ptp_rx_phytstamp_e600(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb, unsigned int ptp_class) +{ + struct ixgbe_rx_phy_ts_skb_e610 *tstamp, *n, *rx_skb; + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ptp_header *hdr; + unsigned long flags; + __le64 val; + u16 seq_id; + + q_vector->ptp_hold_rx_skb = false; + /* Copy the bits out of the skb, and then trim the skb length. */ + skb_copy_bits(skb, skb->len - IXGBE_TS_HDR_LEN, &val, IXGBE_TS_HDR_LEN); + __pskb_trim(skb, skb->len - IXGBE_TS_HDR_LEN); + + skb_reset_mac_header(skb); + hdr = ptp_parse_header(skb, ptp_class); + if (!hdr) { + u64 ns = le64_to_cpu(val); + struct timespec64 ts = { + .tv_sec = upper_32_bits(ns), + .tv_nsec = lower_32_bits(ns) + }; + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + ns = timecounter_cyc2time(&adapter->hw_tc, + timespec64_to_ns(&ts)); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + + skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); + return; + } + + q_vector->ptp_hold_rx_skb = true; + skb_hwtstamps(skb)->hwtstamp = 0; + seq_id = ntohs(hdr->sequence_id); + + /* Try to find matching timestamp. If not found, cache the skb. */ + spin_lock_irqsave(&adapter->ptp.rx_tstamps_lock, flags); + list_for_each_entry_safe(tstamp, n, &adapter->ptp.rx_tstamps, list) { + /* Flush timestamps without skbs after 500 ms. */ + if (time_is_before_jiffies(tstamp->acquired + + msecs_to_jiffies(500))) { + list_del(&tstamp->list); + kfree(tstamp); + continue; + } + + if (seq_id != tstamp->seq_id) + continue; + + skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(tstamp->ns); + list_del(&tstamp->list); + kfree(tstamp); + q_vector->ptp_hold_rx_skb = false; + + break; + } + spin_unlock_irqrestore(&adapter->ptp.rx_tstamps_lock, flags); + + if (!q_vector->ptp_hold_rx_skb) + return; + + /* Add skb to the list. */ + rx_skb = kzalloc(sizeof(*rx_skb), GFP_KERNEL); + if (!rx_skb) + return; + + rx_skb->skb = skb; + rx_skb->acquired = jiffies; + rx_skb->seq_id = seq_id; + spin_lock_irqsave(&q_vector->ptp_skbs_lock_e600, flags); + list_add_tail(&rx_skb->list, &q_vector->ptp_skbs_e600); + spin_unlock_irqrestore(&q_vector->ptp_skbs_lock_e600, flags); +} + +/** + * ixgbe_ptp_by_phy_set_params_e600 - configure PTP by PHY parameters + * @adapter: pointer to the adapter structure + */ +static void ixgbe_ptp_by_phy_set_params_e600(struct ixgbe_adapter *adapter) +{ + u8 ptp_request, flags; + s32 status; + + ptp_request = IXGBE_SET_PTP_BY_PHY_PTP_REQ_SET_PHY_PARAMS; + if (adapter->ptp.vlan_ena) + flags = FIELD_PREP(IXGBE_SET_PTP_BY_PHY_ETHERTYPE_M, + IXGBE_SET_PTP_BY_PHY_ETHERTYPE_VLAN_TAG); + else + flags = FIELD_PREP(IXGBE_SET_PTP_BY_PHY_ETHERTYPE_M, + IXGBE_SET_PTP_BY_PHY_ETHERTYPE_NO_VLAN_TAG); + + status = ixgbe_set_ptp_by_phy(&adapter->hw, ptp_request, flags); + if (status) + e_dev_err("PTP by PHY set PHY params failed, status=%d\n", + status); +} + +/** + * ixgbe_do_aux_work - do PTP periodic work + * @info: Driver's PTP info structure + * + * Do periodic PTP work for PTP by PHY feature. This consists of: + * - updating cached PHC time at least once per 4.3 seconds, + * - setting PTP by PHY parameters on VLAN state change, which cannot be + * performed in atomic context, + * - reinitializing PHY ToD on PHY ToD drift interrupt, which cannot be + * performed in atomic context. + * + * Reschedule work every second to have a safe margin and to ensure that cached + * PHC time never goes stale, even with OS scheduling delays. + * + * Return: delay of the next auxiliary work scheduling time (>=0) or negative + * value in case further scheduling is not required + */ +static long ixgbe_do_aux_work(struct ptp_clock_info *info) +{ + struct ixgbe_adapter *adapter = container_of(info, struct ixgbe_adapter, + ptp_caps); + struct timespec64 ts; + + ixgbe_ptp_gettime_e600(info, &ts); + + if (atomic_cmpxchg(&adapter->ptp.vlan_change, true, false)) + ixgbe_ptp_by_phy_set_params_e600(adapter); + + if (atomic_cmpxchg(&adapter->ptp.reinit_phy_tod, true, false)) { + u8 request = IXGBE_SET_PTP_BY_PHY_PTP_REQ_TOD_INIT; + s32 status; + + status = ixgbe_set_ptp_by_phy(&adapter->hw, request, 0); + if (status) + e_dev_err("PTP by PHY ToD reinit failed, status=%d\n", + status); + } + + return msecs_to_jiffies(MSEC_PER_SEC); +} + +#ifndef HAVE_PTP_CANCEL_WORKER_SYNC +static void ptp_aux_kworker(struct kthread_work *work) +{ + struct ixgbe_ptp_e600 *ptp = container_of(work, struct ixgbe_ptp_e600, + ptp_aux_work.work); + struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, + ptp); + struct ptp_clock_info *info = &adapter->ptp_caps; + long delay; + + delay = ixgbe_do_aux_work(info); + + if (delay >= 0) + kthread_queue_delayed_work(ptp->ptp_kworker, &ptp->ptp_aux_work, + delay); +} + +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ +/** + * ixgbe_ptp_cfg_phy_vlan_e600 - configure PTP vlan tag timestamping on PHY + * @adapter: pointer to the adapter structure + * @enabled: true to indicate to the PHY that VLAN is enabled, false otherwise + */ +void ixgbe_ptp_cfg_phy_vlan_e600(struct ixgbe_adapter *adapter, bool enabled) +{ + if (adapter->ptp.vlan_ena == enabled) + return; + + adapter->ptp.vlan_ena = enabled; + if (!adapter->ptp.ptp_by_phy_ena) + return; + + /* Schedule worker to handle VLAN change. */ + atomic_set(&adapter->ptp.vlan_change, true); +#ifdef HAVE_PTP_CANCEL_WORKER_SYNC + ptp_schedule_worker(adapter->ptp_clock, 0); +#else /* HAVE_PTP_CANCEL_WORKER_SYNC */ + kthread_mod_delayed_work(adapter->ptp.ptp_kworker, + &adapter->ptp.ptp_aux_work, 0); +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ +} + +/** + * ixgbe_ptp_set_timestamp_mode_e600 - setup the hardware for the requested mode + * @adapter: the private ixgbe adapter structure + * @config: the hwtstamp configuration requested + * + * Outgoing time stamping can be enabled and disabled. Play nice and + * disable it when requested, although it shouldn't cause any overhead + * when no packet needs it. At most one packet in the queue may be + * marked for time stamping, otherwise it would be impossible to tell + * for sure to which packet the hardware time stamp belongs. + * + * Incoming time stamping has to be configured via the hardware + * filters. Not all combinations are supported, in particular event + * type has to be specified. Matching the kind of event packet is + * not supported, with the exception of "all V2 events regardless of + * level 2 or 4". + * + * Since hardware always timestamps Path delay packets when timestamping V2 + * packets, regardless of the type specified in the register, only use V2 + * Event mode. This more accurately tells the user what the hardware is going + * to do anyways. + * + * Note: this may modify the hwtstamp configuration towards a more general + * mode, if required to support the specifically requested mode. + * + * Return: 0 on success, -EINVAL on invalid flags, -ERANGE on invalid filter. + */ +int ixgbe_ptp_set_timestamp_mode_e600(struct ixgbe_adapter *adapter, + struct hwtstamp_config *config) +{ + int rx_mtrl_filter = HWTSTAMP_FILTER_NONE; + struct ixgbe_hw *hw = &adapter->hw; + u32 val; + + /* Reserved for future extensions. */ + if (config->flags) + return -EINVAL; + + /* Enable/disable TX. */ + val = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); + switch (config->tx_type) { + case HWTSTAMP_TX_OFF: + val &= ~IXGBE_TSYNCTXCTL_ENABLED; + break; + case HWTSTAMP_TX_ON: + val |= IXGBE_TSYNCTXCTL_ENABLED; + break; + default: + return -ERANGE; + } + IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, val); + + /* Enable/disable RX. */ + val = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); + switch (config->rx_filter) { + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: +#ifdef HAVE_HWTSTAMP_FILTER_NTP_ALL + case HWTSTAMP_FILTER_NTP_ALL: +#endif /* HAVE_HWTSTAMP_FILTER_NTP_ALL */ + case HWTSTAMP_FILTER_ALL: + /* Per-packet timestamping only works if the filter is set to + * all packets. Since this is desired, always timestamp + * all packets as long as any Rx filter was configured. + * + * Enable timestamping all packets only if at least some packets + * were requested. Otherwise, play nice and disable + * timestamping. + */ + val = IXGBE_TSYNCRXCTL_ENABLED | + IXGBE_TSYNCRXCTL_TYPE_ALL | + IXGBE_TSYNCRXCTL_TSIP_UT_EN; + + /* Cache original Rx filter for RXMTRL. */ + rx_mtrl_filter = config->rx_filter; + config->rx_filter = HWTSTAMP_FILTER_ALL; + adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; + break; + case HWTSTAMP_FILTER_NONE: + default: + val &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK); + adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + if (config->rx_filter != HWTSTAMP_FILTER_NONE) { + /* Register RXMTRL must be set in order to do V1 + * packets, therefore it is not possible to timestamp + * both V1 Sync and Delay_Req messages unless hardware + * supports timestamping all packets => return error. + */ + config->rx_filter = HWTSTAMP_FILTER_NONE; + return -ERANGE; + } + } + IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, val); + + /* Define which PTP packets are timestamped. */ + switch (rx_mtrl_filter) { + case HWTSTAMP_FILTER_NONE: + val = 0; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + val = IXGBE_RXMTRL_V1_SYNC_MSG | PTP_EV_PORT << 16; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + val = IXGBE_RXMTRL_V1_DELAY_REQ_MSG | PTP_EV_PORT << 16; + break; + default: + val = PTP_EV_PORT << 16; + } + IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, val); + + /* Define ethertype filter for timestamping L2 packets. */ + if (config->rx_filter != HWTSTAMP_FILTER_NONE) + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), + (IXGBE_ETQF_FILTER_EN | + IXGBE_ETQF_1588 | + ETH_P_1588)); + else + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), 0); + + IXGBE_WRITE_FLUSH(hw); + + ixgbe_ptp_clear_tx_timestamp_e600(adapter); + return 0; +} + +/** + * ixgbe_ptp_link_up_e600 - perform PTP adjustments on a link up + * @adapter: pointer to the adapter structure + */ +void ixgbe_ptp_link_up_e600(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.dev_caps.common_cap.ptp_by_phy_ll) { + ixgbe_ptp_cfg_phy_timestamping_e610(adapter); + /* Sleep for at least 2 seconds for the PHY to reset, so that + * the driver does not report any link flaps. + */ + msleep(MSEC_PER_SEC * 3); + } +} + +static const struct cyclecounter ixgbe_ptp_cc_e600 = { + .read = ixgbe_ptp_read_phc_e600, + .mask = CYCLECOUNTER_MASK(32), + .mult = IXGBE_E600_CC_MULT, + .shift = IXGBE_E600_CC_SHIFT, +}; + +/** + * ixgbe_ptp_start_clock_e600 - create the cycle counter from hw + * @adapter: pointer to the adapter structure + * + * This function should be called to set the proper values for the TIMINCA + * register and tell the cyclecounter structure what the tick rate of SYSTIME + * is. It does not directly modify SYSTIME registers or the timecounter + * structure. It should be called whenever a new TIMINCA value is necessary, + * such as during initialization or when the link speed changes. + */ +static void ixgbe_ptp_start_clock_e600(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + unsigned long flags; + u32 tsauxc; + + adapter->hw_cc = ixgbe_ptp_cc_e600; + /* enable SYSTIME counter */ + tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, + tsauxc | IXGBE_TSAUXC_DISABLE_SYSTIME); + IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, + tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); + IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); + IXGBE_WRITE_FLUSH(hw); + + spin_lock_irqsave(&adapter->tmreg_lock, flags); + timecounter_init(&adapter->hw_tc, &adapter->hw_cc, + ktime_get_real_ns()); + spin_unlock_irqrestore(&adapter->tmreg_lock, flags); +} + +/** + * ixgbe_ptp_reset_e600 + * @adapter: the ixgbe private board structure + * + * When the MAC resets, all the hardware bits for timesync are reset. This + * function is used to re-enable the device for PTP based on current settings. + * We do lose the current clock time, so just reset the cyclecounter to the + * system real clock time. + * + * This function will maintain hwtstamp_config settings, and resets the SDP + * output if it was enabled. + */ +void ixgbe_ptp_reset_e600(struct ixgbe_adapter *adapter) +{ + /* reset the hardware timestamping mode */ + ixgbe_ptp_start_clock_e600(adapter); + ixgbe_ptp_set_timestamp_mode_e600(adapter, &adapter->tstamp_config); +} + +/** + * ixgbe_ptp_create_clock - create a PTP clock device + * @adapter: the ixgbe private adapter structure + * + * This function performs setup of the user entry point function table and + * initializes the PTP clock device, which is used to access the clock-like + * features of the PTP core. It will be called by ixgbe_ptp_init, and may + * reuse a previously initialized clock (such as during a suspend/resume + * cycle). + * + * Return: 0 on success, negative error code otherwise. + */ +static long ixgbe_ptp_create_clock_e600(struct ixgbe_adapter *adapter) +{ + struct ptp_clock_info *info = &adapter->ptp_caps; + struct net_device *netdev = adapter->netdev; + long err; + + /* Do nothing if we already have a clock device. */ + if (!IS_ERR_OR_NULL(adapter->ptp_clock)) + return 0; + + snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name); + info->owner = THIS_MODULE; + info->max_adj = 500000000; +#ifdef HAVE_PTP_CLOCK_INFO_ADJFINE + info->adjfine = ixgbe_ptp_adjfine_e600; +#else + info->adjfreq = ixgbe_ptp_adjfreq_e600; +#endif + info->adjtime = ixgbe_ptp_adjtime_e600; +#ifdef HAVE_PTP_CLOCK_INFO_GETTIME64 + info->gettime64 = ixgbe_ptp_gettime_e600; + info->settime64 = ixgbe_ptp_settime_e600; +#else /* HAVE_PTP_CLOCK_INFO_GETTIME64 */ + info->gettime = ixgbe_ptp_gettime32_e600; + info->settime = ixgbe_ptp_settime32_e600; +#endif /* !HAVE_PTP_CLOCK_INFO_GETTIME64 */ +#ifdef HAVE_PTP_CANCEL_WORKER_SYNC + info->do_aux_work = ixgbe_do_aux_work; +#endif /* HAVE_PTP_CANCEL_WORKER_SYNC */ + info->n_pins = 1; + info->n_per_out = 1; + info->pin_config = adapter->ptp.pin_config; + info->enable = ixgbe_ptp_gpio_enable_e600; + info->verify = ixgbe_ptp_verify_pin_e600; + + adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, + ixgbe_pf_to_dev(adapter)); + if (IS_ERR(adapter->ptp_clock)) { + err = PTR_ERR(adapter->ptp_clock); + adapter->ptp_clock = NULL; + e_dev_err("ptp_clock_register failed\n"); + return err; + } else if (adapter->ptp_clock) { + e_dev_info("Registered PHC device on %s\n", netdev->name); + } + + return 0; +} + +/** + * ixgbe_ptp_init_e600 - initialize PTP support on HW and SW + * @adapter: the ixgbe private adapter structure + * + * This function performs the required steps for enabling PTP support. + */ +void ixgbe_ptp_init_e600(struct ixgbe_adapter *adapter) +{ + adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; + adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; + + adapter->ptp.pin_config[0] = e600_pin_cfg[0]; + spin_lock_init(&adapter->tmreg_lock); + INIT_LIST_HEAD(&adapter->ptp.rx_tstamps); + spin_lock_init(&adapter->ptp.rx_tstamps_lock); + + /* Obtain a PTP device, or re-use an existing device. */ + if (ixgbe_ptp_create_clock_e600(adapter)) + return; + + INIT_WORK(&adapter->ptp_tx_work, ixgbe_ptp_tx_hwtstamp_work); + +#ifndef HAVE_PTP_CANCEL_WORKER_SYNC + kthread_init_delayed_work(&adapter->ptp.ptp_aux_work, ptp_aux_kworker); + adapter->ptp.ptp_kworker = kthread_create_worker(0, "ixgbe_ptp"); + if (IS_ERR(adapter->ptp.ptp_kworker)) { + e_dev_err("Failed to create ptp aux_worker err=%li\n", + PTR_ERR(adapter->ptp.ptp_kworker)); + return; + } +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ + ixgbe_ptp_reset_e600(adapter); +#ifdef HAVE_PTP_CANCEL_WORKER_SYNC + ptp_schedule_worker(adapter->ptp_clock, 0); +#else /* HAVE_PTP_CANCEL_WORKER_SYNC */ + kthread_mod_delayed_work(adapter->ptp.ptp_kworker, + &adapter->ptp.ptp_aux_work, 0); +#endif /* !HAVE_PTP_CANCEL_WORKER_SYNC */ + + set_bit(__IXGBE_PTP_RUNNING, adapter->state); +} + +/** + * ixgbe_ptp_release_e600 - release PTP resources + * @adapter: pointer to adapter struct + * + * Completely destroy the PTP device, should only be called when the device is + * being fully closed. + */ +void ixgbe_ptp_release_e600(struct ixgbe_adapter *adapter) +{ + struct ptp_perout_request rq = {}; + + if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, adapter->state)) + return; + + /* Disable SDP. */ + ixgbe_ptp_setup_sdp_e600(adapter, &rq, false); + + /* Ensure that we cancel any pending PTP Tx work item in progress. */ + cancel_work_sync(&adapter->ptp_tx_work); +#ifdef HAVE_PTP_CANCEL_WORKER_SYNC + ptp_cancel_worker_sync(adapter->ptp_clock); +#else /* !HAVE_PTP_CANCEL_WORKER_SYNC */ + kthread_cancel_delayed_work_sync(&adapter->ptp.ptp_aux_work); +#endif /* HAVE_PTP_CANCEL_WORKER_SYNC */ + + ixgbe_ptp_clear_tx_timestamp_e600(adapter); + + if (adapter->ptp_clock) { + ptp_clock_unregister(adapter->ptp_clock); + adapter->ptp_clock = NULL; + e_dev_info("Removed PHC device on %s\n", adapter->netdev->name); + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.h new file mode 100644 index 0000000000..3762fda5fe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_ptp_e600.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_PTP_E600_H_ +#define _IXGBE_PTP_E600_H_ + +#include + +unsigned int ixgbe_ptp_rx_complete_skb_e600(struct ixgbe_q_vector *q_vector, + int *budget); +int ixgbe_ptp_set_timestamp_mode_e600(struct ixgbe_adapter *adapter, + struct hwtstamp_config *config); +void ixgbe_ptp_cfg_phy_vlan_e600(struct ixgbe_adapter *adapter, bool enabled); +bool ixgbe_ptp_is_tx_ptp(struct ixgbe_adapter *adapter, struct sk_buff *skb); +void ixgbe_ptp_link_up_e600(struct ixgbe_adapter *adapter); +void ixgbe_ptp_reset_e600(struct ixgbe_adapter *adapter); +void ixgbe_ptp_init_e600(struct ixgbe_adapter *adapter); +void ixgbe_ptp_release_e600(struct ixgbe_adapter *adapter); + +#endif /* _IXGBE_PTP_E600_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.c new file mode 100644 index 0000000000..342e8db9a8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.c @@ -0,0 +1,2238 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ixgbe_type.h" +#include "ixgbe_sriov.h" + +static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf); + +#ifdef CONFIG_PCI_IOV +static inline void ixgbe_alloc_vf_macvlans(struct ixgbe_adapter *adapter, + unsigned int num_vfs) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct vf_macvlans *mv_list; + int num_vf_macvlans, i; + + num_vf_macvlans = hw->mac.num_rar_entries - + (IXGBE_MAX_PF_MACVLANS + 1 + num_vfs); + if (!num_vf_macvlans) + return; + + mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans), + GFP_KERNEL); + if (mv_list) { + /* Initialize list of VF macvlans */ + INIT_LIST_HEAD(&adapter->vf_mvs.l); + for (i = 0; i < num_vf_macvlans; i++) { + mv_list[i].vf = -1; + mv_list[i].free = true; + list_add(&mv_list[i].l, &adapter->vf_mvs.l); + } + adapter->mv_list = mv_list; + } +} + +static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter, + unsigned int num_vfs) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + +#ifdef HAVE_XDP_SUPPORT + if (adapter->xdp_prog) { + e_warn(probe, "SRIOV is not supported with XDP\n"); + return -EINVAL; + } +#endif /* HAVE_XDP_SUPPORT */ + + adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED; + + /* Enable VMDq flag so device will be set in VM mode */ + adapter->flags |= IXGBE_FLAG_VMDQ_ENABLED; + if (!adapter->ring_feature[RING_F_VMDQ].limit) + adapter->ring_feature[RING_F_VMDQ].limit = 1; + + /* Allocate memory for per VF control structures */ + adapter->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage), + GFP_KERNEL); + if (!adapter->vfinfo) + return -ENOMEM; + + /* Initialize default switching mode VEB */ + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); + + /* set adapter->num_vfs only after allocating vfinfo to avoid + * NULL pointer issues when accessing adapter->vfinfo + */ + adapter->num_vfs = num_vfs; + + ixgbe_alloc_vf_macvlans(adapter, num_vfs); + + adapter->ring_feature[RING_F_VMDQ].offset = num_vfs; + + /* enable L2 switch and replication */ + adapter->flags |= IXGBE_FLAG_SRIOV_L2SWITCH_ENABLE | + IXGBE_FLAG_SRIOV_REPLICATION_ENABLE; + + /* limit traffic classes based on VFs enabled */ + if ((adapter->hw.mac.type == ixgbe_mac_82599EB) && + (adapter->num_vfs < 16)) { + adapter->dcb_cfg.num_tcs.pg_tcs = + IXGBE_DCB_MAX_TRAFFIC_CLASS; + adapter->dcb_cfg.num_tcs.pfc_tcs = + IXGBE_DCB_MAX_TRAFFIC_CLASS; + } else if (adapter->num_vfs < 32) { + adapter->dcb_cfg.num_tcs.pg_tcs = 4; + adapter->dcb_cfg.num_tcs.pfc_tcs = 4; + } else { + adapter->dcb_cfg.num_tcs.pg_tcs = 1; + adapter->dcb_cfg.num_tcs.pfc_tcs = 1; + } + adapter->dcb_cfg.vt_mode = true; + +#ifdef IXGBE_DISABLE_VF_MQ + /* We do not support RSS w/ SR-IOV */ + adapter->ring_feature[RING_F_RSS].limit = 1; +#endif + + /* Disable RSC when in SR-IOV mode */ + adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE | + IXGBE_FLAG2_RSC_ENABLED); + + + for (i = 0; i < adapter->num_vfs; i++) { + /* enable spoof checking for all VFs */ + adapter->vfinfo[i].spoofchk_enabled = true; + adapter->vfinfo[i].link_enable = true; + +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN + /* We support VF RSS querying only for 82599 and x540 + * devices at the moment. These devices share RSS + * indirection table and RSS hash key with PF therefore + * we want to disable the querying by default. + */ + adapter->vfinfo[i].rss_query_enabled = 0; + +#endif + /* Untrust all VFs */ + adapter->vfinfo[i].trusted = false; + + /* set the default xcast mode */ + adapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE; + } + + e_dev_info("SR-IOV enabled with %d VFs\n", num_vfs); + if (hw->mac.type < ixgbe_mac_X550) + e_dev_info("configure port vlans to keep your VFs secure\n"); + + return 0; +} + +/** + * ixgbe_get_vfs - Find and take references to all vf devices + * @adapter: Pointer to adapter struct + */ +static void ixgbe_get_vfs(struct ixgbe_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + u16 vendor = pdev->vendor; + struct pci_dev *vfdev; + int vf = 0; + u16 vf_id; + int pos; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) + return; + pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id); + + vfdev = pci_get_device(vendor, vf_id, NULL); + for (; vfdev; vfdev = pci_get_device(vendor, vf_id, vfdev)) { + if (!vfdev->is_virtfn) + continue; + if (vfdev->physfn != pdev) + continue; + if (vf >= adapter->num_vfs) + continue; + pci_dev_get(vfdev); + adapter->vfinfo[vf].vfdev = vfdev; + ++vf; + } +} + +/* Note this function is called when the user wants to enable SR-IOV + * VFs using the now deprecated module parameter + */ +void ixgbe_enable_sriov(struct ixgbe_adapter *adapter) +{ + int pre_existing_vfs = 0; + unsigned int num_vfs; + + pre_existing_vfs = pci_num_vf(adapter->pdev); + if (!pre_existing_vfs && !adapter->max_vfs) + return; + + /* If there are pre-existing VFs then we have to force + * use of that many - over ride any module parameter value. + * This may result from the user unloading the PF driver + * while VFs were assigned to guest VMs or because the VFs + * have been created via the new PCI SR-IOV sysfs interface. + */ + if (pre_existing_vfs) { + num_vfs = pre_existing_vfs; + dev_warn(&adapter->pdev->dev, + "Virtual Functions already enabled for this device - Please reload all VF drivers to avoid spoofed packet errors\n"); + } else { + int err; + /* + * The 82599 supports up to 64 VFs per physical function + * but this implementation limits allocation to 63 so that + * basic networking resources are still available to the + * physical function. If the user requests greater thn + * 63 VFs then it is an error - reset to default of zero. + */ + num_vfs = min_t(unsigned int, adapter->max_vfs, + IXGBE_MAX_VFS_DRV_LIMIT); + + err = pci_enable_sriov(adapter->pdev, num_vfs); + if (err) { + e_err(probe, "Failed to enable PCI sriov: %d\n", err); + return; + } + } + + if (!__ixgbe_enable_sriov(adapter, num_vfs)) { + ixgbe_get_vfs(adapter); + return; + } + + /* If we have gotten to this point then there is no memory available + * to manage the VF devices - print message and bail. + */ + e_err(probe, "Unable to allocate memory for VF Data Storage - SRIOV disabled\n"); + ixgbe_disable_sriov(adapter); +} + +#endif /* CONFIG_PCI_IOV */ +int ixgbe_disable_sriov(struct ixgbe_adapter *adapter) +{ + unsigned int num_vfs = adapter->num_vfs, vf; + struct ixgbe_hw *hw = &adapter->hw; + u32 gpie; + u32 vmdctl; + + /* set num VFs to 0 to prevent access to vfinfo */ + adapter->num_vfs = 0; + + /* put the reference to all of the vf devices */ + for (vf = 0; vf < num_vfs; ++vf) { + struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev; + + if (!vfdev) + continue; + adapter->vfinfo[vf].vfdev = NULL; + pci_dev_put(vfdev); + } + + /* free VF control structures */ + kfree(adapter->vfinfo); + adapter->vfinfo = NULL; + + /* free macvlan list */ + kfree(adapter->mv_list); + adapter->mv_list = NULL; + + /* if SR-IOV is already disabled then there is nothing to do */ + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return 0; + + /* Turn off malicious driver detection */ + if ((hw->mac.ops.disable_mdd) && + (!(adapter->flags & IXGBE_FLAG_MDD_ENABLED))) + hw->mac.ops.disable_mdd(hw); + +#ifdef CONFIG_PCI_IOV + /* + * If our VFs are assigned we cannot shut down SR-IOV + * without causing issues, so just leave the hardware + * available but disabled + */ + if (pci_vfs_assigned(adapter->pdev)) { + e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n"); + return -EPERM; + } + /* disable iov and allow time for transactions to clear */ + pci_disable_sriov(adapter->pdev); +#endif + /* turn off device IOV mode */ + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, 0); + gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + gpie &= ~IXGBE_GPIE_VTMODE_MASK; + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + + /* set default pool back to 0 */ + vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); + vmdctl &= ~IXGBE_VT_CTL_POOL_MASK; + IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl); + IXGBE_WRITE_FLUSH(hw); + + /* Disable VMDq flag so device will be set in VM mode */ + if (adapter->ring_feature[RING_F_VMDQ].limit == 1) + adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED; + + adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; + adapter->ring_feature[RING_F_VMDQ].offset = 0; + + /* take a breather then clean up driver data */ + msleep(100); + return 0; +} + +static int ixgbe_pci_sriov_enable(struct pci_dev __maybe_unused *dev, int __maybe_unused num_vfs) +{ +#ifdef CONFIG_PCI_IOV + struct ixgbe_adapter *adapter = pci_get_drvdata(dev); + int pre_existing_vfs = pci_num_vf(dev); + int err = 0, i; + u8 num_tc; + + if (!(adapter->flags & IXGBE_FLAG_SRIOV_CAPABLE)) { + e_dev_warn("SRIOV not supported on this device\n"); + return -EOPNOTSUPP; + } + + if (adapter->num_vfs == num_vfs) + return -EINVAL; + + if (pre_existing_vfs && pre_existing_vfs != num_vfs) + err = ixgbe_disable_sriov(adapter); + else if (pre_existing_vfs && pre_existing_vfs == num_vfs) + goto out; + + if (err) + goto err_out; + + /* While the SR-IOV capability structure reports total VFs to be + * 64 we limit the actual number that can be allocated as below + * so that some transmit/receive resources can be reserved to the + * PF. The PCI bus driver already checks for other values out of + * range. + * Num_TCs MAX_VFs + * 1 63 + * <=4 31 + * >4 15 + */ + num_tc = netdev_get_num_tc(adapter->netdev); + if (num_tc > 4) { + if (num_vfs > IXGBE_MAX_VFS_8TC) { + e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_8TC); + err = -EPERM; + goto err_out; + } + } else if ((num_tc > 1) && (num_tc <= 4)) { + if (num_vfs > IXGBE_MAX_VFS_4TC) { + e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_4TC); + err = -EPERM; + goto err_out; + } + } else { + if (num_vfs > IXGBE_MAX_VFS_1TC) { + e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_1TC); + err = -EPERM; + goto err_out; + } + } + + err = __ixgbe_enable_sriov(adapter, num_vfs); + if (err) + goto err_out; + + for (i = 0; i < adapter->num_vfs; i++) + ixgbe_vf_configuration(dev, (i | 0x10000000)); + + /* reset before enabling SRIOV to avoid mailbox issues */ + ixgbe_sriov_reinit(adapter); + + err = pci_enable_sriov(dev, num_vfs); + if (err) { + e_dev_warn("Failed to enable PCI sriov: %d\n", err); + goto err_out; + } + ixgbe_get_vfs(adapter); + +out: + return num_vfs; + +err_out: + return err; +#endif + return 0; +} + +static int ixgbe_pci_sriov_disable(struct pci_dev *dev) +{ + struct ixgbe_adapter *adapter = pci_get_drvdata(dev); + int err; +#ifdef CONFIG_PCI_IOV + u32 current_flags = adapter->flags; +#endif + + if (!adapter->num_vfs && !pci_num_vf(dev)) + return -EINVAL; + + err = ixgbe_disable_sriov(adapter); + + /* Only reinit if no error and state changed */ +#ifdef CONFIG_PCI_IOV + if (!err && current_flags != adapter->flags) + ixgbe_sriov_reinit(adapter); +#endif + + return err; +} + +/** + * ixgbe_pci_sriov_configure - Configure SR-IOV for the PCI device + * @dev: PCI device structure + * @num_vfs: Number of virtual functions (VFs) to configure + * + * This function configures Single Root I/O Virtualization (SR-IOV) for the + * specified PCI device. If `num_vfs` is zero, it disables SR-IOV. Otherwise, + * it enables SR-IOV with the specified number of VFs. + * + * Return: The number of VFs enabled on success, or a negative error code on failure. + */ +int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs) +{ + if (num_vfs == 0) + return ixgbe_pci_sriov_disable(dev); + else + return ixgbe_pci_sriov_enable(dev, num_vfs); +} + +static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + int entries = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) + >> IXGBE_VT_MSGINFO_SHIFT; + u16 *hash_list = (u16 *)&msgbuf[1]; + struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; + struct ixgbe_hw *hw = &adapter->hw; + int i; + u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); + + /* only so many hash values supported */ + entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES); + + /* salt away the number of multi cast addresses assigned + * to this VF for later use to restore when the PF multi cast + * list changes + */ + vfinfo->num_vf_mc_hashes = entries; + + /* VFs are limited to using the MTA hash table for their multicast + * addresses */ + for (i = 0; i < entries; i++) + vfinfo->vf_mc_hashes[i] = hash_list[i]; + + vmolr |= IXGBE_VMOLR_ROMPE; + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); + + /* Sync up the PF and VF in the same MTA table */ + ixgbe_write_mc_addr_list(adapter->netdev); + + return 0; +} + +#ifdef CONFIG_PCI_IOV +void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct vf_data_storage *vfinfo; + int i, j; + u32 vector_bit; + u32 vector_reg; + + /* Clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); + + for (i = 0; i < adapter->num_vfs; i++) { + u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i)); + vfinfo = &adapter->vfinfo[i]; + for (j = 0; j < vfinfo->num_vf_mc_hashes; j++) { + hw->addr_ctrl.mta_in_use++; + vector_reg = (vfinfo->vf_mc_hashes[j] >> 5) & 0x7F; + vector_bit = vfinfo->vf_mc_hashes[j] & 0x1F; + hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); + } + if (vfinfo->num_vf_mc_hashes) + vmolr |= IXGBE_VMOLR_ROMPE; + else + vmolr &= ~IXGBE_VMOLR_ROMPE; + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(i), vmolr); + } + + /* Restore any VF macvlans */ + ixgbe_full_sync_mac_table(adapter); +} +#endif /* CONFIG_PCI_IOV */ + +int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + +#ifndef HAVE_VLAN_RX_REGISTER + /* If VLAN overlaps with one the PF is currently monitoring make + * sure that we are able to allocate a VLVF entry. This may be + * redundant but it guarantees PF will maintain visibility to + * the VLAN. + */ + if (add && test_bit(vid, adapter->active_vlans)) { + err = hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), true, false); + if (err) + return err; + } +#endif + + err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false); +#ifndef HAVE_VLAN_RX_REGISTER + + if (add && !err) + return err; + + /* If we failed to add the VF VLAN or we are removing the VF VLAN + * we may need to drop the PF pool bit in order to allow us to free + * up the VLVF resources. + */ + if (test_bit(vid, adapter->active_vlans) || + (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)) + ixgbe_update_pf_promisc_vlvf(adapter, vid); +#endif + + return err; +} +static int ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 max_frame, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 max_frs; + + /* + * For 82599EB we have to keep all PFs and VFs operating with + * the same max_frame value in order to avoid sending an oversize + * frame to a VF. In order to guarantee this is handled correctly + * for all cases we have several special exceptions to take into + * account before we can enable the VF for receive + */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + + struct net_device *dev = adapter->netdev; + int pf_max_frame = dev->mtu + ETH_HLEN; + u32 reg_offset, vf_shift, vfre; + s32 err = 0; + +#if IS_ENABLED(CONFIG_FCOE) +#ifdef HAVE_NETDEV_FCOE_MTU + if (dev->fcoe_mtu) +#else + if (dev->features & NETIF_F_FCOE_MTU) +#endif + pf_max_frame = max_t(int, pf_max_frame, + IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif /* CONFIG_FCOE */ + + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + /* Version 1.1 supports jumbo frames on VFs if PF has + * jumbo frames enabled which means legacy VFs are + * disabled + */ + if (pf_max_frame > ETH_FRAME_LEN) + break; + fallthrough; + default: + /* If the PF or VF are running w/ jumbo frames enabled + * we need to shut down the VF Rx path as we cannot + * support jumbo frames on legacy VFs + */ + if ((pf_max_frame > ETH_FRAME_LEN) || + (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN))) + err = -EINVAL; + break; + } + + /* determine VF receive enable location */ + vf_shift = vf % 32; + reg_offset = vf / 32; + + /* enable or disable receive depending on error */ + vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); + if (err) + vfre &= ~(1 << vf_shift); + else + vfre |= 1 << vf_shift; + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), vfre); + + if (err) { + e_err(drv, "VF max_frame %d out of range\n", max_frame); + return err; + } + } + + /* pull current max frame size from hardware */ + max_frs = IXGBE_READ_REG(hw, IXGBE_MAXFRS); + max_frs &= IXGBE_MHADD_MFS_MASK; + max_frs >>= IXGBE_MHADD_MFS_SHIFT; + + if (max_frs < max_frame) { + max_frs = max_frame << IXGBE_MHADD_MFS_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_MAXFRS, max_frs); + } + + e_info(hw, "VF requests change max MTU to %d\n", max_frame); + + return 0; +} + +void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) +{ + u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); + vmolr |= IXGBE_VMOLR_BAM; + if (aupe) + vmolr |= IXGBE_VMOLR_AUPE; + else + vmolr &= ~IXGBE_VMOLR_AUPE; + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); +} + +static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, + u16 vid, u16 qos, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vmvir = vid | (qos << VLAN_PRIO_SHIFT) | IXGBE_VMVIR_VLANA_DEFAULT; + + IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), vmvir); +} + +static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + + IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); +} + +static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlvfb_mask, pool_mask, i; + + /* create mask for VF and other pools */ + pool_mask = (u32)~BIT(VMDQ_P(0) % 32); + vlvfb_mask = BIT(vf % 32); + + /* post increment loop, covers VLVF_ENTRIES - 1 to 0 */ + for (i = IXGBE_VLVF_ENTRIES; i--;) { + u32 bits[2], vlvfb, vid, vfta, vlvf; + u32 word = i * 2 + vf / 32; + u32 mask; + + vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word)); + + /* if our bit isn't set we can skip it */ + if (!(vlvfb & vlvfb_mask)) + continue; + + /* clear our bit from vlvfb */ + vlvfb ^= vlvfb_mask; + + /* create 64b mask to check to see if we should clear VLVF */ + bits[word % 2] = vlvfb; + bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1)); + + /* if other pools are present, just remove ourselves */ + if (bits[(VMDQ_P(0) / 32) ^ 1] || + (bits[VMDQ_P(0) / 32] & pool_mask)) + goto update_vlvfb; + + /* if PF is present, leave VFTA */ + if (bits[0] || bits[1]) + goto update_vlvf; + + /* if we cannot determine VLAN just remove ourselves */ + vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i)); + if (!vlvf) + goto update_vlvfb; + + vid = vlvf & VLAN_VID_MASK; + mask = BIT(vid % 32); + + /* clear bit from VFTA */ + vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(vid / 32)); + if (vfta & mask) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(vid / 32), vfta ^ mask); +update_vlvf: + /* clear POOL selection enable */ + IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0); + + if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)) + vlvfb = 0; +update_vlvfb: + /* clear pool bits */ + IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb); + } +} + +static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter, + int vf, int index, unsigned char *mac_addr) +{ + struct vf_macvlans *entry; + struct list_head *pos; + int retval = 0; + + if (index <= 1) { + list_for_each(pos, &adapter->vf_mvs.l) { + entry = list_entry(pos, struct vf_macvlans, l); + if (entry->vf == vf) { + entry->vf = -1; + entry->free = true; + entry->is_macvlan = false; + ixgbe_del_mac_filter(adapter, + entry->vf_macvlan, vf); + } + } + } + + /* + * If index was zero then we were asked to clear the uc list + * for the VF. We're done. + */ + if (!index) + return 0; + + entry = NULL; + + list_for_each(pos, &adapter->vf_mvs.l) { + entry = list_entry(pos, struct vf_macvlans, l); + if (entry->free) + break; + } + + /* + * If we traversed the entire list and didn't find a free entry + * then we're out of space on the RAR table. Also entry may + * be NULL because the original memory allocation for the list + * failed, which is not fatal but does mean we can't support + * VF requests for MACVLAN because we couldn't allocate + * memory for the list management required. + */ + if (!entry || !entry->free) + return -ENOSPC; + + retval = ixgbe_add_mac_filter(adapter, mac_addr, vf); + if (retval < 0) + return retval; + + entry->free = false; + entry->is_macvlan = true; + entry->vf = vf; + memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN); + + return 0; +} + +static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; + u8 num_tcs = netdev_get_num_tc(adapter->netdev); + u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + struct ixgbe_hw *hw = &adapter->hw; + u32 reg_val; + u32 queue; + u32 word; + + /* remove VLAN filters belonging to this VF */ + ixgbe_clear_vf_vlans(adapter, vf); + + /* add back PF assigned VLAN or VLAN 0 */ + ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf); + + /* reset offloads to defaults */ + ixgbe_set_vmolr(hw, vf, !vfinfo->pf_vlan); + + /* set outgoing tags for VFs */ + if (!vfinfo->pf_vlan && !vfinfo->pf_qos && !num_tcs) { + ixgbe_clear_vmvir(adapter, vf); + } else { + if (vfinfo->pf_qos || !num_tcs) + ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, + vfinfo->pf_qos, vf); + else + ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, + adapter->default_up, vf); + } + + /* reset multicast table array for vf */ + adapter->vfinfo[vf].num_vf_mc_hashes = 0; + + /* Flush and reset the mta with the new values */ + ixgbe_set_rx_mode(adapter->netdev); + + ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf); + ixgbe_set_vf_macvlan(adapter, vf, 0, NULL); + + /* reset VF api back to unknown */ + adapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10; + + /* + * Toggling VF's TX queues and clearing VF Mailbox Memory after VFLR + * should only affect X550 and above + */ + if (hw->mac.type >= ixgbe_mac_X550) { + /* Restart each queue for given VF */ + for (queue = 0; queue < q_per_pool; queue++) { + unsigned int reg_idx = (vf * q_per_pool) + queue; + + reg_val = IXGBE_READ_REG(hw, IXGBE_PVFTXDCTL(reg_idx)); + + /* Re-enabling only configured queues */ + if (reg_val) { + reg_val |= IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(reg_idx), + reg_val); + reg_val &= ~IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(reg_idx), + reg_val); + } + } + + /* Clear VF's mailbox memory */ + for (word = 0; word < IXGBE_VFMAILBOX_SIZE; word++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf), word, 0); + + IXGBE_WRITE_FLUSH(hw); + } +} + +int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, + int vf, unsigned char *mac_addr) +{ + s32 retval = 0; + + ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf); + retval = ixgbe_add_mac_filter(adapter, mac_addr, vf); + if (retval >= 0) + memcpy(adapter->vfinfo[vf].vf_mac_addresses, + mac_addr, ETH_ALEN); + else + memset(adapter->vfinfo[vf].vf_mac_addresses, 0, ETH_ALEN); + + return retval; +} + +#ifdef CONFIG_PCI_IOV +int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) +{ + unsigned char vf_mac_addr[6]; + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + unsigned int vfn = (event_mask & 0x3f); + bool enable = ((event_mask & 0x10000000U) != 0); + + if (enable) { + memset(vf_mac_addr, 0, ETH_ALEN); + memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6); + } + + return 0; +} +#endif /* CONFIG_PCI_IOV */ + +static inline void ixgbe_write_qde(struct ixgbe_adapter *adapter, u32 vf, + u32 qde) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + u32 reg; + int i; + + for (i = vf * q_per_pool; i < ((vf + 1) * q_per_pool); i++) { + /* flush previous write */ + IXGBE_WRITE_FLUSH(hw); + + /* drop enable should always be set in SRIOV mode*/ + reg = IXGBE_QDE_WRITE | qde; + reg |= i << IXGBE_QDE_IDX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_QDE, reg); + } + +} + +static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; + u32 reg, reg_offset, vf_shift; + u32 msgbuf[4] = {0, 0, 0, 0}; + u8 *addr = (u8 *)(&msgbuf[1]); + u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + int i; + + e_info(probe, "VF Reset msg received from vf %d\n", vf); + + /* reset the filters for the device */ + ixgbe_vf_reset_event(adapter, vf); + + /* set vf mac address */ + if (!is_zero_ether_addr(vf_mac)) + ixgbe_set_vf_mac(adapter, vf, vf_mac); + + vf_shift = vf % 32; + reg_offset = vf / 32; + + /* force drop enable for all VF Rx queues */ + reg = IXGBE_QDE_ENABLE; + if (adapter->vfinfo[vf].pf_vlan) + reg |= IXGBE_QDE_HIDE_VLAN; + + ixgbe_write_qde(adapter, vf, reg); + + /* set transmit and receive for vf */ + ixgbe_set_vf_rx_tx(adapter, vf); + + /* enable VF mailbox for further messages */ + adapter->vfinfo[vf].clear_to_send = true; + + reg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset)); + reg |= (1 << vf_shift); + IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg); + + /* + * Reset the VFs TDWBAL and TDWBAH registers + * which are not cleared by an FLR + */ + for (i = 0; i < q_per_pool; i++) { + IXGBE_WRITE_REG(hw, IXGBE_PVFTDWBAHn(q_per_pool, vf, i), 0); + IXGBE_WRITE_REG(hw, IXGBE_PVFTDWBALn(q_per_pool, vf, i), 0); + } + + /* reply to reset with ack and vf mac address */ + msgbuf[0] = IXGBE_VF_RESET; + if (!is_zero_ether_addr(vf_mac) && adapter->vfinfo[vf].pf_set_mac) { + msgbuf[0] |= IXGBE_VT_MSGTYPE_SUCCESS; + memcpy(addr, vf_mac, ETH_ALEN); + } else { + msgbuf[0] |= IXGBE_VT_MSGTYPE_FAILURE; + } + + /* + * Piggyback the multicast filter type so VF can compute the + * correct vectors + */ + msgbuf[3] = hw->mac.mc_filter_type; + ixgbe_write_mbx(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN, vf); + + return 0; +} + +static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u8 *new_mac = ((u8 *)(&msgbuf[1])); + + if (!is_valid_ether_addr(new_mac)) { + e_warn(drv, "VF %d attempted to set invalid mac\n", vf); + return -1; + } + + if (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted && + memcmp(adapter->vfinfo[vf].vf_mac_addresses, new_mac, + ETH_ALEN)) { + u8 *pm = adapter->vfinfo[vf].vf_mac_addresses; + e_warn(drv, + "VF %d attempted to set a new MAC address but it already has an administratively set MAC address %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", + vf, pm[0], pm[1], pm[2], pm[3], pm[4], pm[5]); + e_warn(drv, "Check the VF driver and if it is not using the correct MAC address you may need to reload the VF driver\n"); + return -1; + } + return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0; +} + +static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u32 add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; + u32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); + u8 tcs = netdev_get_num_tc(adapter->netdev); + int err = 0; + + if (adapter->vfinfo[vf].pf_vlan || tcs) { + e_warn(drv, + "VF %d attempted to override administratively set VLAN configuration\n" + "Reload the VF driver to resume operations\n", + vf); + return -1; + } + + /* VLAN 0 is a special case, don't allow it to be removed */ + if (!vid && !add) + return 0; + + err = ixgbe_set_vf_vlan(adapter, add, vid, vf); + if (err) + goto out; + +#ifdef HAVE_VLAN_RX_REGISTER + /* in case of promiscuous mode any VLAN filter set for a VF must + * also have the PF pool added to it. + */ + if (add && adapter->netdev->flags & IFF_PROMISC) { + err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0)); + if (err) + goto out; + } + +#ifdef CONFIG_PCI_IOV + /* Go through all the checks to see if the VLAN filter should + * be wiped completely. + */ + if (!add && adapter->netdev->flags & IFF_PROMISC) { + struct ixgbe_hw *hw = &adapter->hw; + u32 bits, vlvf; + s32 reg_ndx; + + reg_ndx = ixgbe_find_vlvf_entry(hw, vid); + if (reg_ndx < 0) + goto out; + vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx)); + /* See if any other pools are set for this VLAN filter + * entry other than the PF. + */ + if (VMDQ_P(0) < 32) { + bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2)); + bits &= ~(1 << VMDQ_P(0)); + bits |= IXGBE_READ_REG(hw, + IXGBE_VLVFB(reg_ndx * 2) + 1); + } else { + bits = IXGBE_READ_REG(hw, + IXGBE_VLVFB(reg_ndx * 2) + 1); + bits &= ~(1 << (VMDQ_P(0) - 32)); + bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2)); + } + + /* If the filter was removed then ensure PF pool bit + * is cleared if the PF only added itself to the pool + * because the PF is in promiscuous mode. + */ + if ((vlvf & VLAN_VID_MASK) == vid && !bits) + err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0)); + } + +#endif /* CONFIG_PCI_IOV */ +#endif /* HAVE_VLAN_RX_REGISTER */ +out: + return err; +} + +static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u8 *new_mac = ((u8 *)(&msgbuf[1])); + int index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> + IXGBE_VT_MSGINFO_SHIFT; + int err; + + if (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted && + index > 0) { + e_warn(drv, + "VF %d requested MACVLAN filter but is administratively denied\n", + vf); + return -1; + } + + /* An non-zero index indicates the VF is setting a filter */ + if (index) { + if (!is_valid_ether_addr(new_mac)) { + e_warn(drv, "VF %d attempted to set invalid mac\n", vf); + return -1; + } + + /* + * If the VF is allowed to set MAC filters then turn off + * anti-spoofing to avoid false positives. + */ + if (adapter->vfinfo[vf].spoofchk_enabled) { + struct ixgbe_hw *hw = &adapter->hw; + + hw->mac.ops.set_mac_anti_spoofing(hw, false, vf); + hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); + } + } + + err = ixgbe_set_vf_macvlan(adapter, vf, index, new_mac); + if (err == -ENOSPC) + e_warn(drv, + "VF %d has requested a MACVLAN filter but there is no space for it\n", + vf); + + return err < 0; +} + +static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + int api = msgbuf[1]; + + switch (api) { + case ixgbe_mbox_api_10: + case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + adapter->vfinfo[vf].vf_api = api; + return 0; + default: + break; + } + + e_info(drv, "VF %d requested invalid api version %u\n", vf, api); + + return -1; +} + +static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + struct net_device *dev = adapter->netdev; + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + unsigned int default_tc = 0; + u8 num_tcs = netdev_get_num_tc(dev); + + /* verify the PF is supporting the correct APIs */ + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_20: + case ixgbe_mbox_api_11: + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + break; + default: + return -1; + } + + /* only allow 1 Tx queue for bandwidth limiting */ + msgbuf[IXGBE_VF_TX_QUEUES] = __ALIGN_MASK(1, ~vmdq->mask); + msgbuf[IXGBE_VF_RX_QUEUES] = __ALIGN_MASK(1, ~vmdq->mask); + + /* if TCs > 1 determine which TC belongs to default user priority */ + if (num_tcs > 1) + default_tc = netdev_get_prio_tc_map(dev, adapter->default_up); + + /* notify VF of need for VLAN tag stripping, and correct queue */ + if (num_tcs) + msgbuf[IXGBE_VF_TRANS_VLAN] = num_tcs; + else if (adapter->vfinfo[vf].pf_vlan || adapter->vfinfo[vf].pf_qos) + msgbuf[IXGBE_VF_TRANS_VLAN] = 1; + else + msgbuf[IXGBE_VF_TRANS_VLAN] = 0; + + /* notify VF of default queue */ + msgbuf[IXGBE_VF_DEF_QUEUE] = default_tc; + + return 0; +} + +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN +static int ixgbe_get_vf_reta(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) +{ + u32 i, j; + u32 *out_buf = &msgbuf[1]; + const u8 *reta = adapter->rss_indir_tbl; + u32 reta_size = ixgbe_rss_indir_tbl_entries(adapter); + + /* Check if operation is permitted */ + if (!adapter->vfinfo[vf].rss_query_enabled) + return -EPERM; + + /* verify the PF is supporting the correct API */ + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + break; + default: + return -EOPNOTSUPP; + } + + /* This mailbox command is supported (required) only for 82599 and x540 + * VFs which support up to 4 RSS queues. Therefore we will compress the + * RETA by saving only 2 bits from each entry. This way we will be able + * to transfer the whole RETA in a single mailbox operation. + */ + for (i = 0; i < reta_size / 16; i++) { + out_buf[i] = 0; + for (j = 0; j < 16; j++) + out_buf[i] |= (u32)(reta[16 * i + j] & 0x3) << (2 * j); + } + + return 0; +} + +static int ixgbe_get_vf_rss_key(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u32 *rss_key = &msgbuf[1]; + + /* Check if the operation is permitted */ + if (!adapter->vfinfo[vf].rss_query_enabled) + return -EPERM; + + /* verify the PF is supporting the correct API */ + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + break; + default: + return -EOPNOTSUPP; + } + + memcpy(rss_key, adapter->rss_key, IXGBE_RSS_KEY_SIZE); + + return 0; +} +#endif /* HAVE_NDO_SET_VF_RSS_QUERY_EN */ + +static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + int xcast_mode = msgbuf[1]; + u32 vmolr, fctrl, disable, enable; + + /* verify the PF is supporting the correct APIs */ + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_12: + /* promisc introduced in 1.3 version */ + if (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC) + return -EOPNOTSUPP; + /* Fall threw */ + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + break; + default: + return -EOPNOTSUPP; + } + + if (xcast_mode > IXGBEVF_XCAST_MODE_MULTI && + !adapter->vfinfo[vf].trusted) { + xcast_mode = IXGBEVF_XCAST_MODE_MULTI; + } + + if (adapter->vfinfo[vf].xcast_mode == xcast_mode) + goto out; + + switch (xcast_mode) { + case IXGBEVF_XCAST_MODE_NONE: + disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | + IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; + enable = 0; + break; + case IXGBEVF_XCAST_MODE_MULTI: + disable = IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; + enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE; + break; + case IXGBEVF_XCAST_MODE_ALLMULTI: + disable = IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; + enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE; + break; + case IXGBEVF_XCAST_MODE_PROMISC: + if (hw->mac.type <= ixgbe_mac_82599EB) + return -EOPNOTSUPP; + + fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + if (!(fctrl & IXGBE_FCTRL_UPE)) { + /* VF promisc requires PF in promisc */ + e_warn(drv, + "Enabling VF promisc requires PF in promisc\n"); + return -EPERM; + } + + disable = 0; + enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | + IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; + break; + default: + return -EOPNOTSUPP; + } + + vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); + vmolr &= ~disable; + vmolr |= enable; + IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); + + adapter->vfinfo[vf].xcast_mode = xcast_mode; + +out: + msgbuf[1] = xcast_mode; + + return 0; +} + +static int ixgbe_get_vf_link_state(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u32 *link_state = &msgbuf[1]; + + /* verify the PF is supporting the correct API */ + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + break; + default: + return -EOPNOTSUPP; + } + + *link_state = adapter->vfinfo[vf].link_enable; + + return 0; +} + +static int ixgbe_get_vf_link_status(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_16: + case ixgbe_mbox_api_17: + if (!ixgbe_is_mac_E6xx(hw->mac.type)) + return -EOPNOTSUPP; + break; + default: + return -EOPNOTSUPP; + } + + /* Simply provide stored values as watchdog / link status events take + * care of it's freshness. + */ + msgbuf[1] = adapter->link_speed; + msgbuf[2] = adapter->link_up; + + return 0; +} + +/** + * ixgbe_negotiate_vf_features - negotiate supported features with VF driver + * @adapter: pointer to adapter struct + * @msgbuf: pointer to message buffers + * @vf: VF identifier + * + * Return: 0 on success or -EOPNOTSUPP when operation is not supported. + */ +static int ixgbe_negotiate_vf_features(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u32 features = msgbuf[1]; + + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_17: + break; + default: + return -EOPNOTSUPP; + } + + features &= IXGBE_SUPPORTED_FEATURES; + msgbuf[1] = features; + + return 0; +} + +static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) +{ + u32 mbx_size = IXGBE_VFMAILBOX_SIZE; + u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; + struct ixgbe_hw *hw = &adapter->hw; + s32 retval; + + retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); + + if (retval) { + pr_err("Error receiving message from VF\n"); + return retval; + } + + /* this is a message we already processed, do nothing */ + if (msgbuf[0] & (IXGBE_VT_MSGTYPE_SUCCESS | IXGBE_VT_MSGTYPE_FAILURE)) + return retval; + + /* flush the ack before we write any messages back */ + IXGBE_WRITE_FLUSH(hw); + + if (msgbuf[0] == IXGBE_VF_RESET) + return ixgbe_vf_reset_msg(adapter, vf); + + /* + * until the vf completes a virtual function reset it should not be + * allowed to start any configuration. + */ + + if (!adapter->vfinfo[vf].clear_to_send) { + msgbuf[0] |= IXGBE_VT_MSGTYPE_FAILURE; + ixgbe_write_mbx(hw, msgbuf, 1, vf); + return retval; + } + + switch ((msgbuf[0] & 0xFFFF)) { + case IXGBE_VF_SET_MAC_ADDR: + retval = ixgbe_set_vf_mac_addr(adapter, msgbuf, vf); + break; + case IXGBE_VF_SET_MULTICAST: + retval = ixgbe_set_vf_multicasts(adapter, msgbuf, vf); + break; + case IXGBE_VF_SET_VLAN: + retval = ixgbe_set_vf_vlan_msg(adapter, msgbuf, vf); + break; + case IXGBE_VF_SET_LPE: + if (msgbuf[1] > IXGBE_MAX_JUMBO_FRAME_SIZE) { + e_err(drv, "VF max_frame %d out of range\n", msgbuf[1]); + return -EINVAL; + } + retval = ixgbe_set_vf_lpe(adapter, msgbuf[1], vf); + break; + case IXGBE_VF_SET_MACVLAN: + retval = ixgbe_set_vf_macvlan_msg(adapter, msgbuf, vf); + break; + case IXGBE_VF_API_NEGOTIATE: + retval = ixgbe_negotiate_vf_api(adapter, msgbuf, vf); + break; + case IXGBE_VF_GET_QUEUES: + retval = ixgbe_get_vf_queues(adapter, msgbuf, vf); + break; +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN + case IXGBE_VF_GET_RETA: + retval = ixgbe_get_vf_reta(adapter, msgbuf, vf); + break; + case IXGBE_VF_GET_RSS_KEY: + retval = ixgbe_get_vf_rss_key(adapter, msgbuf, vf); + break; +#endif /* HAVE_NDO_SET_VF_RSS_QUERY_EN */ + case IXGBE_VF_UPDATE_XCAST_MODE: + retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf); + break; + case IXGBE_VF_GET_LINK_STATE: + retval = ixgbe_get_vf_link_state(adapter, msgbuf, vf); + break; + case IXGBE_VF_GET_PF_LINK_STATE: + retval = ixgbe_get_vf_link_status(adapter, msgbuf, vf); + break; + case IXGBE_VF_FEATURES_NEGOTIATE: + retval = ixgbe_negotiate_vf_features(adapter, msgbuf, vf); + break; + default: + e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); + retval = IXGBE_ERR_MBX; + break; + } + + /* notify the VF of the results of what it sent us */ + if (retval) + msgbuf[0] |= IXGBE_VT_MSGTYPE_FAILURE; + else + msgbuf[0] |= IXGBE_VT_MSGTYPE_SUCCESS; + + msgbuf[0] |= IXGBE_VT_MSGTYPE_CTS; + + ixgbe_write_mbx(hw, msgbuf, mbx_size, vf); + + return retval; +} + +static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 msg = IXGBE_VT_MSGTYPE_FAILURE; + + /* if device isn't clear to send it shouldn't be reading either */ + if (!adapter->vfinfo[vf].clear_to_send) + ixgbe_write_mbx(hw, &msg, 1, vf); +} + +#define Q_BITMAP_DEPTH 2 +int ixgbe_check_mdd_event(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vf_bitmap[Q_BITMAP_DEPTH] = { 0 }; + int retval = false; + u32 j, i; + u32 ping; + + if (!hw->mac.ops.mdd_event) + return retval; + + /* Did we have a malicious event */ + hw->mac.ops.mdd_event(hw, vf_bitmap); + + /* Log any blocked queues and release lock */ + for (i = 0; i < Q_BITMAP_DEPTH; i++) { + for (j = 0; j < 32 && vf_bitmap[i]; j++) { + u32 vf; + + if (!(vf_bitmap[i] & (1 << j))) + continue; + + /* The VF that malicious event occurred on */ + vf = j + (i * 32); + + dev_warn(ixgbe_pf_to_dev(adapter), + "Malicious event on VF %d tx:%x rx:%x\n", vf, + IXGBE_READ_REG(hw, IXGBE_LVMMC_TX), + IXGBE_READ_REG(hw, IXGBE_LVMMC_RX)); + + /* restart the vf */ + if (hw->mac.ops.restore_mdd_vf) { + hw->mac.ops.restore_mdd_vf(hw, vf); + + /* get the VF to rebuild its queues */ + adapter->vfinfo[vf].clear_to_send = 0; + ping = IXGBE_PF_CONTROL_MSG | + IXGBE_VT_MSGTYPE_CTS; + ixgbe_write_mbx(hw, &ping, 1, vf); + } + + retval = true; + } + } + + return retval; +} + +void ixgbe_msg_task(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vf; + + if (!adapter->vfinfo) + return; + + if (adapter->flags & IXGBE_FLAG_MDD_ENABLED) + ixgbe_check_mdd_event(adapter); + + for (vf = 0; vf < adapter->num_vfs; vf++) { + /* process any reset requests */ + if (!ixgbe_check_for_rst(hw, vf)) + ixgbe_vf_reset_event(adapter, vf); + + /* process any messages pending */ + if (!ixgbe_check_for_msg(hw, vf)) + ixgbe_rcv_msg_from_vf(adapter, vf); + + /* process any acks */ + if (!ixgbe_check_for_ack(hw, vf)) + ixgbe_rcv_ack_from_vf(adapter, vf); + } +} + +#if defined(HAVE_NDO_SET_VF_TRUST) || defined(HAVE_NDO_SET_VF_LINK_STATE) +static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 ping; + + ping = IXGBE_PF_CONTROL_MSG; + if (adapter->vfinfo[vf].clear_to_send) + ping |= IXGBE_VT_MSGTYPE_CTS; + ixgbe_write_mbx(hw, &ping, 1, vf); +} +#endif + +void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 ping; + int i; + + for (i = 0 ; i < adapter->num_vfs; i++) { + ping = IXGBE_PF_CONTROL_MSG; + if (adapter->vfinfo[i].clear_to_send) + ping |= IXGBE_VT_MSGTYPE_CTS; + ixgbe_write_mbx(hw, &ping, 1, i); + } +} + +/** + * ixgbe_set_all_vfs - update vfs queues + * @adapter: Pointer to adapter struct + * + * Update setting transmit and receive queues for all vfs + **/ +void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0 ; i < adapter->num_vfs; i++) { + ixgbe_set_vf_link_state(adapter, i, + adapter->vfinfo[i].link_state); + } +} + +#ifdef HAVE_NDO_SET_VF_TRUST +/** + * ixgbe_ndo_set_vf_trust - Set trust status for a virtual function (VF) + * @netdev: Network device structure + * @vf: VF index + * @setting: Boolean value to set the VF as trusted (true) or not trusted (false) + * + * This function sets the trust status for a specified virtual function (VF) on + * the network device. If the trust status changes, the VF is reset to reconfigure + * its features. The function logs the new trust status of the VF. + * + * Return: 0 on success, or -EINVAL if the VF index is out of range. + */ +int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + /* nothing to do */ + if (adapter->vfinfo[vf].trusted == setting) + return 0; + + adapter->vfinfo[vf].trusted = setting; + + /* reset VF to reconfigure features */ + adapter->vfinfo[vf].clear_to_send = false; + ixgbe_ping_vf(adapter, vf); + + e_info(drv, "VF %u is %strusted\n", vf, setting ? "" : "not "); + + return 0; +} +#endif /* HAVE_NDO_SET_VF_TRUST */ + +#ifdef IFLA_VF_MAX +/** + * ixgbe_ndo_set_vf_mac - Set MAC address for a virtual function (VF) + * @netdev: Network device structure + * @vf: VF index + * @mac: Pointer to the MAC address to be set + * + * This function sets or removes the MAC address for a specified virtual + * function (VF) on the network device. It validates the MAC address and + * updates the VF configuration. If a valid MAC address is provided, it sets + * the MAC address and marks it as set by the PF. If a zero MAC address is + * provided, it removes the existing MAC address. The function logs relevant + * messages and warns if the PF device is down. + * + * Return: 0 on success, -EINVAL if the VF index is out of range or the MAC + * address is invalid, or a negative error code on failure. + */ +int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + s32 retval = 0; + + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + if (is_valid_ether_addr(mac)) { + dev_info(ixgbe_pf_to_dev(adapter), "setting MAC %pM on VF %d\n", + mac, vf); + dev_info(ixgbe_pf_to_dev(adapter), "Reload the VF driver to make this change effective.\n"); + + retval = ixgbe_set_vf_mac(adapter, vf, mac); + if (retval >= 0) { + adapter->vfinfo[vf].pf_set_mac = true; + + if (test_bit(__IXGBE_DOWN, adapter->state)) { + dev_warn(ixgbe_pf_to_dev(adapter), "The VF MAC address has been set, but the PF device is not up.\n"); + dev_warn(ixgbe_pf_to_dev(adapter), "Bring the PF device up before attempting to use the VF device.\n"); + } + } else { + dev_warn(ixgbe_pf_to_dev(adapter), "The VF MAC address was NOT set due to invalid or duplicate MAC address.\n"); + } + } else if (is_zero_ether_addr(mac)) { + unsigned char *vf_mac_addr = + adapter->vfinfo[vf].vf_mac_addresses; + + /* nothing to do */ + if (is_zero_ether_addr(vf_mac_addr)) + return 0; + + dev_info(ixgbe_pf_to_dev(adapter), "removing MAC on VF %d\n", + vf); + + retval = ixgbe_del_mac_filter(adapter, vf_mac_addr, vf); + if (retval >= 0) { + adapter->vfinfo[vf].pf_set_mac = false; + memcpy(vf_mac_addr, mac, ETH_ALEN); + } else { + dev_warn(ixgbe_pf_to_dev(adapter), "Could NOT remove the VF MAC address.\n"); + } + } else { + retval = -EINVAL; + } + return retval; +} + +static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, + int vf, u16 vlan, u8 qos) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + + err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); + if (err) + goto out; + + /* Revoke tagless access via VLAN 0 */ + ixgbe_set_vf_vlan(adapter, false, 0, vf); + + ixgbe_set_vmvir(adapter, vlan, qos, vf); + ixgbe_set_vmolr(hw, vf, false); + + /* enable hide vlan on X550 */ + if (hw->mac.type >= ixgbe_mac_X550) + ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE | + IXGBE_QDE_HIDE_VLAN); + adapter->vfinfo[vf].pf_vlan = vlan; + adapter->vfinfo[vf].pf_qos = qos; + dev_info(ixgbe_pf_to_dev(adapter), + "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); + if (test_bit(__IXGBE_DOWN, adapter->state)) { + dev_warn(ixgbe_pf_to_dev(adapter), "The VF VLAN has been set, but the PF device is not up.\n"); + dev_warn(ixgbe_pf_to_dev(adapter), "Bring the PF device up before attempting to use the VF device.\n"); + } + +out: + return err; +} + +static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + + err = ixgbe_set_vf_vlan(adapter, false, + adapter->vfinfo[vf].pf_vlan, vf); + /* Restore tagless access via VLAN 0 */ + ixgbe_set_vf_vlan(adapter, true, 0, vf); + ixgbe_clear_vmvir(adapter, vf); + ixgbe_set_vmolr(hw, vf, true); + + /* disable hide VLAN on X550 */ + if (hw->mac.type >= ixgbe_mac_X550) + ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE); + + adapter->vfinfo[vf].pf_vlan = 0; + adapter->vfinfo[vf].pf_qos = 0; + + return err; +} + +/** + * ixgbe_ndo_set_vf_vlan - Set VLAN configuration for a virtual function (VF) + * @netdev: Network device structure + * @vf: VF index + * @vlan: VLAN ID to be set + * @qos: Quality of Service (QoS) priority + * @vlan_proto: (Optional) VLAN protocol, typically ETH_P_8021Q + * + * This function sets the VLAN configuration for a specified virtual function + * (VF) on the network device. It validates the VLAN ID and QoS values, and + * ensures the VLAN protocol is supported. If a VLAN is already set, it is + * disabled before setting the new configuration. The function handles both + * enabling and disabling of port VLANs for the VF. + * + * Return: 0 on success, -EINVAL if the VF index, VLAN ID, or QoS is invalid, + * or -EPROTONOSUPPORT if the VLAN protocol is unsupported. + */ +#ifdef IFLA_VF_VLAN_INFO_MAX +int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, + u8 qos, __be16 vlan_proto) +#else /* IFLA_VF_VLAN_INFO_MAX */ +int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) +#endif /* IFLA_VF_VLAN_INFO_MAX */ +{ + int err = 0; + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + /* VLAN IDs accepted range 0-4094 */ + if (vf < 0 || vf >= adapter->num_vfs || + vlan > VLAN_VID_MASK - 1 || qos > 7) + return -EINVAL; + +#ifdef IFLA_VF_VLAN_INFO_MAX + if (vlan_proto != htons(ETH_P_8021Q)) + return -EPROTONOSUPPORT; +#endif + if (vlan || qos) { + /* + * Check if there is already a port VLAN set, if so + * we have to delete the old one first before we + * can set the new one. The usage model had + * previously assumed the user would delete the + * old port VLAN before setting a new one but this + * is not necessarily the case. + */ + if (adapter->vfinfo[vf].pf_vlan) + err = ixgbe_disable_port_vlan(adapter, vf); + if (err) + goto out; + err = ixgbe_enable_port_vlan(adapter, vf, vlan, qos); + + } else { + err = ixgbe_disable_port_vlan(adapter, vf); + } +out: + return err; +} + + +static int ixgbe_link_mbps(struct ixgbe_adapter *adapter) +{ + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + return 100; + case IXGBE_LINK_SPEED_1GB_FULL: + return 1000; + case IXGBE_LINK_SPEED_10GB_FULL: + return 10000; + default: + return 0; + } +} + +static void ixgbe_set_vf_rate_limit(struct ixgbe_adapter *adapter, int vf) +{ + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + struct ixgbe_hw *hw = &adapter->hw; + u32 bcnrc_val = 0; + u16 queue, queues_per_pool; + u16 tx_rate = adapter->vfinfo[vf].tx_rate; + + if (tx_rate) { + /* start with base link speed value */ + bcnrc_val = adapter->vf_rate_link_speed; + + /* Calculate the rate factor values to set */ + bcnrc_val <<= IXGBE_RTTBCNRC_RF_INT_SHIFT; + bcnrc_val /= tx_rate; + + /* clear everything but the rate factor */ + bcnrc_val &= IXGBE_RTTBCNRC_RF_INT_MASK | + IXGBE_RTTBCNRC_RF_DEC_MASK; + + /* enable the rate scheduler */ + bcnrc_val |= IXGBE_RTTBCNRC_RS_ENA; + } + + /* + * Set global transmit compensation time to the MMW_SIZE in RTTBCNRM + * register. Typically MMW_SIZE=0x014 if 9728-byte jumbo is supported + * and 0x004 otherwise. + */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRM, 0x4); + break; + case ixgbe_mac_X540: + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRM, 0x14); + break; + default: + break; + } + + /* determine how many queues per pool based on VMDq mask */ + queues_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + + /* write value for all Tx queues belonging to VF */ + for (queue = 0; queue < queues_per_pool; queue++) { + unsigned int reg_idx = (vf * queues_per_pool) + queue; + + IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, reg_idx); + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val); + } +} + +void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter) +{ + int i; + + /* VF Tx rate limit was not set */ + if (!adapter->vf_rate_link_speed) + return; + + if (ixgbe_link_mbps(adapter) != adapter->vf_rate_link_speed) { + adapter->vf_rate_link_speed = 0; + dev_info(ixgbe_pf_to_dev(adapter), + "Link speed has been changed. VF Transmit rate is disabled\n"); + } + + for (i = 0; i < adapter->num_vfs; i++) { + if (!adapter->vf_rate_link_speed) + adapter->vfinfo[i].tx_rate = 0; + + ixgbe_set_vf_rate_limit(adapter, i); + } +} + +/** + * ixgbe_ndo_set_vf_bw - Set bandwidth limit for a virtual function (VF) + * @netdev: Network device structure + * @vf: VF index + * @min_tx_rate: Minimum transmit rate (unused) + * @max_tx_rate: Maximum transmit rate in Mbps + * + * This function sets the maximum bandwidth limit for a specified virtual + * function (VF) on the network device. It verifies that the VF is active, + * the link is up, and the link speed is 10 Gbps. The function ensures that + * the specified rate is within valid limits and updates the hardware + * configuration accordingly. + * + * Return: 0 on success, -EINVAL if the VF index is out of range or the rate + * is invalid, or -EOPNOTSUPP if rate limiting is not supported. + */ +#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE +int ixgbe_ndo_set_vf_bw(struct net_device *netdev, + int vf, + int __always_unused min_tx_rate, + int max_tx_rate) +#else +int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int max_tx_rate) +#endif /* HAVE_NDO_SET_VF_MIN_MAX_TX_RATE */ +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int link_speed; + + /* verify VF is active */ + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + /* verify link is up */ + if (!adapter->link_up) + return -EINVAL; + + /* verify we are linked at 10Gbps */ + link_speed = ixgbe_link_mbps(adapter); + if (link_speed != 10000) + return -EINVAL; + + /* rate limit cannot be less than 10Mbs or greater than link speed */ + if (max_tx_rate && ((max_tx_rate <= 10) || (max_tx_rate > link_speed))) + return -EINVAL; + + /* store values */ + adapter->vf_rate_link_speed = link_speed; + adapter->vfinfo[vf].tx_rate = max_tx_rate; + + /* update hardware configuration */ + ixgbe_set_vf_rate_limit(adapter, vf); + + return 0; +} +#endif /* IFLA_VF_MAX */ + +#if IS_ENABLED(CONFIG_PCI_IOV) +/** + * ixgbe_ndo_set_vf_spoofchk - Enable or disable spoof checking for a VF + * @netdev: Network device structure + * @vf: VF index + * @setting: Boolean value to enable (true) or disable (false) spoof checking + * + * This function enables or disables MAC and VLAN spoof checking for a specified + * virtual function (VF) on the network device. It updates the VF's spoof check + * setting and configures the hardware accordingly. For certain hardware, it + * also configures Ethertype anti-spoofing for LLDP and FC. + * + * Return: 0 on success, or -EINVAL if the VF index is out of range. + */ +int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + adapter->vfinfo[vf].spoofchk_enabled = setting; + + /* configure MAC spoofing */ + hw->mac.ops.set_mac_anti_spoofing(hw, setting, vf); + + /* configure VLAN spoofing */ + hw->mac.ops.set_vlan_anti_spoofing(hw, setting, vf); + + /* Ensure LLDP and FC is set for Ethertype Antispoofing if we will be + * calling set_ethertype_anti_spoofing for each VF in loop below + */ + if (hw->mac.ops.set_ethertype_anti_spoofing) { + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_LLDP), + (IXGBE_ETQF_FILTER_EN | + IXGBE_ETQF_TX_ANTISPOOF | + IXGBE_ETH_P_LLDP)); + + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FC), + (IXGBE_ETQF_FILTER_EN | + IXGBE_ETQF_TX_ANTISPOOF | + ETH_P_PAUSE)); + + hw->mac.ops.set_ethertype_anti_spoofing(hw, setting, vf); + } + + return 0; +} +#endif /* CONFIG_PCI_IOV */ + +/** + * ixgbe_set_vf_rx_tx - Set VF rx tx + * @adapter: Pointer to adapter struct + * @vf: VF identifier + * + * Set or reset correct transmit and receive for vf + **/ +static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reg_cur_tx, reg_cur_rx, reg_req_tx, reg_req_rx; + u32 reg_offset, vf_shift; + + vf_shift = vf % 32; + reg_offset = vf / 32; + + reg_cur_tx = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); + reg_cur_rx = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); + + if (adapter->vfinfo[vf].link_enable) { + reg_req_tx = reg_cur_tx | 1 << vf_shift; + reg_req_rx = reg_cur_rx | 1 << vf_shift; + + } else { + reg_req_tx = reg_cur_tx & ~(1 << vf_shift); + reg_req_rx = reg_cur_rx & ~(1 << vf_shift); + } + + /* + * The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs. + * For more info take a look at ixgbe_set_vf_lpe + */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + struct net_device *dev = adapter->netdev; + int pf_max_frame = dev->mtu + ETH_HLEN; + +#if IS_ENABLED(CONFIG_FCOE) +#ifdef HAVE_NETDEV_FCOE_MTU + if (dev->fcoe_mtu) +#else + if (dev->features & NETIF_F_FCOE_MTU) +#endif + pf_max_frame = max_t(int, pf_max_frame, + IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif /* CONFIG_FCOE */ + + if (pf_max_frame > ETH_FRAME_LEN) + reg_req_rx = reg_cur_rx & ~(1 << vf_shift); + } + + /* Enable/Disable particular VF */ + if (reg_cur_tx != reg_req_tx) + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg_req_tx); + if (reg_cur_rx != reg_req_rx) + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg_req_rx); +} + +#ifdef HAVE_NDO_SET_VF_LINK_STATE + +/** + * ixgbe_set_vf_link_state - Set link state + * @adapter: Pointer to adapter struct + * @vf: VF identifier + * @state: required link state + * + * Set a link force state on/off a single vf + **/ +void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state) +{ + adapter->vfinfo[vf].link_state = state; + + switch (state) { + case IFLA_VF_LINK_STATE_AUTO: + if (test_bit(__IXGBE_DOWN, adapter->state)) + adapter->vfinfo[vf].link_enable = false; + else + adapter->vfinfo[vf].link_enable = true; + break; + case IFLA_VF_LINK_STATE_ENABLE: + adapter->vfinfo[vf].link_enable = true; + break; + case IFLA_VF_LINK_STATE_DISABLE: + adapter->vfinfo[vf].link_enable = false; + break; + } + + ixgbe_set_vf_rx_tx(adapter, vf); + + /* restart the VF */ + adapter->vfinfo[vf].clear_to_send = false; + ixgbe_ping_vf(adapter, vf); +} + +/** + * ixgbe_ndo_set_vf_link_state - Set link state + * @netdev: network interface device structure + * @vf: VF identifier + * @state: required link state + * + * Set the link state of a specified VF, regardless of physical link state + **/ +int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int ret = 0; + + if (vf < 0 || vf >= adapter->num_vfs) { + dev_err(ixgbe_pf_to_dev(adapter), + "NDO set VF link - invalid VF identifier %d\n", vf); + ret = -EINVAL; + goto out; + } + + switch (state) { + case IFLA_VF_LINK_STATE_ENABLE: + dev_info(ixgbe_pf_to_dev(adapter), + "NDO set VF %d link state %d - not supported\n", + vf, state); + break; + case IFLA_VF_LINK_STATE_DISABLE: + dev_info(ixgbe_pf_to_dev(adapter), + "NDO set VF %d link state disable\n", vf); + ixgbe_set_vf_link_state(adapter, vf, state); + break; + case IFLA_VF_LINK_STATE_AUTO: + dev_info(ixgbe_pf_to_dev(adapter), + "NDO set VF %d link state auto\n", vf); + ixgbe_set_vf_link_state(adapter, vf, state); + break; + default: + dev_err(ixgbe_pf_to_dev(adapter), + "NDO set VF %d - invalid link state %d\n", vf, state); + ret = -EINVAL; + } +out: + return ret; +} +#endif /* HAVE_NDO_SET_VF_LINK_STATE */ + +#ifdef IFLA_VF_MAX +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN +/** + * ixgbe_ndo_set_vf_rss_query_en - Enable or disable RSS query for a VF + * @netdev: Network device structure + * @vf: VF index + * @setting: Boolean value to enable (true) or disable (false) RSS query + * + * This function enables or disables the Receive Side Scaling (RSS) query + * capability for a specified virtual function (VF) on the network device. + * The operation is supported only for 82599 and X540 devices. + * + * Return: 0 on success, -EINVAL if the VF index is out of range, or + * -EOPNOTSUPP if the operation is not supported on the device. + */ +int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf, + bool setting) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + /* This operation is currently supported only for 82599 and x540 + * devices. + */ + if (adapter->hw.mac.type < ixgbe_mac_82599EB || + adapter->hw.mac.type >= ixgbe_mac_X550) + return -EOPNOTSUPP; + + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + adapter->vfinfo[vf].rss_query_enabled = setting; + + return 0; +} +#endif + +/** + * ixgbe_ndo_get_vf_config - Retrieve configuration for a virtual function (VF) + * @netdev: Network device structure + * @vf: VF index + * @ivi: Pointer to ifla_vf_info structure to be filled with VF configuration + * + * This function retrieves the configuration for a specified virtual function + * (VF) on the network device. It populates the `ifla_vf_info` structure with + * details such as the VF's MAC address, VLAN, QoS, and other attributes. The + * function supports additional parameters based on kernel capabilities. + * + * Return: 0 on success, or -EINVAL if the VF index is out of range. + */ +int ixgbe_ndo_get_vf_config(struct net_device *netdev, + int vf, struct ifla_vf_info *ivi) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (vf < 0 || vf >= adapter->num_vfs) + return -EINVAL; + + ivi->vf = vf; + memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); + +#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE + ivi->max_tx_rate = adapter->vfinfo[vf].tx_rate; + ivi->min_tx_rate = 0; +#else + ivi->tx_rate = adapter->vfinfo[vf].tx_rate; +#endif /* HAVE_NDO_SET_VF_MIN_MAX_TX_RATE */ + + ivi->vlan = adapter->vfinfo[vf].pf_vlan; + ivi->qos = adapter->vfinfo[vf].pf_qos; + +#ifdef HAVE_NDO_SET_VF_LINK_STATE + ivi->linkstate = adapter->vfinfo[vf].link_state; +#endif +#ifdef HAVE_VF_SPOOFCHK_CONFIGURE + ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled; +#endif +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN + ivi->rss_query_en = adapter->vfinfo[vf].rss_query_enabled; +#endif +#ifdef HAVE_NDO_SET_VF_TRUST + ivi->trusted = adapter->vfinfo[vf].trusted; +#endif + return 0; +} +#endif /* IFLA_VF_MAX */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.h new file mode 100644 index 0000000000..9ec812f353 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sriov.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_SRIOV_H_ +#define _IXGBE_SRIOV_H_ + +/* ixgbe driver limit the max number of VFs could be enabled to + * 63 (IXGBE_MAX_VF_FUNCTIONS - 1) + */ +#define IXGBE_MAX_VFS_DRV_LIMIT (IXGBE_MAX_VF_FUNCTIONS - 1) +#define IXGBE_MAX_VFS_1TC IXGBE_MAX_VFS_DRV_LIMIT +#define IXGBE_MAX_VFS_4TC 31 +#define IXGBE_MAX_VFS_8TC 15 + +void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter); +int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf); +void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe); +int ixgbe_check_mdd_event(struct ixgbe_adapter *adapter); +void ixgbe_msg_task(struct ixgbe_adapter *adapter); +int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, + int vf, unsigned char *mac_addr); +void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); +void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter); +#ifdef IFLA_VF_MAX +int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); +#ifdef IFLA_VF_VLAN_INFO_MAX +int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, + u8 qos, __be16 vlan_proto); +#else +int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, + u8 qos); +#endif +#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE +int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, + int max_tx_rate); +#else +int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); +#endif /* HAVE_NDO_SET_VF_MIN_MAX_TX_RATE */ +#ifdef HAVE_NDO_SET_VF_RSS_QUERY_EN +int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf, + bool setting); +#endif +#ifdef HAVE_NDO_SET_VF_TRUST +int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting); +#endif +int ixgbe_ndo_get_vf_config(struct net_device *netdev, + int vf, struct ifla_vf_info *ivi); +#endif /* IFLA_VF_MAX */ +int ixgbe_disable_sriov(struct ixgbe_adapter *adapter); +#ifdef CONFIG_PCI_IOV +int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); +void ixgbe_enable_sriov(struct ixgbe_adapter *adapter); +int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); +#endif +#ifdef HAVE_NDO_SET_VF_LINK_STATE +int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state); +#endif +int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs); +#ifdef IFLA_VF_MAX +void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); +#endif /* IFLA_VF_MAX */ +void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state); +void ixgbe_dump_registers(struct ixgbe_adapter *adapter); + +/* + * These are defined in ixgbe_type.h on behalf of the VF driver + * but we need them here unwrapped for the PF driver. + */ +#define IXGBE_DEV_ID_E630_VF 0x126B +#define IXGBE_DEV_ID_E610_VF 0x57AD +#define IXGBE_DEV_ID_82599_VF 0x10ED +#define IXGBE_DEV_ID_X540_VF 0x1515 +#define IXGBE_DEV_ID_X550_VF 0x1565 +#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8 +#define IXGBE_DEV_ID_X550EM_A_VF 0x15C5 +#endif /* _IXGBE_SRIOV_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sysfs.c new file mode 100644 index 0000000000..dde0dcbe24 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_sysfs.c @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" +#include "ixgbe_common.h" +#include "ixgbe_type.h" + +#ifdef IXGBE_SYSFS + +#include +#include +#include +#include +#include +#include +#include +#ifdef IXGBE_HWMON +#include +#endif + +#ifdef IXGBE_HWMON +/* hwmon callback functions */ +static ssize_t ixgbe_hwmon_show_location(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + return snprintf(buf, PAGE_SIZE, "loc%u\n", + ixgbe_attr->sensor->location); +} + +static ssize_t ixgbe_hwmon_show_temp(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + unsigned int value; + + /* reset the temp field */ + ixgbe_attr->hw->mac.ops.get_thermal_sensor_data(ixgbe_attr->hw); + + value = ixgbe_attr->sensor->temp; + + /* display millidegree */ + value *= 1000; + + return snprintf(buf, PAGE_SIZE, "%u\n", value); +} + +static ssize_t ixgbe_hwmon_show_cautionthresh(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + unsigned int value = ixgbe_attr->sensor->caution_thresh; + + /* display millidegree */ + value *= 1000; + + return snprintf(buf, PAGE_SIZE, "%u\n", value); +} + +static ssize_t ixgbe_hwmon_show_maxopthresh(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + unsigned int value = ixgbe_attr->sensor->max_op_thresh; + + /* display millidegree */ + value *= 1000; + + return snprintf(buf, PAGE_SIZE, "%u\n", value); +} + +/** + * ixgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file. + * @adapter: pointer to the adapter structure + * @offset: offset in the eeprom sensor data table + * @type: type of sensor data to display + * + * For each file we want in hwmon's sysfs interface we need a device_attribute + * This is included in our hwmon_attr struct that contains the references to + * the data structures we need to get the data to display. + */ +static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter, + unsigned int offset, int type) { + unsigned int n_attr; + struct hwmon_attr *ixgbe_attr; +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + + n_attr = adapter->ixgbe_hwmon_buff->n_hwmon; + ixgbe_attr = &adapter->ixgbe_hwmon_buff->hwmon_list[n_attr]; +#else + int rc; + + n_attr = adapter->ixgbe_hwmon_buff.n_hwmon; + ixgbe_attr = &adapter->ixgbe_hwmon_buff.hwmon_list[n_attr]; +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ + + switch (type) { + case IXGBE_HWMON_TYPE_LOC: + ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_location; + snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), + "temp%u_label", offset + 1); + break; + case IXGBE_HWMON_TYPE_TEMP: + ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_temp; + snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), + "temp%u_input", offset + 1); + break; + case IXGBE_HWMON_TYPE_CAUTION: + ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_cautionthresh; + snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), + "temp%u_max", offset + 1); + break; + case IXGBE_HWMON_TYPE_MAX: + ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_maxopthresh; + snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), + "temp%u_crit", offset + 1); + break; + default: + return -EPERM; + } + + /* These always the same regardless of type */ + ixgbe_attr->sensor = + &adapter->hw.mac.thermal_sensor_data.sensor[offset]; + ixgbe_attr->hw = &adapter->hw; + ixgbe_attr->dev_attr.store = NULL; + ixgbe_attr->dev_attr.attr.mode = 0444; + ixgbe_attr->dev_attr.attr.name = ixgbe_attr->name; + +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + sysfs_attr_init(&ixgbe_attr->dev_attr.attr); + + adapter->ixgbe_hwmon_buff->attrs[n_attr] = &ixgbe_attr->dev_attr.attr; + + ++adapter->ixgbe_hwmon_buff->n_hwmon; + + return 0; +#else + rc = device_create_file(ixgbe_pf_to_dev(adapter), + &ixgbe_attr->dev_attr); + + if (rc == 0) + ++adapter->ixgbe_hwmon_buff.n_hwmon; + + return rc; +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ +} +#endif /* IXGBE_HWMON */ + +static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter __maybe_unused *adapter) +{ +#ifdef IXGBE_HWMON +#ifndef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + int i; + + if (adapter == NULL) + return; + + for (i = 0; i < adapter->ixgbe_hwmon_buff.n_hwmon; i++) { + device_remove_file(ixgbe_pf_to_dev(adapter), + &adapter->ixgbe_hwmon_buff.hwmon_list[i].dev_attr); + } + + kfree(adapter->ixgbe_hwmon_buff.hwmon_list); + + if (adapter->ixgbe_hwmon_buff.device) + hwmon_device_unregister(adapter->ixgbe_hwmon_buff.device); +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ +#endif /* IXGBE_HWMON */ +} + +/* called from ixgbe_main.c */ +void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter) +{ + ixgbe_sysfs_del_adapter(adapter); +} + +/* called from ixgbe_main.c */ +int ixgbe_sysfs_init(struct ixgbe_adapter *adapter) +{ + int rc = 0; +#ifdef IXGBE_HWMON +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + struct hwmon_buff *ixgbe_hwmon; + struct device *hwmon_dev; +#else + struct hwmon_buff *ixgbe_hwmon = &adapter->ixgbe_hwmon_buff; + int n_attrs; +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ + unsigned int i; +#endif /* IXGBE_HWMON */ + +#ifdef IXGBE_HWMON + /* If this method isn't defined we don't support thermals */ + if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) { + goto no_thermal; + } + + /* Don't create thermal hwmon interface if no sensors present */ + if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw)) + goto no_thermal; + +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + ixgbe_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*ixgbe_hwmon), + GFP_KERNEL); + + if (!ixgbe_hwmon) { + rc = -ENOMEM; + goto exit; + } + + adapter->ixgbe_hwmon_buff = ixgbe_hwmon; +#else + /* + * Allocation space for max attributs + * max num sensors * values (loc, temp, max, caution) + */ + n_attrs = IXGBE_MAX_SENSORS * 4; + ixgbe_hwmon->hwmon_list = kcalloc(n_attrs, sizeof(struct hwmon_attr), + GFP_KERNEL); + + if (!ixgbe_hwmon->hwmon_list) { + rc = -ENOMEM; + goto err; + } +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ + + for (i = 0; i < IXGBE_MAX_SENSORS; i++) { + /* + * Only create hwmon sysfs entries for sensors that have + * meaningful data for. + */ + if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0) + continue; + + /* Bail if any hwmon attr struct fails to initialize */ + rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_CAUTION); + if (rc) + goto err; + rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_LOC); + if (rc) + goto err; + rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_TEMP); + if (rc) + goto err; + rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_MAX); + if (rc) + goto err; + } + +#ifdef HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS + ixgbe_hwmon->groups[0] = &ixgbe_hwmon->group; + ixgbe_hwmon->group.attrs = ixgbe_hwmon->attrs; + + hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev, + "ixgbe", + ixgbe_hwmon, + ixgbe_hwmon->groups); + + if (IS_ERR(hwmon_dev)) { + rc = PTR_ERR(hwmon_dev); + goto exit; + } + +#else + ixgbe_hwmon->device = + hwmon_device_register(ixgbe_pf_to_dev(adapter)); + + if (IS_ERR(ixgbe_hwmon->device)) { + rc = PTR_ERR(ixgbe_hwmon->device); + goto err; + } + +#endif /* HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS */ +no_thermal: +#endif /* IXGBE_HWMON */ + + goto exit; + +err: + ixgbe_sysfs_del_adapter(adapter); +exit: + return rc; +} +#endif /* IXGBE_SYSFS */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_txrx_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_txrx_common.h new file mode 100644 index 0000000000..d2c42d37b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_txrx_common.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_TXRX_COMMON_H_ +#define _IXGBE_TXRX_COMMON_H_ + +#define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \ + IXGBE_TXD_CMD_RS) + +#define IXGBE_XDP_PASS 0 +#define IXGBE_XDP_CONSUMED BIT(0) +#define IXGBE_XDP_TX BIT(1) +#define IXGBE_XDP_REDIR BIT(2) + +#define IXGBE_PKT_HDR_PAD (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2)) + +void ixgbe_xdp_ring_update_tail(struct ixgbe_ring *ring); +void ixgbe_xdp_ring_update_tail_locked(struct ixgbe_ring *ring); + +#ifdef HAVE_XDP_SUPPORT +#ifdef HAVE_XDP_FRAME_STRUCT +int ixgbe_xmit_xdp_ring(struct ixgbe_ring *ring, struct xdp_frame *xdpf); +#else +int ixgbe_xmit_xdp_ring(struct ixgbe_ring *ring, struct xdp_buff *xdp); +#endif +#ifdef HAVE_AF_XDP_ZC_SUPPORT +void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring); +void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring); + +#ifndef HAVE_NETDEV_BPF_XSK_POOL +struct xdp_umem *ixgbe_xsk_umem(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring); +int ixgbe_xsk_umem_setup(struct ixgbe_adapter *adapter, struct xdp_umem *umem, + u16 qid); +#else +struct xsk_buff_pool *ixgbe_xsk_umem(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring); +int ixgbe_xsk_umem_setup(struct ixgbe_adapter *adapter, struct xsk_buff_pool *umem, + u16 qid); +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +void ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 cleaned_count); +void ixgbe_zca_free(struct zero_copy_allocator *alloc, unsigned long handle); +#else +bool ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 cleaned_count); +#endif +int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *rx_ring, + const int budget); +void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring); +bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *tx_ring); +#ifdef HAVE_NDO_XSK_WAKEUP +int ixgbe_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags); +#else +int ixgbe_xsk_async_xmit(struct net_device *dev, u32 queue_id); +#endif +void ixgbe_xsk_clean_tx_ring(struct ixgbe_ring *tx_ring); +bool ixgbe_xsk_any_rx_ring_enabled(struct ixgbe_adapter *adapter); +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif /* HAVE_XDP_SUPPORT */ + +bool ixgbe_cleanup_headers(struct ixgbe_ring __maybe_unused *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb); +void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb); +void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb); + +void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, u64 qmask); +#endif /* _IXGBE_TXRX_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type.h new file mode 100644 index 0000000000..c1ea3e3498 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type.h @@ -0,0 +1,4428 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_TYPE_H_ +#define _IXGBE_TYPE_H_ + +/* + * The following is a brief description of the error categories used by the + * ERROR_REPORT* macros. + * + * - IXGBE_ERROR_INVALID_STATE + * This category is for errors which represent a serious failure state that is + * unexpected, and could be potentially harmful to device operation. It should + * not be used for errors relating to issues that can be worked around or + * ignored. + * + * - IXGBE_ERROR_POLLING + * This category is for errors related to polling/timeout issues and should be + * used in any case where the timeout occurred, or a failure to obtain a lock, or + * failure to receive data within the time limit. + * + * - IXGBE_ERROR_CAUTION + * This category should be used for reporting issues that may be the cause of + * other errors, such as temperature warnings. It should indicate an event which + * could be serious, but hasn't necessarily caused problems yet. + * + * - IXGBE_ERROR_SOFTWARE + * This category is intended for errors due to software state preventing + * something. The category is not intended for errors due to bad arguments, or + * due to unsupported features. It should be used when a state occurs which + * prevents action but is not a serious issue. + * + * - IXGBE_ERROR_ARGUMENT + * This category is for when a bad or invalid argument is passed. It should be + * used whenever a function is called and error checking has detected the + * argument is wrong or incorrect. + * + * - IXGBE_ERROR_UNSUPPORTED + * This category is for errors which are due to unsupported circumstances or + * configuration issues. It should not be used when the issue is due to an + * invalid argument, but for when something has occurred that is unsupported + * (Ex: Flow control autonegotiation or an unsupported SFP+ module.) + */ + +#include "ixgbe_osdep.h" +#include "ixgbe_type_e610.h" + +/* Override this by setting IOMEM in your ixgbe_osdep.h header */ +#ifndef IOMEM +#define IOMEM +#endif + +/* Vendor ID */ +#define IXGBE_INTEL_VENDOR_ID 0x8086 + +/* Device IDs */ +#define IXGBE_DEV_ID_82598 0x10B6 +#define IXGBE_DEV_ID_82598_BX 0x1508 +#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6 +#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 +#define IXGBE_DEV_ID_82598AT 0x10C8 +#define IXGBE_DEV_ID_82598AT2 0x150B +#define IXGBE_DEV_ID_82598EB_SFP_LOM 0x10DB +#define IXGBE_DEV_ID_82598EB_CX4 0x10DD +#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC +#define IXGBE_DEV_ID_82598_DA_DUAL_PORT 0x10F1 +#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1 +#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 +#define IXGBE_DEV_ID_82599_KX4 0x10F7 +#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514 +#define IXGBE_DEV_ID_82599_KR 0x1517 +#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 +#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C +#define IXGBE_DEV_ID_82599_CX4 0x10F9 +#define IXGBE_DEV_ID_82599_SFP 0x10FB +#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 +#define IXGBE_SUBDEV_ID_82599_SFP_WOL0 0x1071 +#define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72 +#define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 +#define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470 +#define IXGBE_SUBDEV_ID_82599_SP_560FLR 0x211B +#define IXGBE_SUBDEV_ID_82599_LOM_SNAP6 0x2159 +#define IXGBE_SUBDEV_ID_82599_SFP_1OCP 0x000D +#define IXGBE_SUBDEV_ID_82599_SFP_2OCP 0x0008 +#define IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM1 0x8976 +#define IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM2 0x06EE +#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152A +#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529 +#define IXGBE_DEV_ID_82599_SFP_EM 0x1507 +#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D +#define IXGBE_DEV_ID_82599_SFP_SF_QP 0x154A +#define IXGBE_DEV_ID_82599_QSFP_SF_QP 0x1558 +#define IXGBE_DEV_ID_82599EN_SFP 0x1557 +#define IXGBE_SUBDEV_ID_82599EN_SFP_OCP1 0x0001 +#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC +#define IXGBE_DEV_ID_82599_T3_LOM 0x151C +#define IXGBE_DEV_ID_X540T 0x1528 +#define IXGBE_DEV_ID_X540T1 0x1560 +#define IXGBE_DEV_ID_X550T 0x1563 +#define IXGBE_DEV_ID_X550T1 0x15D1 +/* Placeholder value, pending official value. */ +#define IXGBE_DEV_ID_X550EM_A_KR 0x15C2 +#define IXGBE_DEV_ID_X550EM_A_KR_L 0x15C3 +#define IXGBE_DEV_ID_X550EM_A_SFP_N 0x15C4 +#define IXGBE_DEV_ID_X550EM_A_SGMII 0x15C6 +#define IXGBE_DEV_ID_X550EM_A_SGMII_L 0x15C7 +#define IXGBE_DEV_ID_X550EM_A_10G_T 0x15C8 +#define IXGBE_DEV_ID_X550EM_A_QSFP 0x15CA +#define IXGBE_DEV_ID_X550EM_A_QSFP_N 0x15CC +#define IXGBE_DEV_ID_X550EM_A_SFP 0x15CE +#define IXGBE_DEV_ID_X550EM_A_1G_T 0x15E4 +#define IXGBE_DEV_ID_X550EM_A_1G_T_L 0x15E5 +#define IXGBE_DEV_ID_X550EM_X_KX4 0x15AA +#define IXGBE_DEV_ID_X550EM_X_KR 0x15AB +#define IXGBE_DEV_ID_X550EM_X_SFP 0x15AC +#define IXGBE_DEV_ID_X550EM_X_10G_T 0x15AD +#define IXGBE_DEV_ID_X550EM_X_1G_T 0x15AE +#define IXGBE_DEV_ID_X550EM_X_XFI 0x15B0 +#define IXGBE_DEV_ID_E610_BACKPLANE 0x57AE +#define IXGBE_DEV_ID_E610_SFP 0x57AF +#define IXGBE_DEV_ID_E610_10G_T 0x57B0 +#define IXGBE_DEV_ID_E610_2_5G_T 0x57B1 +#define IXGBE_DEV_ID_E610_SGMII 0x57B2 + +#define IXGBE_CAT(r,m) IXGBE_##r##m + +#define IXGBE_BY_MAC(_hw, r) ((_hw)->mvals[IXGBE_CAT(r, _IDX)]) + +/* General Registers */ +#define IXGBE_CTRL 0x00000 +#define IXGBE_STATUS 0x00008 +#define IXGBE_CTRL_EXT 0x00018 +#define IXGBE_ESDP 0x00020 +#define IXGBE_EODSDP 0x00028 +#define IXGBE_I2CCTL_82599 0x00028 +#define IXGBE_I2CCTL IXGBE_I2CCTL_82599 +#define IXGBE_I2CCTL_X540 IXGBE_I2CCTL_82599 +#define IXGBE_I2CCTL_X550 0x15F5C +#define IXGBE_I2CCTL_X550EM_x IXGBE_I2CCTL_X550 +#define IXGBE_I2CCTL_X550EM_a IXGBE_I2CCTL_X550 +#define IXGBE_I2CCTL_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2CCTL) +#define IXGBE_PHY_GPIO 0x00028 +#define IXGBE_MAC_GPIO 0x00030 +#define IXGBE_PHYINT_STATUS0 0x00100 +#define IXGBE_PHYINT_STATUS1 0x00104 +#define IXGBE_PHYINT_STATUS2 0x00108 +#define IXGBE_LEDCTL 0x00200 +#define IXGBE_FRTIMER 0x00048 +#define IXGBE_TCPTIMER 0x0004C +#define IXGBE_CORESPARE 0x00600 +#define IXGBE_EXVET 0x05078 + +/* NVM Registers */ +#define IXGBE_EEC 0x10010 +#define IXGBE_EEC_X540 IXGBE_EEC +#define IXGBE_EEC_X550 IXGBE_EEC +#define IXGBE_EEC_X550EM_x IXGBE_EEC +#define IXGBE_EEC_X550EM_a 0x15FF8 +#define IXGBE_EEC_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EEC) + +#define IXGBE_EERD 0x10014 +#define IXGBE_EEWR 0x10018 + +#define IXGBE_FLA 0x1001C +#define IXGBE_FLA_X540 IXGBE_FLA +#define IXGBE_FLA_X550 IXGBE_FLA +#define IXGBE_FLA_X550EM_x IXGBE_FLA +#define IXGBE_FLA_X550EM_a 0x15F68 +#define IXGBE_FLA_BY_MAC(_hw) IXGBE_BY_MAC((_hw), FLA) +#define IXGBE_FLA_FL_SIZE_SHIFT_X540 17 +#define IXGBE_FLA_FL_SIZE_SHIFT_X550 12 +#define IXGBE_FLA_FL_SIZE_MASK_X540 (0x7 << IXGBE_FLA_FL_SIZE_SHIFT_X540) +#define IXGBE_FLA_FL_SIZE_MASK_X550 (0x7 << IXGBE_FLA_FL_SIZE_SHIFT_X550) + +#define IXGBE_EEMNGCTL 0x10110 +#define IXGBE_EEMNGDATA 0x10114 +#define IXGBE_FLMNGCTL 0x10118 +#define IXGBE_FLMNGDATA 0x1011C +#define IXGBE_FLMNGCNT 0x10120 +#define IXGBE_FLOP 0x1013C + +#define IXGBE_GRC 0x10200 +#define IXGBE_GRC_X540 IXGBE_GRC +#define IXGBE_GRC_X550 IXGBE_GRC +#define IXGBE_GRC_X550EM_x IXGBE_GRC +#define IXGBE_GRC_X550EM_a 0x15F64 +#define IXGBE_GRC_BY_MAC(_hw) IXGBE_BY_MAC((_hw), GRC) + +#define IXGBE_SRAMREL 0x10210 +#define IXGBE_SRAMREL_X540 IXGBE_SRAMREL +#define IXGBE_SRAMREL_X550 IXGBE_SRAMREL +#define IXGBE_SRAMREL_X550EM_x IXGBE_SRAMREL +#define IXGBE_SRAMREL_X550EM_a 0x15F6C +#define IXGBE_SRAMREL_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SRAMREL) + +#define IXGBE_PHYDBG 0x10218 + +/* General Receive Control */ +#define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */ +#define IXGBE_GRC_APME 0x00000002 /* APM enabled in EEPROM */ + +#define IXGBE_VPDDIAG0 0x10204 +#define IXGBE_VPDDIAG1 0x10208 + +/* I2CCTL Bit Masks */ +#define IXGBE_I2C_CLK_IN 0x00000001 +#define IXGBE_I2C_CLK_IN_X540 IXGBE_I2C_CLK_IN +#define IXGBE_I2C_CLK_IN_X550 0x00004000 +#define IXGBE_I2C_CLK_IN_X550EM_x IXGBE_I2C_CLK_IN_X550 +#define IXGBE_I2C_CLK_IN_X550EM_a IXGBE_I2C_CLK_IN_X550 +#define IXGBE_I2C_CLK_IN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_IN) + +#define IXGBE_I2C_CLK_OUT 0x00000002 +#define IXGBE_I2C_CLK_OUT_X540 IXGBE_I2C_CLK_OUT +#define IXGBE_I2C_CLK_OUT_X550 0x00000200 +#define IXGBE_I2C_CLK_OUT_X550EM_x IXGBE_I2C_CLK_OUT_X550 +#define IXGBE_I2C_CLK_OUT_X550EM_a IXGBE_I2C_CLK_OUT_X550 +#define IXGBE_I2C_CLK_OUT_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_OUT) + +#define IXGBE_I2C_DATA_IN 0x00000004 +#define IXGBE_I2C_DATA_IN_X540 IXGBE_I2C_DATA_IN +#define IXGBE_I2C_DATA_IN_X550 0x00001000 +#define IXGBE_I2C_DATA_IN_X550EM_x IXGBE_I2C_DATA_IN_X550 +#define IXGBE_I2C_DATA_IN_X550EM_a IXGBE_I2C_DATA_IN_X550 +#define IXGBE_I2C_DATA_IN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_IN) + +#define IXGBE_I2C_DATA_OUT 0x00000008 +#define IXGBE_I2C_DATA_OUT_X540 IXGBE_I2C_DATA_OUT +#define IXGBE_I2C_DATA_OUT_X550 0x00000400 +#define IXGBE_I2C_DATA_OUT_X550EM_x IXGBE_I2C_DATA_OUT_X550 +#define IXGBE_I2C_DATA_OUT_X550EM_a IXGBE_I2C_DATA_OUT_X550 +#define IXGBE_I2C_DATA_OUT_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_OUT) + +#define IXGBE_I2C_DATA_OE_N_EN 0 +#define IXGBE_I2C_DATA_OE_N_EN_X540 IXGBE_I2C_DATA_OE_N_EN +#define IXGBE_I2C_DATA_OE_N_EN_X550 0x00000800 +#define IXGBE_I2C_DATA_OE_N_EN_X550EM_x IXGBE_I2C_DATA_OE_N_EN_X550 +#define IXGBE_I2C_DATA_OE_N_EN_X550EM_a IXGBE_I2C_DATA_OE_N_EN_X550 +#define IXGBE_I2C_DATA_OE_N_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_OE_N_EN) + +#define IXGBE_I2C_BB_EN 0 +#define IXGBE_I2C_BB_EN_X540 IXGBE_I2C_BB_EN +#define IXGBE_I2C_BB_EN_X550 0x00000100 +#define IXGBE_I2C_BB_EN_X550EM_x IXGBE_I2C_BB_EN_X550 +#define IXGBE_I2C_BB_EN_X550EM_a IXGBE_I2C_BB_EN_X550 +#define IXGBE_I2C_BB_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_BB_EN) + +#define IXGBE_I2C_CLK_OE_N_EN 0 +#define IXGBE_I2C_CLK_OE_N_EN_X540 IXGBE_I2C_CLK_OE_N_EN +#define IXGBE_I2C_CLK_OE_N_EN_X550 0x00002000 +#define IXGBE_I2C_CLK_OE_N_EN_X550EM_x IXGBE_I2C_CLK_OE_N_EN_X550 +#define IXGBE_I2C_CLK_OE_N_EN_X550EM_a IXGBE_I2C_CLK_OE_N_EN_X550 +#define IXGBE_I2C_CLK_OE_N_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_OE_N_EN) +#define IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT 500 + +#define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8 +#define IXGBE_EMC_INTERNAL_DATA 0x00 +#define IXGBE_EMC_INTERNAL_THERM_LIMIT 0x20 +#define IXGBE_EMC_DIODE1_DATA 0x01 +#define IXGBE_EMC_DIODE1_THERM_LIMIT 0x19 +#define IXGBE_EMC_DIODE2_DATA 0x23 +#define IXGBE_EMC_DIODE2_THERM_LIMIT 0x1A + +#define IXGBE_MAX_SENSORS 3 + +struct ixgbe_thermal_diode_data { + u8 location; + u8 temp; + u8 caution_thresh; + u8 max_op_thresh; +}; + +struct ixgbe_thermal_sensor_data { + struct ixgbe_thermal_diode_data sensor[IXGBE_MAX_SENSORS]; +}; + +#define NVM_OROM_OFFSET 0x17 +#define NVM_OROM_BLK_LOW 0x83 +#define NVM_OROM_BLK_HI 0x84 +#define NVM_OROM_PATCH_MASK 0xFF +#define NVM_OROM_SHIFT 8 + +#define NVM_VER_MASK 0x00FF /* version mask */ +#define NVM_VER_SHIFT 8 /* version bit shift */ +#define NVM_OEM_PROD_VER_PTR 0x1B /* OEM Product version block pointer */ +#define NVM_OEM_PROD_VER_CAP_OFF 0x1 /* OEM Product version format offset */ +#define NVM_OEM_PROD_VER_OFF_L 0x2 /* OEM Product version offset low */ +#define NVM_OEM_PROD_VER_OFF_H 0x3 /* OEM Product version offset high */ +#define NVM_OEM_PROD_VER_CAP_MASK 0xF /* OEM Product version cap mask */ +#define NVM_OEM_PROD_VER_MOD_LEN 0x3 /* OEM Product version module length */ +#define NVM_ETK_OFF_LOW 0x2D /* version low order word */ +#define NVM_ETK_OFF_HI 0x2E /* version high order word */ +#define NVM_ETK_SHIFT 16 /* high version word shift */ +#define NVM_VER_INVALID 0xFFFF +#define NVM_ETK_VALID 0x8000 +#define NVM_INVALID_PTR 0xFFFF +#define NVM_VER_SIZE 32 /* version sting size */ + +struct ixgbe_nvm_version { + u32 etk_id; + u8 nvm_major; + u16 nvm_minor; + u8 nvm_id; + + bool oem_valid; + u8 oem_major; + u8 oem_minor; + u16 oem_release; + + bool or_valid; + u8 or_major; + u16 or_build; + u8 or_patch; + +}; + +/* Interrupt Registers */ +#define IXGBE_EICR 0x00800 +#define IXGBE_EICS 0x00808 +#define IXGBE_EIMS 0x00880 +#define IXGBE_EIMC 0x00888 +#define IXGBE_EIAC 0x00810 +#define IXGBE_EIAM 0x00890 +#define IXGBE_EICS_EX(_i) (0x00A90 + (_i) * 4) +#define IXGBE_EIMS_EX(_i) (0x00AA0 + (_i) * 4) +#define IXGBE_EIMC_EX(_i) (0x00AB0 + (_i) * 4) +#define IXGBE_EIAM_EX(_i) (0x00AD0 + (_i) * 4) +/* 82599 EITR is only 12 bits, with the lower 3 always zero */ +/* + * 82598 EITR is 16 bits but set the limits based on the max + * supported by all ixgbe hardware + */ +#define IXGBE_MAX_INT_RATE 488281 +#define IXGBE_MIN_INT_RATE 956 +#define IXGBE_MAX_EITR 0x00000FF8 +#define IXGBE_MIN_EITR 8 +#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \ + (0x012300 + (((_i) - 24) * 4))) +#define IXGBE_EITR_ITR_INT_MASK 0x00000FF8 +#define IXGBE_EITR_LLI_MOD 0x00008000 +#define IXGBE_EITR_CNT_WDIS 0x80000000 +#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */ +#define IXGBE_IVAR_MISC 0x00A00 /* misc MSI-X interrupt causes */ +#define IXGBE_EITRSEL 0x00894 +#define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */ +#define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */ +#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4))) +#define IXGBE_GPIE 0x00898 + +/* Flow Control Registers */ +#define IXGBE_FCADBUL 0x03210 +#define IXGBE_FCADBUH 0x03214 +#define IXGBE_FCAMACL 0x04328 +#define IXGBE_FCAMACH 0x0432C +#define IXGBE_FCRTH_82599(_i) (0x03260 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_FCRTL_82599(_i) (0x03220 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_PFCTOP 0x03008 +#define IXGBE_FCTTV(_i) (0x03200 + ((_i) * 4)) /* 4 of these (0-3) */ +#define IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */ +#define IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */ +#define IXGBE_FCRTV 0x032A0 +#define IXGBE_FCCFG 0x03D00 +#define IXGBE_TFCS 0x0CE00 + +/* Receive DMA Registers */ +#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \ + (0x0D000 + (((_i) - 64) * 0x40))) +#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \ + (0x0D004 + (((_i) - 64) * 0x40))) +#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \ + (0x0D008 + (((_i) - 64) * 0x40))) +#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \ + (0x0D010 + (((_i) - 64) * 0x40))) +#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \ + (0x0D018 + (((_i) - 64) * 0x40))) +#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \ + (0x0D028 + (((_i) - 64) * 0x40))) +#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \ + (0x0D02C + (((_i) - 64) * 0x40))) +#define IXGBE_RSCDBU 0x03028 +#define IXGBE_RDDCC 0x02F20 +#define IXGBE_RXMEMWRAP 0x03190 +#define IXGBE_STARCTRL 0x03024 +/* + * Split and Replication Receive Control Registers + * 00-15 : 0x02100 + n*4 + * 16-64 : 0x01014 + n*0x40 + * 64-127: 0x0D014 + (n-64)*0x40 + */ +#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \ + (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \ + (0x0D014 + (((_i) - 64) * 0x40)))) +/* + * Rx DCA Control Register: + * 00-15 : 0x02200 + n*4 + * 16-64 : 0x0100C + n*0x40 + * 64-127: 0x0D00C + (n-64)*0x40 + */ +#define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \ + (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \ + (0x0D00C + (((_i) - 64) * 0x40)))) +#define IXGBE_RDRXCTL 0x02F00 +/* 8 of these 0x03C00 - 0x03C1C */ +#define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4)) +#define IXGBE_RXCTRL 0x03000 +#define IXGBE_DROPEN 0x03D04 +#define IXGBE_RXPBSIZE_SHIFT 10 +#define IXGBE_RXPBSIZE_MASK 0x000FFC00 + +/* Receive Registers */ +#define IXGBE_RXCSUM 0x05000 +#define IXGBE_RFCTL 0x05008 +#define IXGBE_DRECCCTL 0x02F08 +#define IXGBE_DRECCCTL_DISABLE 0 +#define IXGBE_DRECCCTL2 0x02F8C + +/* Multicast Table Array - 128 entries */ +#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4)) +#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \ + (0x0A200 + ((_i) * 8))) +#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \ + (0x0A204 + ((_i) * 8))) +#define IXGBE_MPSAR_LO(_i) (0x0A600 + ((_i) * 8)) +#define IXGBE_MPSAR_HI(_i) (0x0A604 + ((_i) * 8)) +/* Packet split receive type */ +#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : \ + (0x0EA00 + ((_i) * 4))) +/* array of 4096 1-bit vlan filters */ +#define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4)) +/*array of 4096 4-bit vlan vmdq indices */ +#define IXGBE_VFTAVIND(_j, _i) (0x0A200 + ((_j) * 0x200) + ((_i) * 4)) +#define IXGBE_FCTRL 0x05080 +#define IXGBE_VLNCTRL 0x05088 +#define IXGBE_MCSTCTRL 0x05090 +#define IXGBE_MRQC 0x05818 +#define IXGBE_SAQF(_i) (0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */ +#define IXGBE_DAQF(_i) (0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */ +#define IXGBE_SDPQF(_i) (0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */ +#define IXGBE_FTQF(_i) (0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */ +#define IXGBE_ETQF(_i) (0x05128 + ((_i) * 4)) /* EType Queue Filter */ +#define IXGBE_ETQS(_i) (0x0EC00 + ((_i) * 4)) /* EType Queue Select */ +#define IXGBE_SYNQF 0x0EC30 /* SYN Packet Queue Filter */ +#define IXGBE_RQTC 0x0EC70 +#define IXGBE_MTQC 0x08120 +#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */ +#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */ +#define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */ +#define IXGBE_PFFLPL 0x050B0 +#define IXGBE_PFFLPH 0x050B4 +#define IXGBE_VT_CTL 0x051B0 +#define IXGBE_PFMAILBOX(_i) (0x04B00 + (4 * (_i))) /* 64 total */ +/* 64 Mailboxes, 16 DW each */ +#define IXGBE_PFMBMEM(_i) (0x13000 + (64 * (_i))) +#define IXGBE_PFMBICR_INDEX(_i) ((_i) >> 4) +#define IXGBE_PFMBICR_SHIFT(_i) ((_i) % 16) +#define IXGBE_PFMBICR(_i) (0x00710 + (4 * (_i))) /* 4 total */ +#define IXGBE_PFMBIMR(_i) (0x00720 + (4 * (_i))) /* 4 total */ +#define IXGBE_PFVFLRE(_i) ((((_i) & 1) ? 0x001C0 : 0x00600)) +#define IXGBE_PFVFLREC(_i) (0x00700 + ((_i) * 4)) +#define IXGBE_PFVFLRE_INDEX(_i) ((_i) >> 5) +#define IXGBE_PFVFLRE_SHIFT(_i) ((_i) % 32) +#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4)) +#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4)) +#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4)) +#define IXGBE_QDE 0x2F04 +#define IXGBE_VMTXSW(_i) (0x05180 + ((_i) * 4)) /* 2 total */ +#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */ +#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4)) +#define IXGBE_MRCTL(_i) (0x0F600 + ((_i) * 4)) +#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4)) +#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4)) +#define IXGBE_LVMMC_RX 0x2FA8 +#define IXGBE_LVMMC_TX 0x8108 +#define IXGBE_LMVM_RX 0x2FA4 +#define IXGBE_LMVM_TX 0x8124 +#define IXGBE_WQBR_RX(_i) (0x2FB0 + ((_i) * 4)) /* 4 total */ +#define IXGBE_WQBR_TX(_i) (0x8130 + ((_i) * 4)) /* 4 total */ +#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/ +#define IXGBE_RXFECCERR0 0x051B8 +#define IXGBE_LLITHRESH 0x0EC90 +#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_IMIRVP 0x05AC0 +#define IXGBE_VMD_CTL 0x0581C +#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */ +#define IXGBE_ERETA(_i) (0x0EE80 + ((_i) * 4)) /* 96 of these (0-95) */ +#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */ + +/* Registers for setting up RSS on X550 with SRIOV + * _p - pool number (0..63) + * _i - index (0..10 for PFVFRSSRK, 0..15 for PFVFRETA) + */ +#define IXGBE_PFVFMRQC(_p) (0x03400 + ((_p) * 4)) +#define IXGBE_PFVFRSSRK(_i, _p) (0x018000 + ((_i) * 4) + ((_p) * 0x40)) +#define IXGBE_PFVFRETA(_i, _p) (0x019000 + ((_i) * 4) + ((_p) * 0x40)) + +/* Flow Director registers */ +#define IXGBE_FDIRCTRL 0x0EE00 +#define IXGBE_FDIRHKEY 0x0EE68 +#define IXGBE_FDIRSKEY 0x0EE6C +#define IXGBE_FDIRDIP4M 0x0EE3C +#define IXGBE_FDIRSIP4M 0x0EE40 +#define IXGBE_FDIRTCPM 0x0EE44 +#define IXGBE_FDIRUDPM 0x0EE48 +#define IXGBE_FDIRSCTPM 0x0EE78 +#define IXGBE_FDIRIP6M 0x0EE74 +#define IXGBE_FDIRM 0x0EE70 + +/* Flow Director Stats registers */ +#define IXGBE_FDIRFREE 0x0EE38 +#define IXGBE_FDIRLEN 0x0EE4C +#define IXGBE_FDIRUSTAT 0x0EE50 +#define IXGBE_FDIRFSTAT 0x0EE54 +#define IXGBE_FDIRMATCH 0x0EE58 +#define IXGBE_FDIRMISS 0x0EE5C + +/* Flow Director Programming registers */ +#define IXGBE_FDIRSIPv6(_i) (0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */ +#define IXGBE_FDIRIPSA 0x0EE18 +#define IXGBE_FDIRIPDA 0x0EE1C +#define IXGBE_FDIRPORT 0x0EE20 +#define IXGBE_FDIRVLAN 0x0EE24 +#define IXGBE_FDIRHASH 0x0EE28 +#define IXGBE_FDIRCMD 0x0EE2C + +/* Transmit DMA registers */ +#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of them (0-31)*/ +#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40)) +#define IXGBE_TDLEN(_i) (0x06008 + ((_i) * 0x40)) +#define IXGBE_TDH(_i) (0x06010 + ((_i) * 0x40)) +#define IXGBE_TDT(_i) (0x06018 + ((_i) * 0x40)) +#define IXGBE_TXDCTL(_i) (0x06028 + ((_i) * 0x40)) +#define IXGBE_TDWBAL(_i) (0x06038 + ((_i) * 0x40)) +#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40)) +#define IXGBE_DTXCTL 0x07E00 + +#define IXGBE_DMATXCTL 0x04A80 +#define IXGBE_PFVFSPOOF(_i) (0x08200 + ((_i) * 4)) /* 8 of these 0 - 7 */ +#define IXGBE_PFDTXGSWC 0x08220 +#define IXGBE_DTXMXSZRQ 0x08100 +#define IXGBE_DTXTCPFLGL 0x04A88 +#define IXGBE_DTXTCPFLGH 0x04A8C +#define IXGBE_LBDRPEN 0x0CA00 +#define IXGBE_TXPBTHRESH(_i) (0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */ + +#define IXGBE_DMATXCTL_TE 0x1 /* Transmit Enable */ +#define IXGBE_DMATXCTL_NS 0x2 /* No Snoop LSO hdr buffer */ +#define IXGBE_DMATXCTL_GDV 0x8 /* Global Double VLAN */ +#define IXGBE_DMATXCTL_MDP_EN 0x20 /* Bit 5 */ +#define IXGBE_DMATXCTL_MBINTEN 0x40 /* Bit 6 */ +#define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */ + +#define IXGBE_PFDTXGSWC_VT_LBEN 0x1 /* Local L2 VT switch enable */ + +/* Anti-spoofing defines */ +#define IXGBE_SPOOF_MACAS_MASK 0xFF +#define IXGBE_SPOOF_VLANAS_MASK 0xFF00 +#define IXGBE_SPOOF_VLANAS_SHIFT 8 +#define IXGBE_SPOOF_ETHERTYPEAS 0xFF000000 +#define IXGBE_SPOOF_ETHERTYPEAS_SHIFT 16 +#define IXGBE_PFVFSPOOF_REG_COUNT 8 +/* 16 of these (0-15) */ +#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) +/* Tx DCA Control register : 128 of these (0-127) */ +#define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40)) +#define IXGBE_TIPG 0x0CB00 +#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_MNGTXMAP 0x0CD10 +#define IXGBE_TIPG_FIBER_DEFAULT 3 +#define IXGBE_TXPBSIZE_SHIFT 10 + +/* Wake up registers */ +#define IXGBE_WUC 0x05800 +#define IXGBE_WUFC 0x05808 +#define IXGBE_WUS 0x05810 +#define IXGBE_IPAV 0x05838 +#define IXGBE_IP4AT 0x05840 /* IPv4 table 0x5840-0x5858 */ +#define IXGBE_IP6AT 0x05880 /* IPv6 table 0x5880-0x588F */ + +#define IXGBE_WUPL 0x05900 +#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */ +#define IXGBE_PROXYS 0x05F60 /* Proxying Status Register */ +#define IXGBE_PROXYFC 0x05F64 /* Proxying Filter Control Register */ +#define IXGBE_VXLANCTRL 0x0000507C /* Rx filter VXLAN UDPPORT Register */ + +/* masks for accessing VXLAN and GENEVE UDP ports */ +#define IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK 0x0000ffff /* VXLAN port */ +#define IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK 0xffff0000 /* GENEVE port */ +#define IXGBE_VXLANCTRL_ALL_UDPPORT_MASK 0xffffffff /* GENEVE/VXLAN */ +#define IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT 16 + +#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter table */ +/* Ext Flexible Host Filter Table */ +#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) +#define IXGBE_FHFT_EXT_X550(_n) (0x09600 + ((_n) * 0x100)) + +/* Four Flexible Filters are supported */ +#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4 +/* Six Flexible Filters are supported */ +#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_6 6 +/* Eight Flexible Filters are supported */ +#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_8 8 +#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2 + +/* Each Flexible Filter is at most 128 (0x80) bytes in length */ +#define IXGBE_FLEXIBLE_FILTER_SIZE_MAX 128 +#define IXGBE_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */ +#define IXGBE_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */ + +/* Definitions for power management and wakeup registers */ +/* Wake Up Control */ +#define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */ +#define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */ +#define IXGBE_WUC_WKEN 0x00000010 /* Enable PE_WAKE_N pin assertion */ + +/* Wake Up Filter Control */ +#define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ +#define IXGBE_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +#define IXGBE_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +#define IXGBE_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ +#define IXGBE_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ +#define IXGBE_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ +#define IXGBE_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ +#define IXGBE_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ +#define IXGBE_WUFC_MNG 0x00000100 /* Directed Mgmt Packet Wakeup Enable */ + +#define IXGBE_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */ +#define IXGBE_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ +#define IXGBE_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ +#define IXGBE_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ +#define IXGBE_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */ +#define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */ +#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */ +#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */ +#define IXGBE_WUFC_FLX_FILTERS_6 0x003F0000 /* Mask for 6 flex filters */ +#define IXGBE_WUFC_FLX_FILTERS_8 0x00FF0000 /* Mask for 8 flex filters */ +#define IXGBE_WUFC_FW_RST_WK 0x80000000 /* Ena wake on FW reset assertion */ +/* Mask for Ext. flex filters */ +#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 +#define IXGBE_WUFC_ALL_FILTERS 0x000F00FF /* Mask all 4 flex filters */ +#define IXGBE_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask all 6 flex filters */ +#define IXGBE_WUFC_ALL_FILTERS_8 0x00FF00FF /* Mask all 8 flex filters */ +#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */ + +/* Wake Up Status */ +#define IXGBE_WUS_LNKC IXGBE_WUFC_LNKC +#define IXGBE_WUS_MAG IXGBE_WUFC_MAG +#define IXGBE_WUS_EX IXGBE_WUFC_EX +#define IXGBE_WUS_MC IXGBE_WUFC_MC +#define IXGBE_WUS_BC IXGBE_WUFC_BC +#define IXGBE_WUS_ARP IXGBE_WUFC_ARP +#define IXGBE_WUS_IPV4 IXGBE_WUFC_IPV4 +#define IXGBE_WUS_IPV6 IXGBE_WUFC_IPV6 +#define IXGBE_WUS_MNG IXGBE_WUFC_MNG +#define IXGBE_WUS_FLX0 IXGBE_WUFC_FLX0 +#define IXGBE_WUS_FLX1 IXGBE_WUFC_FLX1 +#define IXGBE_WUS_FLX2 IXGBE_WUFC_FLX2 +#define IXGBE_WUS_FLX3 IXGBE_WUFC_FLX3 +#define IXGBE_WUS_FLX4 IXGBE_WUFC_FLX4 +#define IXGBE_WUS_FLX5 IXGBE_WUFC_FLX5 +#define IXGBE_WUS_FLX_FILTERS IXGBE_WUFC_FLX_FILTERS +#define IXGBE_WUS_FW_RST_WK IXGBE_WUFC_FW_RST_WK +/* Proxy Status */ +#define IXGBE_PROXYS_EX 0x00000004 /* Exact packet received */ +#define IXGBE_PROXYS_ARP_DIR 0x00000020 /* ARP w/filter match received */ +#define IXGBE_PROXYS_NS 0x00000200 /* IPV6 NS received */ +#define IXGBE_PROXYS_NS_DIR 0x00000400 /* IPV6 NS w/DA match received */ +#define IXGBE_PROXYS_ARP 0x00000800 /* ARP request packet received */ +#define IXGBE_PROXYS_MLD 0x00001000 /* IPv6 MLD packet received */ + +/* Proxying Filter Control */ +#define IXGBE_PROXYFC_ENABLE 0x00000001 /* Port Proxying Enable */ +#define IXGBE_PROXYFC_EX 0x00000004 /* Directed Exact Proxy Enable */ +#define IXGBE_PROXYFC_ARP_DIR 0x00000020 /* Directed ARP Proxy Enable */ +#define IXGBE_PROXYFC_NS 0x00000200 /* IPv6 Neighbor Solicitation */ +#define IXGBE_PROXYFC_ARP 0x00000800 /* ARP Request Proxy Enable */ +#define IXGBE_PROXYFC_MLD 0x00000800 /* IPv6 MLD Proxy Enable */ +#define IXGBE_PROXYFC_NO_TCO 0x00008000 /* Ignore TCO packets */ + +#define IXGBE_WUPL_LENGTH_MASK 0xFFFF + +/* DCB registers */ +#define IXGBE_DCB_MAX_TRAFFIC_CLASS 8 +#define IXGBE_RMCS 0x03D00 +#define IXGBE_DPMCS 0x07F40 +#define IXGBE_PDPMCS 0x0CD00 +#define IXGBE_RUPPBMR 0x050A0 +#define IXGBE_RT2CR(_i) (0x03C20 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RT2SR(_i) (0x03C40 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_TDTQ2TCCR(_i) (0x0602C + ((_i) * 0x40)) /* 8 of these (0-7) */ +#define IXGBE_TDTQ2TCSR(_i) (0x0622C + ((_i) * 0x40)) /* 8 of these (0-7) */ +#define IXGBE_TDPT2TCCR(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */ + +/* Power Management */ +/* DMA Coalescing configuration */ +struct ixgbe_dmac_config { + u16 watchdog_timer; /* usec units */ + bool fcoe_en; + u32 link_speed; + u8 fcoe_tc; + u8 num_tcs; +}; + +/* + * DMA Coalescing threshold Rx PB TC[n] value in Kilobyte by link speed. + * DMACRXT = 10Gbps = 10,000 bits / usec = 1250 bytes / usec 70 * 1250 == + * 87500 bytes [85KB] + */ +#define IXGBE_DMACRXT_10G 0x55 +#define IXGBE_DMACRXT_1G 0x09 +#define IXGBE_DMACRXT_100M 0x01 + +/* DMA Coalescing registers */ +#define IXGBE_DMCMNGTH 0x15F20 /* Management Threshold */ +#define IXGBE_DMACR 0x02400 /* Control register */ +#define IXGBE_DMCTH(_i) (0x03300 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_DMCTLX 0x02404 /* Time to Lx request */ +/* DMA Coalescing register fields */ +#define IXGBE_DMCMNGTH_DMCMNGTH_MASK 0x000FFFF0 /* Mng Threshold mask */ +#define IXGBE_DMCMNGTH_DMCMNGTH_SHIFT 4 /* Management Threshold shift */ +#define IXGBE_DMACR_DMACWT_MASK 0x0000FFFF /* Watchdog Timer mask */ +#define IXGBE_DMACR_HIGH_PRI_TC_MASK 0x00FF0000 +#define IXGBE_DMACR_HIGH_PRI_TC_SHIFT 16 +#define IXGBE_DMACR_EN_MNG_IND 0x10000000 /* Enable Mng Indications */ +#define IXGBE_DMACR_LX_COAL_IND 0x40000000 /* Lx Coalescing indicate */ +#define IXGBE_DMACR_DMAC_EN 0x80000000 /* DMA Coalescing Enable */ +#define IXGBE_DMCTH_DMACRXT_MASK 0x000001FF /* Receive Threshold mask */ +#define IXGBE_DMCTLX_TTLX_MASK 0x00000FFF /* Time to Lx request mask */ + +/* EEE registers */ +#define IXGBE_EEER 0x043A0 /* EEE register */ +#define IXGBE_EEE_STAT 0x04398 /* EEE Status */ +#define IXGBE_EEE_SU 0x04380 /* EEE Set up */ +#define IXGBE_EEE_SU_TEEE_DLY_SHIFT 26 +#define IXGBE_TLPIC 0x041F4 /* EEE Tx LPI count */ +#define IXGBE_RLPIC 0x041F8 /* EEE Rx LPI count */ + +/* EEE register fields */ +#define IXGBE_EEER_TX_LPI_EN 0x00010000 /* Enable EEE LPI TX path */ +#define IXGBE_EEER_RX_LPI_EN 0x00020000 /* Enable EEE LPI RX path */ +#define IXGBE_EEE_STAT_NEG 0x20000000 /* EEE support neg on link */ +#define IXGBE_EEE_RX_LPI_STATUS 0x40000000 /* RX Link in LPI status */ +#define IXGBE_EEE_TX_LPI_STATUS 0x80000000 /* TX Link in LPI status */ + +/* Security Control Registers */ +#define IXGBE_SECTXCTRL 0x08800 +#define IXGBE_SECTXSTAT 0x08804 +#define IXGBE_SECTXBUFFAF 0x08808 +#define IXGBE_SECTXMINIFG 0x08810 +#define IXGBE_SECRXCTRL 0x08D00 +#define IXGBE_SECRXSTAT 0x08D04 + +/* Security Bit Fields and Masks */ +#define IXGBE_SECTXCTRL_SECTX_DIS 0x00000001 +#define IXGBE_SECTXCTRL_TX_DIS 0x00000002 +#define IXGBE_SECTXCTRL_STORE_FORWARD 0x00000004 + +#define IXGBE_SECTXSTAT_SECTX_RDY 0x00000001 +#define IXGBE_SECTXSTAT_ECC_TXERR 0x00000002 + +#define IXGBE_SECRXCTRL_SECRX_DIS 0x00000001 +#define IXGBE_SECRXCTRL_RX_DIS 0x00000002 + +#define IXGBE_SECRXSTAT_SECRX_RDY 0x00000001 +#define IXGBE_SECRXSTAT_ECC_RXERR 0x00000002 + +/* LinkSec (MacSec) Registers */ +#define IXGBE_LSECTXCAP 0x08A00 +#define IXGBE_LSECRXCAP 0x08F00 +#define IXGBE_LSECTXCTRL 0x08A04 +#define IXGBE_LSECTXSCL 0x08A08 /* SCI Low */ +#define IXGBE_LSECTXSCH 0x08A0C /* SCI High */ +#define IXGBE_LSECTXSA 0x08A10 +#define IXGBE_LSECTXPN0 0x08A14 +#define IXGBE_LSECTXPN1 0x08A18 +#define IXGBE_LSECTXKEY0(_n) (0x08A1C + (4 * (_n))) /* 4 of these (0-3) */ +#define IXGBE_LSECTXKEY1(_n) (0x08A2C + (4 * (_n))) /* 4 of these (0-3) */ +#define IXGBE_LSECRXCTRL 0x08F04 +#define IXGBE_LSECRXSCL 0x08F08 +#define IXGBE_LSECRXSCH 0x08F0C +#define IXGBE_LSECRXSA(_i) (0x08F10 + (4 * (_i))) /* 2 of these (0-1) */ +#define IXGBE_LSECRXPN(_i) (0x08F18 + (4 * (_i))) /* 2 of these (0-1) */ +#define IXGBE_LSECRXKEY(_n, _m) (0x08F20 + ((0x10 * (_n)) + (4 * (_m)))) +#define IXGBE_LSECTXUT 0x08A3C /* OutPktsUntagged */ +#define IXGBE_LSECTXPKTE 0x08A40 /* OutPktsEncrypted */ +#define IXGBE_LSECTXPKTP 0x08A44 /* OutPktsProtected */ +#define IXGBE_LSECTXOCTE 0x08A48 /* OutOctetsEncrypted */ +#define IXGBE_LSECTXOCTP 0x08A4C /* OutOctetsProtected */ +#define IXGBE_LSECRXUT 0x08F40 /* InPktsUntagged/InPktsNoTag */ +#define IXGBE_LSECRXOCTD 0x08F44 /* InOctetsDecrypted */ +#define IXGBE_LSECRXOCTV 0x08F48 /* InOctetsValidated */ +#define IXGBE_LSECRXBAD 0x08F4C /* InPktsBadTag */ +#define IXGBE_LSECRXNOSCI 0x08F50 /* InPktsNoSci */ +#define IXGBE_LSECRXUNSCI 0x08F54 /* InPktsUnknownSci */ +#define IXGBE_LSECRXUNCH 0x08F58 /* InPktsUnchecked */ +#define IXGBE_LSECRXDELAY 0x08F5C /* InPktsDelayed */ +#define IXGBE_LSECRXLATE 0x08F60 /* InPktsLate */ +#define IXGBE_LSECRXOK(_n) (0x08F64 + (0x04 * (_n))) /* InPktsOk */ +#define IXGBE_LSECRXINV(_n) (0x08F6C + (0x04 * (_n))) /* InPktsInvalid */ +#define IXGBE_LSECRXNV(_n) (0x08F74 + (0x04 * (_n))) /* InPktsNotValid */ +#define IXGBE_LSECRXUNSA 0x08F7C /* InPktsUnusedSa */ +#define IXGBE_LSECRXNUSA 0x08F80 /* InPktsNotUsingSa */ + +/* LinkSec (MacSec) Bit Fields and Masks */ +#define IXGBE_LSECTXCAP_SUM_MASK 0x00FF0000 +#define IXGBE_LSECTXCAP_SUM_SHIFT 16 +#define IXGBE_LSECRXCAP_SUM_MASK 0x00FF0000 +#define IXGBE_LSECRXCAP_SUM_SHIFT 16 + +#define IXGBE_LSECTXCTRL_EN_MASK 0x00000003 +#define IXGBE_LSECTXCTRL_DISABLE 0x0 +#define IXGBE_LSECTXCTRL_AUTH 0x1 +#define IXGBE_LSECTXCTRL_AUTH_ENCRYPT 0x2 +#define IXGBE_LSECTXCTRL_AISCI 0x00000020 +#define IXGBE_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00 +#define IXGBE_LSECTXCTRL_RSV_MASK 0x000000D8 + +#define IXGBE_LSECRXCTRL_EN_MASK 0x0000000C +#define IXGBE_LSECRXCTRL_EN_SHIFT 2 +#define IXGBE_LSECRXCTRL_DISABLE 0x0 +#define IXGBE_LSECRXCTRL_CHECK 0x1 +#define IXGBE_LSECRXCTRL_STRICT 0x2 +#define IXGBE_LSECRXCTRL_DROP 0x3 +#define IXGBE_LSECRXCTRL_PLSH 0x00000040 +#define IXGBE_LSECRXCTRL_RP 0x00000080 +#define IXGBE_LSECRXCTRL_RSV_MASK 0xFFFFFF33 + +/* IpSec Registers */ +#define IXGBE_IPSTXIDX 0x08900 +#define IXGBE_IPSTXSALT 0x08904 +#define IXGBE_IPSTXKEY(_i) (0x08908 + (4 * (_i))) /* 4 of these (0-3) */ +#define IXGBE_IPSRXIDX 0x08E00 +#define IXGBE_IPSRXIPADDR(_i) (0x08E04 + (4 * (_i))) /* 4 of these (0-3) */ +#define IXGBE_IPSRXSPI 0x08E14 +#define IXGBE_IPSRXIPIDX 0x08E18 +#define IXGBE_IPSRXKEY(_i) (0x08E1C + (4 * (_i))) /* 4 of these (0-3) */ +#define IXGBE_IPSRXSALT 0x08E2C +#define IXGBE_IPSRXMOD 0x08E30 + +#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4 + +/* DCB registers */ +#define IXGBE_RTRPCS 0x02430 +#define IXGBE_RTTDCS 0x04900 +#define IXGBE_RTTDCS_ARBDIS 0x00000040 /* DCB arbiter disable */ +#define IXGBE_RTTPCS 0x0CD00 +#define IXGBE_RTRUP2TC 0x03020 +#define IXGBE_RTTUP2TC 0x0C800 +#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_TXLLQ(_i) (0x082E0 + ((_i) * 4)) /* 4 of these (0-3) */ +#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTPT2C(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTPT2S(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTDQSEL 0x04904 +#define IXGBE_RTTDT1C 0x04908 +#define IXGBE_RTTDT1S 0x0490C +#define IXGBE_RTTQCNCR 0x08B00 +#define IXGBE_RTTQCNTG 0x04A90 +#define IXGBE_RTTBCNRD 0x0498C +#define IXGBE_RTTQCNRR 0x0498C +#define IXGBE_RTTDTECC 0x04990 +#define IXGBE_RTTDTECC_NO_BCN 0x00000100 + +#define IXGBE_RTTBCNRC 0x04984 +#define IXGBE_RTTBCNRC_RS_ENA 0x80000000 +#define IXGBE_RTTBCNRC_RF_DEC_MASK 0x00003FFF +#define IXGBE_RTTBCNRC_RF_INT_SHIFT 14 +#define IXGBE_RTTBCNRC_RF_INT_MASK \ + (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT) +#define IXGBE_RTTBCNRM 0x04980 +#define IXGBE_RTTQCNRM 0x04980 + +/* FCoE DMA Context Registers */ +/* FCoE Direct DMA Context */ +#define IXGBE_FCDDC(_i, _j) (0x20000 + ((_i) * 0x4) + ((_j) * 0x10)) +#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ +#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */ +#define IXGBE_FCBUFF 0x02418 /* FC Buffer Control */ +#define IXGBE_FCDMARW 0x02420 /* FC Receive DMA RW */ +#define IXGBE_FCBUFF_VALID (1 << 0) /* DMA Context Valid */ +#define IXGBE_FCBUFF_BUFFSIZE (3 << 3) /* User Buffer Size */ +#define IXGBE_FCBUFF_WRCONTX (1 << 7) /* 0: Initiator, 1: Target */ +#define IXGBE_FCBUFF_BUFFCNT 0x0000ff00 /* Number of User Buffers */ +#define IXGBE_FCBUFF_OFFSET 0xffff0000 /* User Buffer Offset */ +#define IXGBE_FCBUFF_BUFFSIZE_SHIFT 3 +#define IXGBE_FCBUFF_BUFFCNT_SHIFT 8 +#define IXGBE_FCBUFF_OFFSET_SHIFT 16 +#define IXGBE_FCDMARW_WE (1 << 14) /* Write enable */ +#define IXGBE_FCDMARW_RE (1 << 15) /* Read enable */ +#define IXGBE_FCDMARW_FCOESEL 0x000001ff /* FC X_ID: 11 bits */ +#define IXGBE_FCDMARW_LASTSIZE 0xffff0000 /* Last User Buffer Size */ +#define IXGBE_FCDMARW_LASTSIZE_SHIFT 16 +/* FCoE SOF/EOF */ +#define IXGBE_TEOFF 0x04A94 /* Tx FC EOF */ +#define IXGBE_TSOFF 0x04A98 /* Tx FC SOF */ +#define IXGBE_REOFF 0x05158 /* Rx FC EOF */ +#define IXGBE_RSOFF 0x051F8 /* Rx FC SOF */ +/* FCoE Filter Context Registers */ +#define IXGBE_FCD_ID 0x05114 /* FCoE D_ID */ +#define IXGBE_FCSMAC 0x0510C /* FCoE Source MAC */ +#define IXGBE_FCFLTRW_SMAC_HIGH_SHIFT 16 +/* FCoE Direct Filter Context */ +#define IXGBE_FCDFC(_i, _j) (0x28000 + ((_i) * 0x4) + ((_j) * 0x10)) +#define IXGBE_FCDFCD(_i) (0x30000 + ((_i) * 0x4)) +#define IXGBE_FCFLT 0x05108 /* FC FLT Context */ +#define IXGBE_FCFLTRW 0x05110 /* FC Filter RW Control */ +#define IXGBE_FCPARAM 0x051d8 /* FC Offset Parameter */ +#define IXGBE_FCFLT_VALID (1 << 0) /* Filter Context Valid */ +#define IXGBE_FCFLT_FIRST (1 << 1) /* Filter First */ +#define IXGBE_FCFLT_SEQID 0x00ff0000 /* Sequence ID */ +#define IXGBE_FCFLT_SEQCNT 0xff000000 /* Sequence Count */ +#define IXGBE_FCFLTRW_RVALDT (1 << 13) /* Fast Re-Validation */ +#define IXGBE_FCFLTRW_WE (1 << 14) /* Write Enable */ +#define IXGBE_FCFLTRW_RE (1 << 15) /* Read Enable */ +/* FCoE Receive Control */ +#define IXGBE_FCRXCTRL 0x05100 /* FC Receive Control */ +#define IXGBE_FCRXCTRL_FCOELLI (1 << 0) /* Low latency interrupt */ +#define IXGBE_FCRXCTRL_SAVBAD (1 << 1) /* Save Bad Frames */ +#define IXGBE_FCRXCTRL_FRSTRDH (1 << 2) /* EN 1st Read Header */ +#define IXGBE_FCRXCTRL_LASTSEQH (1 << 3) /* EN Last Header in Seq */ +#define IXGBE_FCRXCTRL_ALLH (1 << 4) /* EN All Headers */ +#define IXGBE_FCRXCTRL_FRSTSEQH (1 << 5) /* EN 1st Seq. Header */ +#define IXGBE_FCRXCTRL_ICRC (1 << 6) /* Ignore Bad FC CRC */ +#define IXGBE_FCRXCTRL_FCCRCBO (1 << 7) /* FC CRC Byte Ordering */ +#define IXGBE_FCRXCTRL_FCOEVER 0x00000f00 /* FCoE Version: 4 bits */ +#define IXGBE_FCRXCTRL_FCOEVER_SHIFT 8 +/* FCoE Redirection */ +#define IXGBE_FCRECTL 0x0ED00 /* FC Redirection Control */ +#define IXGBE_FCRETA0 0x0ED10 /* FC Redirection Table 0 */ +#define IXGBE_FCRETA(_i) (IXGBE_FCRETA0 + ((_i) * 4)) /* FCoE Redir */ +#define IXGBE_FCRECTL_ENA 0x1 /* FCoE Redir Table Enable */ +#define IXGBE_FCRETASEL_ENA 0x2 /* FCoE FCRETASEL bit */ +#define IXGBE_FCRETA_SIZE 8 /* Max entries in FCRETA */ +#define IXGBE_FCRETA_ENTRY_MASK 0x0000007f /* 7 bits for the queue index */ +#define IXGBE_FCRETA_SIZE_X550 32 /* Max entries in FCRETA */ +/* Higher 7 bits for the queue index */ +#define IXGBE_FCRETA_ENTRY_HIGH_MASK 0x007F0000 +#define IXGBE_FCRETA_ENTRY_HIGH_SHIFT 16 + +/* Stats registers */ +#define IXGBE_CRCERRS 0x04000 +#define IXGBE_ILLERRC 0x04004 +#define IXGBE_ERRBC 0x04008 +#define IXGBE_MSPDC 0x04010 +#define IXGBE_MPC(_i) (0x03FA0 + ((_i) * 4)) /* 8 of these 3FA0-3FBC*/ +#define IXGBE_MLFC 0x04034 +#define IXGBE_MRFC 0x04038 +#define IXGBE_RLEC 0x04040 +#define IXGBE_LXONTXC 0x03F60 +#define IXGBE_LXONRXC 0x0CF60 +#define IXGBE_LXOFFTXC 0x03F68 +#define IXGBE_LXOFFRXC 0x0CF68 +#define IXGBE_LXONRXCNT 0x041A4 +#define IXGBE_LXOFFRXCNT 0x041A8 +#define IXGBE_PXONRXCNT(_i) (0x04140 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_PXOFFRXCNT(_i) (0x04160 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_PXON2OFFCNT(_i) (0x03240 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_PXONTXC(_i) (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C*/ +#define IXGBE_PXONRXC(_i) (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C*/ +#define IXGBE_PXOFFTXC(_i) (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C*/ +#define IXGBE_PXOFFRXC(_i) (0x0CF20 + ((_i) * 4)) /* 8 of these CF20-CF3C*/ +#define IXGBE_PRC64 0x0405C +#define IXGBE_PRC127 0x04060 +#define IXGBE_PRC255 0x04064 +#define IXGBE_PRC511 0x04068 +#define IXGBE_PRC1023 0x0406C +#define IXGBE_PRC1522 0x04070 +#define IXGBE_GPRC 0x04074 +#define IXGBE_BPRC 0x04078 +#define IXGBE_MPRC 0x0407C +#define IXGBE_GPTC 0x04080 +#define IXGBE_GORCL 0x04088 +#define IXGBE_GORCH 0x0408C +#define IXGBE_GOTCL 0x04090 +#define IXGBE_GOTCH 0x04094 +#define IXGBE_RNBC(_i) (0x03FC0 + ((_i) * 4)) /* 8 of these 3FC0-3FDC*/ +#define IXGBE_RUC 0x040A4 +#define IXGBE_RFC 0x040A8 +#define IXGBE_ROC 0x040AC +#define IXGBE_RJC 0x040B0 +#define IXGBE_MNGPRC 0x040B4 +#define IXGBE_MNGPDC 0x040B8 +#define IXGBE_MNGPTC 0x0CF90 +#define IXGBE_TORL 0x040C0 +#define IXGBE_TORH 0x040C4 +#define IXGBE_TPR 0x040D0 +#define IXGBE_TPT 0x040D4 +#define IXGBE_PTC64 0x040D8 +#define IXGBE_PTC127 0x040DC +#define IXGBE_PTC255 0x040E0 +#define IXGBE_PTC511 0x040E4 +#define IXGBE_PTC1023 0x040E8 +#define IXGBE_PTC1522 0x040EC +#define IXGBE_MPTC 0x040F0 +#define IXGBE_BPTC 0x040F4 +#define IXGBE_XEC 0x04120 +#define IXGBE_SSVPC 0x08780 + +#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) +#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : \ + (0x08600 + ((_i) * 4))) +#define IXGBE_TQSM(_i) (0x08600 + ((_i) * 4)) + +#define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC_L(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC_H(_i) (0x01038 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */ +#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */ +#define IXGBE_FCCRC 0x05118 /* Num of Good Eth CRC w/ Bad FC CRC */ +#define IXGBE_FCOERPDC 0x0241C /* FCoE Rx Packets Dropped Count */ +#define IXGBE_FCLAST 0x02424 /* FCoE Last Error Count */ +#define IXGBE_FCOEPRC 0x02428 /* Number of FCoE Packets Received */ +#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */ +#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */ +#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */ +#define IXGBE_FCCRC_CNT_MASK 0x0000FFFF /* CRC_CNT: bit 0 - 15 */ +#define IXGBE_FCLAST_CNT_MASK 0x0000FFFF /* Last_CNT: bit 0 - 15 */ +#define IXGBE_O2BGPTC 0x041C4 +#define IXGBE_O2BSPC 0x087B0 +#define IXGBE_B2OSPC 0x041C0 +#define IXGBE_B2OGPRC 0x02F90 +#define IXGBE_BUPRC 0x04180 +#define IXGBE_BMPRC 0x04184 +#define IXGBE_BBPRC 0x04188 +#define IXGBE_BUPTC 0x0418C +#define IXGBE_BMPTC 0x04190 +#define IXGBE_BBPTC 0x04194 +#define IXGBE_BCRCERRS 0x04198 +#define IXGBE_BXONRXC 0x0419C +#define IXGBE_BXOFFRXC 0x041E0 +#define IXGBE_BXONTXC 0x041E4 +#define IXGBE_BXOFFTXC 0x041E8 + +/* Management */ +#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_MFUTP(_i) (0x05030 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_MANC 0x05820 +#define IXGBE_MFVAL 0x05824 +#define IXGBE_MANC2H 0x05860 +#define IXGBE_MDEF(_i) (0x05890 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_MIPAF 0x058B0 +#define IXGBE_MMAL(_i) (0x05910 + ((_i) * 8)) /* 4 of these (0-3) */ +#define IXGBE_MMAH(_i) (0x05914 + ((_i) * 8)) /* 4 of these (0-3) */ +#define IXGBE_FTFT 0x09400 /* 0x9400-0x97FC */ +#define IXGBE_METF(_i) (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */ +#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_LSWFW 0x15F14 +#define IXGBE_BMCIP(_i) (0x05050 + ((_i) * 4)) /* 0x5050-0x505C */ +#define IXGBE_BMCIPVAL 0x05060 +#define IXGBE_BMCIP_IPADDR_TYPE 0x00000001 +#define IXGBE_BMCIP_IPADDR_VALID 0x00000002 + +/* Management Bit Fields and Masks */ +#define IXGBE_MANC_MPROXYE 0x40000000 /* Management Proxy Enable */ +#define IXGBE_MANC_RCV_TCO_EN 0x00020000 /* Rcv TCO packet enable */ +#define IXGBE_MANC_EN_BMC2OS 0x10000000 /* Ena BMC2OS and OS2BMC traffic */ +#define IXGBE_MANC_EN_BMC2OS_SHIFT 28 + +/* Firmware Semaphore Register */ +#define IXGBE_FWSM_MODE_MASK 0xE +#define IXGBE_FWSM_TS_ENABLED 0x1 +#define IXGBE_FWSM_FW_MODE_PT 0x4 +#define IXGBE_FWSM_FW_NVM_RECOVERY_MODE (1 << 5) +#define IXGBE_FWSM_EXT_ERR_IND_MASK 0x01F80000 +#define IXGBE_FWSM_FW_VAL_BIT (1 << 15) + +/* ARC Subsystem registers */ +#define IXGBE_HICR 0x15F00 +#define IXGBE_FWSTS 0x15F0C +#define IXGBE_HSMC0R 0x15F04 +#define IXGBE_HSMC1R 0x15F08 +#define IXGBE_SWSR 0x15F10 +#define IXGBE_FWRESETCNT 0x15F40 +#define IXGBE_HFDR 0x15FE8 +#define IXGBE_FLEX_MNG 0x15800 /* 0x15800 - 0x15EFC */ +#define IXGBE_FLEX_MNG_PTR(_i) (IXGBE_FLEX_MNG + ((_i) * 4)) + +#define IXGBE_HICR_EN 0x01 /* Enable bit - RO */ +/* Driver sets this bit when done to put command in RAM */ +#define IXGBE_HICR_C 0x02 +#define IXGBE_HICR_SV 0x04 /* Status Validity */ +#define IXGBE_HICR_FW_RESET_ENABLE 0x40 +#define IXGBE_HICR_FW_RESET 0x80 + +/* PCI-E registers */ +#define IXGBE_GCR 0x11000 +#define IXGBE_GTV 0x11004 +#define IXGBE_FUNCTAG 0x11008 +#define IXGBE_GLT 0x1100C +#define IXGBE_PCIEPIPEADR 0x11004 +#define IXGBE_PCIEPIPEDAT 0x11008 +#define IXGBE_GSCL_1 0x11010 +#define IXGBE_GSCL_2 0x11014 +#define IXGBE_GSCL_1_X540 IXGBE_GSCL_1 +#define IXGBE_GSCL_2_X540 IXGBE_GSCL_2 +#define IXGBE_GSCL_3 0x11018 +#define IXGBE_GSCL_4 0x1101C +#define IXGBE_GSCN_0 0x11020 +#define IXGBE_GSCN_1 0x11024 +#define IXGBE_GSCN_2 0x11028 +#define IXGBE_GSCN_3 0x1102C +#define IXGBE_GSCN_0_X540 IXGBE_GSCN_0 +#define IXGBE_GSCN_1_X540 IXGBE_GSCN_1 +#define IXGBE_GSCN_2_X540 IXGBE_GSCN_2 +#define IXGBE_GSCN_3_X540 IXGBE_GSCN_3 +#define IXGBE_FACTPS 0x10150 +#define IXGBE_FACTPS_X540 IXGBE_FACTPS +#define IXGBE_GSCL_1_X550 0x11800 +#define IXGBE_GSCL_2_X550 0x11804 +#define IXGBE_GSCL_1_X550EM_x IXGBE_GSCL_1_X550 +#define IXGBE_GSCL_2_X550EM_x IXGBE_GSCL_2_X550 +#define IXGBE_GSCN_0_X550 0x11820 +#define IXGBE_GSCN_1_X550 0x11824 +#define IXGBE_GSCN_2_X550 0x11828 +#define IXGBE_GSCN_3_X550 0x1182C +#define IXGBE_GSCN_0_X550EM_x IXGBE_GSCN_0_X550 +#define IXGBE_GSCN_1_X550EM_x IXGBE_GSCN_1_X550 +#define IXGBE_GSCN_2_X550EM_x IXGBE_GSCN_2_X550 +#define IXGBE_GSCN_3_X550EM_x IXGBE_GSCN_3_X550 +#define IXGBE_FACTPS_X550 IXGBE_FACTPS +#define IXGBE_FACTPS_X550EM_x IXGBE_FACTPS +#define IXGBE_GSCL_1_X550EM_a IXGBE_GSCL_1_X550 +#define IXGBE_GSCL_2_X550EM_a IXGBE_GSCL_2_X550 +#define IXGBE_GSCN_0_X550EM_a IXGBE_GSCN_0_X550 +#define IXGBE_GSCN_1_X550EM_a IXGBE_GSCN_1_X550 +#define IXGBE_GSCN_2_X550EM_a IXGBE_GSCN_2_X550 +#define IXGBE_GSCN_3_X550EM_a IXGBE_GSCN_3_X550 +#define IXGBE_FACTPS_X550EM_a 0x15FEC +#define IXGBE_FACTPS_BY_MAC(_hw) IXGBE_BY_MAC((_hw), FACTPS) + +#define IXGBE_PCIEANACTL 0x11040 +#define IXGBE_SWSM 0x10140 +#define IXGBE_SWSM_X540 IXGBE_SWSM +#define IXGBE_SWSM_X550 IXGBE_SWSM +#define IXGBE_SWSM_X550EM_x IXGBE_SWSM +#define IXGBE_SWSM_X550EM_a 0x15F70 +#define IXGBE_SWSM_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SWSM) + +#define IXGBE_FWSM 0x10148 +#define IXGBE_FWSM_X540 IXGBE_FWSM +#define IXGBE_FWSM_X550 IXGBE_FWSM +#define IXGBE_FWSM_X550EM_x IXGBE_FWSM +#define IXGBE_FWSM_X550EM_a 0x15F74 +#define IXGBE_FWSM_BY_MAC(_hw) IXGBE_BY_MAC((_hw), FWSM) + +#define IXGBE_SWFW_SYNC IXGBE_GSSR +#define IXGBE_SWFW_SYNC_X540 IXGBE_SWFW_SYNC +#define IXGBE_SWFW_SYNC_X550 IXGBE_SWFW_SYNC +#define IXGBE_SWFW_SYNC_X550EM_x IXGBE_SWFW_SYNC +#define IXGBE_SWFW_SYNC_X550EM_a 0x15F78 +#define IXGBE_SWFW_SYNC_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SWFW_SYNC) + +#define IXGBE_GSSR 0x10160 +#define IXGBE_MREVID 0x11064 +#define IXGBE_DCA_ID 0x11070 +#define IXGBE_DCA_CTRL 0x11074 + +/* PCI-E registers 82599-Specific */ +#define IXGBE_GCR_EXT 0x11050 +#define IXGBE_GSCL_5_82599 0x11030 +#define IXGBE_GSCL_6_82599 0x11034 +#define IXGBE_GSCL_7_82599 0x11038 +#define IXGBE_GSCL_8_82599 0x1103C +#define IXGBE_GSCL_5_X540 IXGBE_GSCL_5_82599 +#define IXGBE_GSCL_6_X540 IXGBE_GSCL_6_82599 +#define IXGBE_GSCL_7_X540 IXGBE_GSCL_7_82599 +#define IXGBE_GSCL_8_X540 IXGBE_GSCL_8_82599 +#define IXGBE_PHYADR_82599 0x11040 +#define IXGBE_PHYDAT_82599 0x11044 +#define IXGBE_PHYCTL_82599 0x11048 +#define IXGBE_PBACLR_82599 0x11068 +#define IXGBE_CIAA 0x11088 +#define IXGBE_CIAD 0x1108C +#define IXGBE_CIAA_82599 IXGBE_CIAA +#define IXGBE_CIAD_82599 IXGBE_CIAD +#define IXGBE_CIAA_X540 IXGBE_CIAA +#define IXGBE_CIAD_X540 IXGBE_CIAD +#define IXGBE_GSCL_5_X550 0x11810 +#define IXGBE_GSCL_6_X550 0x11814 +#define IXGBE_GSCL_7_X550 0x11818 +#define IXGBE_GSCL_8_X550 0x1181C +#define IXGBE_GSCL_5_X550EM_x IXGBE_GSCL_5_X550 +#define IXGBE_GSCL_6_X550EM_x IXGBE_GSCL_6_X550 +#define IXGBE_GSCL_7_X550EM_x IXGBE_GSCL_7_X550 +#define IXGBE_GSCL_8_X550EM_x IXGBE_GSCL_8_X550 +#define IXGBE_CIAA_X550 0x11508 +#define IXGBE_CIAD_X550 0x11510 +#define IXGBE_CIAA_X550EM_x IXGBE_CIAA_X550 +#define IXGBE_CIAD_X550EM_x IXGBE_CIAD_X550 +#define IXGBE_GSCL_5_X550EM_a IXGBE_GSCL_5_X550 +#define IXGBE_GSCL_6_X550EM_a IXGBE_GSCL_6_X550 +#define IXGBE_GSCL_7_X550EM_a IXGBE_GSCL_7_X550 +#define IXGBE_GSCL_8_X550EM_a IXGBE_GSCL_8_X550 +#define IXGBE_CIAA_X550EM_a IXGBE_CIAA_X550 +#define IXGBE_CIAD_X550EM_a IXGBE_CIAD_X550 +#define IXGBE_CIAA_BY_MAC(_hw) IXGBE_BY_MAC((_hw), CIAA) +#define IXGBE_CIAD_BY_MAC(_hw) IXGBE_BY_MAC((_hw), CIAD) +#define IXGBE_PICAUSE 0x110B0 +#define IXGBE_PIENA 0x110B8 +#define IXGBE_CDQ_MBR_82599 0x110B4 +#define IXGBE_PCIESPARE 0x110BC +#define IXGBE_MISC_REG_82599 0x110F0 +#define IXGBE_ECC_CTRL_0_82599 0x11100 +#define IXGBE_ECC_CTRL_1_82599 0x11104 +#define IXGBE_ECC_STATUS_82599 0x110E0 +#define IXGBE_BAR_CTRL_82599 0x110F4 + +/* PCI Express Control */ +#define IXGBE_GCR_CMPL_TMOUT_MASK 0x0000F000 +#define IXGBE_GCR_CMPL_TMOUT_10ms 0x00001000 +#define IXGBE_GCR_CMPL_TMOUT_RESEND 0x00010000 +#define IXGBE_GCR_CAP_VER2 0x00040000 + +#define IXGBE_GCR_EXT_MSIX_EN 0x80000000 +#define IXGBE_GCR_EXT_BUFFERS_CLEAR 0x40000000 +#define IXGBE_GCR_EXT_VT_MODE_16 0x00000001 +#define IXGBE_GCR_EXT_VT_MODE_32 0x00000002 +#define IXGBE_GCR_EXT_VT_MODE_64 0x00000003 +#define IXGBE_GCR_EXT_SRIOV (IXGBE_GCR_EXT_MSIX_EN | \ + IXGBE_GCR_EXT_VT_MODE_64) +#define IXGBE_GCR_EXT_VT_MODE_MASK 0x00000003 +/* Time Sync Registers */ +#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */ +#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */ +#define IXGBE_RXSTMPL 0x051E8 /* Rx timestamp Low - RO */ +#define IXGBE_RXSTMPH 0x051A4 /* Rx timestamp High - RO */ +#define IXGBE_RXSATRL 0x051A0 /* Rx timestamp attribute low - RO */ +#define IXGBE_RXSATRH 0x051A8 /* Rx timestamp attribute high - RO */ +#define IXGBE_RXMTRL 0x05120 /* RX message type register low - RW */ +#define IXGBE_TXSTMPL 0x08C04 /* Tx timestamp value Low - RO */ +#define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */ +#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */ +#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */ +#define IXGBE_SYSTIMR 0x08C58 /* System time register Residue - RO */ +#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */ +#define IXGBE_TIMADJL 0x08C18 /* Time Adjustment Offset register Low - RW */ +#define IXGBE_TIMADJH 0x08C1C /* Time Adjustment Offset register High - RW */ +#define IXGBE_TSAUXC 0x08C20 /* TimeSync Auxiliary Control register - RW */ +#define IXGBE_TRGTTIML0 0x08C24 /* Target Time Register 0 Low - RW */ +#define IXGBE_TRGTTIMH0 0x08C28 /* Target Time Register 0 High - RW */ +#define IXGBE_TRGTTIML1 0x08C2C /* Target Time Register 1 Low - RW */ +#define IXGBE_TRGTTIMH1 0x08C30 /* Target Time Register 1 High - RW */ +#define IXGBE_CLKTIML 0x08C34 /* Clock Out Time Register Low - RW */ +#define IXGBE_CLKTIMH 0x08C38 /* Clock Out Time Register High - RW */ +#define IXGBE_FREQOUT0 0x08C34 /* Frequency Out 0 Control register - RW */ +#define IXGBE_FREQOUT1 0x08C38 /* Frequency Out 1 Control register - RW */ +#define IXGBE_AUXSTMPL0 0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */ +#define IXGBE_AUXSTMPH0 0x08C40 /* Auxiliary Time Stamp 0 register High - RO */ +#define IXGBE_AUXSTMPL1 0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */ +#define IXGBE_AUXSTMPH1 0x08C48 /* Auxiliary Time Stamp 1 register High - RO */ +#define IXGBE_TSIM 0x08C68 /* TimeSync Interrupt Mask Register - RW */ +#define IXGBE_TSICR 0x08C60 /* TimeSync Interrupt Cause Register - WO */ +#define IXGBE_TSSDP 0x0003C /* TimeSync SDP Configuration Register - RW */ + +/* Diagnostic Registers */ +#define IXGBE_RDSTATCTL 0x02C20 +#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */ +#define IXGBE_RDHMPN 0x02F08 +#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4)) +#define IXGBE_RDPROBE 0x02F20 +#define IXGBE_RDMAM 0x02F30 +#define IXGBE_RDMAD 0x02F34 +#define IXGBE_TDHMPN 0x07F08 +#define IXGBE_TDHMPN2 0x082FC +#define IXGBE_TXDESCIC 0x082CC +#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4)) +#define IXGBE_TIC_DW2(_i) (0x082B0 + ((_i) * 4)) +#define IXGBE_TDPROBE 0x07F20 +#define IXGBE_TXBUFCTRL 0x0C600 +#define IXGBE_TXBUFDATA0 0x0C610 +#define IXGBE_TXBUFDATA1 0x0C614 +#define IXGBE_TXBUFDATA2 0x0C618 +#define IXGBE_TXBUFDATA3 0x0C61C +#define IXGBE_RXBUFCTRL 0x03600 +#define IXGBE_RXBUFDATA0 0x03610 +#define IXGBE_RXBUFDATA1 0x03614 +#define IXGBE_RXBUFDATA2 0x03618 +#define IXGBE_RXBUFDATA3 0x0361C +#define IXGBE_PCIE_DIAG(_i) (0x11090 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_RFVAL 0x050A4 +#define IXGBE_MDFTC1 0x042B8 +#define IXGBE_MDFTC2 0x042C0 +#define IXGBE_MDFTFIFO1 0x042C4 +#define IXGBE_MDFTFIFO2 0x042C8 +#define IXGBE_MDFTS 0x042CC +#define IXGBE_RXDATAWRPTR(_i) (0x03700 + ((_i) * 4)) /* 8 of these 3700-370C*/ +#define IXGBE_RXDESCWRPTR(_i) (0x03710 + ((_i) * 4)) /* 8 of these 3710-371C*/ +#define IXGBE_RXDATARDPTR(_i) (0x03720 + ((_i) * 4)) /* 8 of these 3720-372C*/ +#define IXGBE_RXDESCRDPTR(_i) (0x03730 + ((_i) * 4)) /* 8 of these 3730-373C*/ +#define IXGBE_TXDATAWRPTR(_i) (0x0C700 + ((_i) * 4)) /* 8 of these C700-C70C*/ +#define IXGBE_TXDESCWRPTR(_i) (0x0C710 + ((_i) * 4)) /* 8 of these C710-C71C*/ +#define IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/ +#define IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/ +#define IXGBE_PCIEECCCTL 0x1106C +#define IXGBE_RXWRPTR(_i) (0x03100 + ((_i) * 4)) /* 8 of these 3100-310C*/ +#define IXGBE_RXUSED(_i) (0x03120 + ((_i) * 4)) /* 8 of these 3120-312C*/ +#define IXGBE_RXRDPTR(_i) (0x03140 + ((_i) * 4)) /* 8 of these 3140-314C*/ +#define IXGBE_RXRDWRPTR(_i) (0x03160 + ((_i) * 4)) /* 8 of these 3160-310C*/ +#define IXGBE_TXWRPTR(_i) (0x0C100 + ((_i) * 4)) /* 8 of these C100-C10C*/ +#define IXGBE_TXUSED(_i) (0x0C120 + ((_i) * 4)) /* 8 of these C120-C12C*/ +#define IXGBE_TXRDPTR(_i) (0x0C140 + ((_i) * 4)) /* 8 of these C140-C14C*/ +#define IXGBE_TXRDWRPTR(_i) (0x0C160 + ((_i) * 4)) /* 8 of these C160-C10C*/ +#define IXGBE_PCIEECCCTL0 0x11100 +#define IXGBE_PCIEECCCTL1 0x11104 +#define IXGBE_RXDBUECC 0x03F70 +#define IXGBE_TXDBUECC 0x0CF70 +#define IXGBE_RXDBUEST 0x03F74 +#define IXGBE_TXDBUEST 0x0CF74 +#define IXGBE_PBTXECC 0x0C300 +#define IXGBE_PBRXECC 0x03300 +#define IXGBE_GHECCR 0x110B0 + +/* MAC Registers */ +#define IXGBE_PCS1GCFIG 0x04200 +#define IXGBE_PCS1GLCTL 0x04208 +#define IXGBE_PCS1GLSTA 0x0420C +#define IXGBE_PCS1GDBG0 0x04210 +#define IXGBE_PCS1GDBG1 0x04214 +#define IXGBE_PCS1GANA 0x04218 +#define IXGBE_PCS1GANLP 0x0421C +#define IXGBE_PCS1GANNP 0x04220 +#define IXGBE_PCS1GANLPNP 0x04224 +#define IXGBE_HLREG0 0x04240 +#define IXGBE_HLREG1 0x04244 +#define IXGBE_PAP 0x04248 +#define IXGBE_MACA 0x0424C +#define IXGBE_APAE 0x04250 +#define IXGBE_ARD 0x04254 +#define IXGBE_AIS 0x04258 +#define IXGBE_MSCA 0x0425C +#define IXGBE_MSRWD 0x04260 +#define IXGBE_MLADD 0x04264 +#define IXGBE_MHADD 0x04268 +#define IXGBE_MAXFRS 0x04268 +#define IXGBE_TREG 0x0426C +#define IXGBE_PCSS1 0x04288 +#define IXGBE_PCSS2 0x0428C +#define IXGBE_XPCSS 0x04290 +#define IXGBE_MFLCN 0x04294 +#define IXGBE_SERDESC 0x04298 +#define IXGBE_MAC_SGMII_BUSY 0x04298 +#define IXGBE_MACS 0x0429C +#define IXGBE_AUTOC 0x042A0 +#define IXGBE_LINKS 0x042A4 +#define IXGBE_LINKS2 0x04324 +#define IXGBE_AUTOC2 0x042A8 +#define IXGBE_AUTOC3 0x042AC +#define IXGBE_ANLP1 0x042B0 +#define IXGBE_ANLP2 0x042B4 +#define IXGBE_MACC 0x04330 +#define IXGBE_ATLASCTL 0x04800 +#define IXGBE_MMNGC 0x042D0 +#define IXGBE_ANLPNP1 0x042D4 +#define IXGBE_ANLPNP2 0x042D8 +#define IXGBE_KRPCSFC 0x042E0 +#define IXGBE_KRPCSS 0x042E4 +#define IXGBE_FECS1 0x042E8 +#define IXGBE_FECS2 0x042EC +#define IXGBE_SMADARCTL 0x14F10 +#define IXGBE_MPVC 0x04318 +#define IXGBE_SGMIIC 0x04314 + +/* Statistics Registers */ +#define IXGBE_RXNFGPC 0x041B0 +#define IXGBE_RXNFGBCL 0x041B4 +#define IXGBE_RXNFGBCH 0x041B8 +#define IXGBE_RXDGPC 0x02F50 +#define IXGBE_RXDGBCL 0x02F54 +#define IXGBE_RXDGBCH 0x02F58 +#define IXGBE_RXDDGPC 0x02F5C +#define IXGBE_RXDDGBCL 0x02F60 +#define IXGBE_RXDDGBCH 0x02F64 +#define IXGBE_RXLPBKGPC 0x02F68 +#define IXGBE_RXLPBKGBCL 0x02F6C +#define IXGBE_RXLPBKGBCH 0x02F70 +#define IXGBE_RXDLPBKGPC 0x02F74 +#define IXGBE_RXDLPBKGBCL 0x02F78 +#define IXGBE_RXDLPBKGBCH 0x02F7C +#define IXGBE_TXDGPC 0x087A0 +#define IXGBE_TXDGBCL 0x087A4 +#define IXGBE_TXDGBCH 0x087A8 + +#define IXGBE_RXDSTATCTRL 0x02F40 + +/* Copper Pond 2 link timeout */ +#define IXGBE_VALIDATE_LINK_READY_TIMEOUT 50 + +/* Omer CORECTL */ +#define IXGBE_CORECTL 0x014F00 +/* BARCTRL */ +#define IXGBE_BARCTRL 0x110F4 +#define IXGBE_BARCTRL_FLSIZE 0x0700 +#define IXGBE_BARCTRL_FLSIZE_SHIFT 8 +#define IXGBE_BARCTRL_CSRSIZE 0x2000 +#define IXGBE_BARCTRL_CSRSIZE_SHIFT 13 + +/* RSCCTL Bit Masks */ +#define IXGBE_RSCCTL_RSCEN 0x01 +#define IXGBE_RSCCTL_MAXDESC_1 0x00 +#define IXGBE_RSCCTL_MAXDESC_4 0x04 +#define IXGBE_RSCCTL_MAXDESC_8 0x08 +#define IXGBE_RSCCTL_MAXDESC_16 0x0C +#define IXGBE_RSCCTL_TS_DIS 0x02 + +/* RSCDBU Bit Masks */ +#define IXGBE_RSCDBU_RSCSMALDIS_MASK 0x0000007F +#define IXGBE_RSCDBU_RSCACKDIS 0x00000080 + +/* RDRXCTL Bit Masks */ +#define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min THLD Size */ +#define IXGBE_RDRXCTL_CRCSTRIP 0x00000002 /* CRC Strip */ +#define IXGBE_RDRXCTL_PSP 0x00000004 /* Pad Small Packet */ +#define IXGBE_RDRXCTL_MVMEN 0x00000020 +#define IXGBE_RDRXCTL_RSC_PUSH_DIS 0x00000020 +#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */ +#define IXGBE_RDRXCTL_RSC_PUSH 0x00000080 +#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */ +#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */ +#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI*/ +#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC ena */ +#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC ena */ +#define IXGBE_RDRXCTL_MBINTEN 0x10000000 +#define IXGBE_RDRXCTL_MDP_EN 0x20000000 + +/* RQTC Bit Masks and Shifts */ +#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4) +#define IXGBE_RQTC_TC0_MASK (0x7 << 0) +#define IXGBE_RQTC_TC1_MASK (0x7 << 4) +#define IXGBE_RQTC_TC2_MASK (0x7 << 8) +#define IXGBE_RQTC_TC3_MASK (0x7 << 12) +#define IXGBE_RQTC_TC4_MASK (0x7 << 16) +#define IXGBE_RQTC_TC5_MASK (0x7 << 20) +#define IXGBE_RQTC_TC6_MASK (0x7 << 24) +#define IXGBE_RQTC_TC7_MASK (0x7 << 28) + +/* PSRTYPE.RQPL Bit masks and shift */ +#define IXGBE_PSRTYPE_RQPL_MASK 0x7 +#define IXGBE_PSRTYPE_RQPL_SHIFT 29 + +/* CTRL Bit Masks */ +#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Primary Disable bit */ +#define IXGBE_CTRL_LNK_RST 0x00000008 /* Link Reset. Resets everything. */ +#define IXGBE_CTRL_RST 0x04000000 /* Reset (SW) */ +#define IXGBE_CTRL_RST_MASK (IXGBE_CTRL_LNK_RST | IXGBE_CTRL_RST) + +/* FACTPS */ +#define IXGBE_FACTPS_MNGCG 0x20000000 /* Manageblility Clock Gated */ +#define IXGBE_FACTPS_LFS 0x40000000 /* LAN Function Select */ + +/* MHADD Bit Masks */ +#define IXGBE_MHADD_MFS_MASK 0xFFFF0000 +#define IXGBE_MHADD_MFS_SHIFT 16 + +/* Extended Device Control */ +#define IXGBE_CTRL_EXT_PFRSTD 0x00004000 /* Physical Function Reset Done */ +#define IXGBE_CTRL_EXT_NS_DIS 0x00010000 /* No Snoop disable */ +#define IXGBE_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ +#define IXGBE_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ + +/* Direct Cache Access (DCA) definitions */ +#define IXGBE_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */ +#define IXGBE_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */ + +#define IXGBE_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */ +#define IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */ + +#define IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */ +#define IXGBE_DCA_RXCTRL_CPUID_MASK_82599 0xFF000000 /* Rx CPUID Mask */ +#define IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */ +#define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* Rx Desc enable */ +#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* Rx Desc header ena */ +#define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* Rx Desc payload ena */ +#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* Rx rd Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DATA_WRO_EN (1 << 13) /* Rx wr data Relax Order */ +#define IXGBE_DCA_RXCTRL_HEAD_WRO_EN (1 << 15) /* Rx wr header RO */ + +#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ +#define IXGBE_DCA_TXCTRL_CPUID_MASK_82599 0xFF000000 /* Tx CPUID Mask */ +#define IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */ +#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ +#define IXGBE_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */ +#define IXGBE_DCA_TXCTRL_DESC_WRO_EN (1 << 11) /* Tx Desc writeback RO bit */ +#define IXGBE_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */ +#define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */ + +/* MSCA Bit Masks */ +#define IXGBE_MSCA_NP_ADDR_MASK 0x0000FFFF /* MDI Addr (new prot) */ +#define IXGBE_MSCA_NP_ADDR_SHIFT 0 +#define IXGBE_MSCA_DEV_TYPE_MASK 0x001F0000 /* Dev Type (new prot) */ +#define IXGBE_MSCA_DEV_TYPE_SHIFT 16 /* Register Address (old prot */ +#define IXGBE_MSCA_PHY_ADDR_MASK 0x03E00000 /* PHY Address mask */ +#define IXGBE_MSCA_PHY_ADDR_SHIFT 21 /* PHY Address shift*/ +#define IXGBE_MSCA_OP_CODE_MASK 0x0C000000 /* OP CODE mask */ +#define IXGBE_MSCA_OP_CODE_SHIFT 26 /* OP CODE shift */ +#define IXGBE_MSCA_ADDR_CYCLE 0x00000000 /* OP CODE 00 (addr cycle) */ +#define IXGBE_MSCA_WRITE 0x04000000 /* OP CODE 01 (wr) */ +#define IXGBE_MSCA_READ 0x0C000000 /* OP CODE 11 (rd) */ +#define IXGBE_MSCA_READ_AUTOINC 0x08000000 /* OP CODE 10 (rd auto inc)*/ +#define IXGBE_MSCA_ST_CODE_MASK 0x30000000 /* ST Code mask */ +#define IXGBE_MSCA_ST_CODE_SHIFT 28 /* ST Code shift */ +#define IXGBE_MSCA_NEW_PROTOCOL 0x00000000 /* ST CODE 00 (new prot) */ +#define IXGBE_MSCA_OLD_PROTOCOL 0x10000000 /* ST CODE 01 (old prot) */ +#define IXGBE_MSCA_MDI_COMMAND 0x40000000 /* Initiate MDI command */ +#define IXGBE_MSCA_MDI_IN_PROG_EN 0x80000000 /* MDI in progress ena */ + +/* MSRWD bit masks */ +#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF +#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0 +#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000 +#define IXGBE_MSRWD_READ_DATA_SHIFT 16 + +/* Atlas registers */ +#define IXGBE_ATLAS_PDN_LPBK 0x24 +#define IXGBE_ATLAS_PDN_10G 0xB +#define IXGBE_ATLAS_PDN_1G 0xC +#define IXGBE_ATLAS_PDN_AN 0xD + +/* Atlas bit masks */ +#define IXGBE_ATLASCTL_WRITE_CMD 0x00010000 +#define IXGBE_ATLAS_PDN_TX_REG_EN 0x10 +#define IXGBE_ATLAS_PDN_TX_10G_QL_ALL 0xF0 +#define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0 +#define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0 + +/* Omer bit masks */ +#define IXGBE_CORECTL_WRITE_CMD 0x00010000 + +/* Device Type definitions for new protocol MDIO commands */ +#define IXGBE_MDIO_ZERO_DEV_TYPE 0x0 +#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1 +#define IXGBE_MDIO_PCS_DEV_TYPE 0x3 +#define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4 +#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7 +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */ +#define IXGBE_TWINAX_DEV 1 + +#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */ + +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL 0x0 /* VS1 Ctrl Reg */ +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS 0x1 /* VS1 Status Reg */ +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS 0x0008 /* 1 = Link Up */ +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS 0x0010 /* 0-10G, 1-1G */ +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_10G_SPEED 0x0018 +#define IXGBE_MDIO_VENDOR_SPECIFIC_1_1G_SPEED 0x0010 + +#define IXGBE_MDIO_AUTO_NEG_CONTROL 0x0 /* AUTO_NEG Control Reg */ +#define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STAT 0xC800 /* AUTO_NEG Vendor Status Reg */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM 0xCC00 /* AUTO_NEG Vendor TX Reg */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2 0xCC01 /* AUTO_NEG Vendor Tx Reg */ +#define IXGBE_MDIO_AUTO_NEG_VEN_LSC 0x1 /* AUTO_NEG Vendor Tx LSC */ +#define IXGBE_MDIO_AUTO_NEG_ADVT 0x10 /* AUTO_NEG Advt Reg */ +#define IXGBE_MDIO_AUTO_NEG_LP 0x13 /* AUTO_NEG LP Status Reg */ +#define IXGBE_MDIO_AUTO_NEG_EEE_ADVT 0x3C /* AUTO_NEG EEE Advt Reg */ +#define IXGBE_AUTO_NEG_10GBASE_EEE_ADVT 0x8 /* AUTO NEG EEE 10GBaseT Advt */ +#define IXGBE_AUTO_NEG_1000BASE_EEE_ADVT 0x4 /* AUTO NEG EEE 1000BaseT Advt */ +#define IXGBE_AUTO_NEG_100BASE_EEE_ADVT 0x2 /* AUTO NEG EEE 100BaseT Advt */ +#define IXGBE_MDIO_PHY_XS_CONTROL 0x0 /* PHY_XS Control Reg */ +#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */ +#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/ +#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/ +#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */ +#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */ +#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */ +#define IXGBE_MDIO_PHY_SPEED_100M 0x0020 /* 100M capable */ +#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */ +#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */ +#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */ +#define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */ +#define IXGBE_MDIO_PHY_SET_LOW_POWER_MODE 0x0800 /* Set low power mode */ +#define IXGBE_AUTO_NEG_LP_STATUS 0xE820 /* AUTO NEG Rx LP Status Reg */ +#define IXGBE_AUTO_NEG_LP_1000BASE_CAP 0x8000 /* AUTO NEG Rx LP 1000BaseT Cap */ +#define IXGBE_AUTO_NEG_LP_10GBASE_CAP 0x0800 /* AUTO NEG Rx LP 10GBaseT Cap */ +#define IXGBE_AUTO_NEG_10GBASET_STAT 0x0021 /* AUTO NEG 10G BaseT Stat */ + +#define IXGBE_MDIO_TX_VENDOR_ALARMS_3 0xCC02 /* Vendor Alarms 3 Reg */ +#define IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK 0x3 /* PHY Reset Complete Mask */ +#define IXGBE_MDIO_GLOBAL_RES_PR_10 0xC479 /* Global Resv Provisioning 10 Reg */ +#define IXGBE_MDIO_POWER_UP_STALL 0x8000 /* Power Up Stall */ +#define IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK 0xFF00 /* int std mask */ +#define IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG 0xFC00 /* chip std int flag */ +#define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK 0xFF01 /* int chip-wide mask */ +#define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG 0xFC01 /* int chip-wide mask */ +#define IXGBE_MDIO_GLOBAL_ALARM_1 0xCC00 /* Global alarm 1 */ +#define IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT 0x0010 /* device fault */ +#define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL 0x4000 /* high temp failure */ +#define IXGBE_MDIO_GLOBAL_FAULT_MSG 0xC850 /* Global Fault Message */ +#define IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP 0x8007 /* high temp failure */ +#define IXGBE_MDIO_GLOBAL_INT_MASK 0xD400 /* Global int mask */ +#define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN 0x1000 /* autoneg vendor alarm int enable */ +#define IXGBE_MDIO_GLOBAL_ALARM_1_INT 0x4 /* int in Global alarm 1 */ +#define IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN 0x1 /* vendor alarm int enable */ +#define IXGBE_MDIO_GLOBAL_STD_ALM2_INT 0x200 /* vendor alarm2 int mask */ +#define IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN 0x4000 /* int high temp enable */ +#define IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN 0x0010 /* int dev fault enable */ +#define IXGBE_MDIO_PMA_PMD_CONTROL_ADDR 0x0000 /* PMA/PMD Control Reg */ +#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ +#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ +#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */ +#define IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK 0xD401 /* PHY TX Vendor LASI */ +#define IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN 0x1 /* PHY TX Vendor LASI enable */ +#define IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR 0x9 /* Standard Transmit Dis Reg */ +#define IXGBE_MDIO_PMD_GLOBAL_TX_DISABLE 0x0001 /* PMD Global Transmit Dis */ + +#define IXGBE_PCRC8ECL 0x0E810 /* PCR CRC-8 Error Count Lo */ +#define IXGBE_PCRC8ECH 0x0E811 /* PCR CRC-8 Error Count Hi */ +#define IXGBE_PCRC8ECH_MASK 0x1F +#define IXGBE_LDPCECL 0x0E820 /* PCR Uncorrected Error Count Lo */ +#define IXGBE_LDPCECH 0x0E821 /* PCR Uncorrected Error Count Hi */ + +/* MII clause 22/28 definitions */ +#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800 + +#define IXGBE_MDIO_XENPAK_LASI_STATUS 0x9005 /* XENPAK LASI Status register*/ +#define IXGBE_XENPAK_LASI_LINK_STATUS_ALARM 0x1 /* Link Status Alarm change */ + +#define IXGBE_MDIO_AUTO_NEG_LINK_STATUS 0x4 /* Indicates if link is up */ + +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK 0x7 /* Speed/Duplex Mask */ +#define IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK 0x6 /* Speed Mask */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10M_HALF 0x0 /* 10Mb/s Half Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10M_FULL 0x1 /* 10Mb/s Full Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_100M_HALF 0x2 /* 100Mb/s Half Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_100M_FULL 0x3 /* 100Mb/s Full Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_HALF 0x4 /* 1Gb/s Half Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL 0x5 /* 1Gb/s Full Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_HALF 0x6 /* 10Gb/s Half Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL 0x7 /* 10Gb/s Full Duplex */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB 0x4 /* 1Gb/s */ +#define IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB 0x6 /* 10Gb/s */ + +#define IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG 0x20 /* 10G Control Reg */ +#define IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG 0xC400 /* 1G Provisioning 1 */ +#define IXGBE_MII_AUTONEG_XNP_TX_REG 0x17 /* 1G XNP Transmit */ +#define IXGBE_MII_AUTONEG_ADVERTISE_REG 0x10 /* 100M Advertisement */ +#define IXGBE_MII_10GBASE_T_ADVERTISE 0x1000 /* full duplex, bit:12*/ +#define IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX 0x4000 /* full duplex, bit:14*/ +#define IXGBE_MII_1GBASE_T_ADVERTISE 0x8000 /* full duplex, bit:15*/ +#define IXGBE_MII_2_5GBASE_T_ADVERTISE 0x0400 +#define IXGBE_MII_5GBASE_T_ADVERTISE 0x0800 +#define IXGBE_MII_100BASE_T_ADVERTISE 0x0100 /* full duplex, bit:8 */ +#define IXGBE_MII_100BASE_T_ADVERTISE_HALF 0x0080 /* half duplex, bit:7 */ +#define IXGBE_MII_RESTART 0x200 +#define IXGBE_MII_AUTONEG_COMPLETE 0x20 +#define IXGBE_MII_AUTONEG_LINK_UP 0x04 +#define IXGBE_MII_AUTONEG_REG 0x0 + +#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0 +#define IXGBE_MAX_PHY_ADDR 32 + +/* PHY IDs*/ +#define TN1010_PHY_ID 0x00A19410 +#define TNX_FW_REV 0xB +#define X540_PHY_ID 0x01540200 +#define X550_PHY_ID 0x01540220 +#define X550_PHY_ID2 0x01540223 +#define X550_PHY_ID3 0x01540221 +#define X557_PHY_ID 0x01540240 +#define X557_PHY_ID2 0x01540250 +#define AQ_FW_REV 0x20 +#define QT2022_PHY_ID 0x0043A400 +#define ATH_PHY_ID 0x03429050 + +/* PHY Types */ +#define IXGBE_M88E1500_E_PHY_ID 0x01410DD0 +#define IXGBE_M88E1543_E_PHY_ID 0x01410EA0 + +/* Special PHY Init Routine */ +#define IXGBE_PHY_INIT_OFFSET_NL 0x002B +#define IXGBE_PHY_INIT_END_NL 0xFFFF +#define IXGBE_CONTROL_MASK_NL 0xF000 +#define IXGBE_DATA_MASK_NL 0x0FFF +#define IXGBE_CONTROL_SHIFT_NL 12 +#define IXGBE_DELAY_NL 0 +#define IXGBE_DATA_NL 1 +#define IXGBE_CONTROL_NL 0x000F +#define IXGBE_CONTROL_EOL_NL 0x0FFF +#define IXGBE_CONTROL_SOL_NL 0x0000 + +/* General purpose Interrupt Enable */ +#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */ +#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */ +#define IXGBE_SDP2_GPIEN 0x00000004 /* SDP2 */ +#define IXGBE_SDP0_GPIEN_X540 0x00000002 /* SDP0 on X540 and X550 */ +#define IXGBE_SDP1_GPIEN_X540 0x00000004 /* SDP1 on X540 and X550 */ +#define IXGBE_SDP2_GPIEN_X540 0x00000008 /* SDP2 on X540 and X550 */ +#define IXGBE_SDP0_GPIEN_X550 IXGBE_SDP0_GPIEN_X540 +#define IXGBE_SDP1_GPIEN_X550 IXGBE_SDP1_GPIEN_X540 +#define IXGBE_SDP2_GPIEN_X550 IXGBE_SDP2_GPIEN_X540 +#define IXGBE_SDP0_GPIEN_X550EM_x IXGBE_SDP0_GPIEN_X540 +#define IXGBE_SDP1_GPIEN_X550EM_x IXGBE_SDP1_GPIEN_X540 +#define IXGBE_SDP2_GPIEN_X550EM_x IXGBE_SDP2_GPIEN_X540 +#define IXGBE_SDP0_GPIEN_X550EM_a IXGBE_SDP0_GPIEN_X540 +#define IXGBE_SDP1_GPIEN_X550EM_a IXGBE_SDP1_GPIEN_X540 +#define IXGBE_SDP2_GPIEN_X550EM_a IXGBE_SDP2_GPIEN_X540 +#define IXGBE_SDP0_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP0_GPIEN) +#define IXGBE_SDP1_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP1_GPIEN) +#define IXGBE_SDP2_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP2_GPIEN) + +#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */ +#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */ +#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */ +#define IXGBE_GPIE_EIAME 0x40000000 +#define IXGBE_GPIE_PBA_SUPPORT 0x80000000 +#define IXGBE_GPIE_RSC_DELAY_SHIFT 11 +#define IXGBE_GPIE_VTMODE_MASK 0x0000C000 /* VT Mode Mask */ +#define IXGBE_GPIE_VTMODE_16 0x00004000 /* 16 VFs 8 queues per VF */ +#define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */ +#define IXGBE_GPIE_VTMODE_64 0x0000C000 /* 64 VFs 2 queues per VF */ + +/* Packet Buffer Initialization */ +#define IXGBE_MAX_PACKET_BUFFERS 8 + +#define IXGBE_TXPBSIZE_20KB 0x00005000 /* 20KB Packet Buffer */ +#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */ +#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */ +#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */ +#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */ +#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */ +#define IXGBE_RXPBSIZE_MAX 0x00080000 /* 512KB Packet Buffer */ +#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer */ + +#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */ +#define IXGBE_MAX_PB 8 + +/* Packet buffer allocation strategies */ +enum { + PBA_STRATEGY_EQUAL = 0, /* Distribute PB space equally */ +#define PBA_STRATEGY_EQUAL PBA_STRATEGY_EQUAL + PBA_STRATEGY_WEIGHTED = 1, /* Weight front half of TCs */ +#define PBA_STRATEGY_WEIGHTED PBA_STRATEGY_WEIGHTED +}; + +/* Transmit Flow Control status */ +#define IXGBE_TFCS_TXOFF 0x00000001 +#define IXGBE_TFCS_TXOFF0 0x00000100 +#define IXGBE_TFCS_TXOFF1 0x00000200 +#define IXGBE_TFCS_TXOFF2 0x00000400 +#define IXGBE_TFCS_TXOFF3 0x00000800 +#define IXGBE_TFCS_TXOFF4 0x00001000 +#define IXGBE_TFCS_TXOFF5 0x00002000 +#define IXGBE_TFCS_TXOFF6 0x00004000 +#define IXGBE_TFCS_TXOFF7 0x00008000 + +/* TCP Timer */ +#define IXGBE_TCPTIMER_KS 0x00000100 +#define IXGBE_TCPTIMER_COUNT_ENABLE 0x00000200 +#define IXGBE_TCPTIMER_COUNT_FINISH 0x00000400 +#define IXGBE_TCPTIMER_LOOP 0x00000800 +#define IXGBE_TCPTIMER_DURATION_MASK 0x000000FF + +/* HLREG0 Bit Masks */ +#define IXGBE_HLREG0_TXCRCEN 0x00000001 /* bit 0 */ +#define IXGBE_HLREG0_RXCRCSTRP 0x00000002 /* bit 1 */ +#define IXGBE_HLREG0_JUMBOEN 0x00000004 /* bit 2 */ +#define IXGBE_HLREG0_TXPADEN 0x00000400 /* bit 10 */ +#define IXGBE_HLREG0_TXPAUSEEN 0x00001000 /* bit 12 */ +#define IXGBE_HLREG0_RXPAUSEEN 0x00004000 /* bit 14 */ +#define IXGBE_HLREG0_LPBK 0x00008000 /* bit 15 */ +#define IXGBE_HLREG0_MDCSPD 0x00010000 /* bit 16 */ +#define IXGBE_HLREG0_CONTMDC 0x00020000 /* bit 17 */ +#define IXGBE_HLREG0_CTRLFLTR 0x00040000 /* bit 18 */ +#define IXGBE_HLREG0_PREPEND 0x00F00000 /* bits 20-23 */ +#define IXGBE_HLREG0_PRIPAUSEEN 0x01000000 /* bit 24 */ +#define IXGBE_HLREG0_RXPAUSERECDA 0x06000000 /* bits 25-26 */ +#define IXGBE_HLREG0_RXLNGTHERREN 0x08000000 /* bit 27 */ +#define IXGBE_HLREG0_RXPADSTRIPEN 0x10000000 /* bit 28 */ + +/* VMD_CTL bitmasks */ +#define IXGBE_VMD_CTL_VMDQ_EN 0x00000001 +#define IXGBE_VMD_CTL_VMDQ_FILTER 0x00000002 + +/* VT_CTL bitmasks */ +#define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */ +#define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */ +#define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */ +#define IXGBE_VT_CTL_POOL_SHIFT 7 +#define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT) + +/* VMOLR bitmasks */ +#define IXGBE_VMOLR_UPE 0x00400000 /* unicast promiscuous */ +#define IXGBE_VMOLR_VPE 0x00800000 /* VLAN promiscuous */ +#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */ +#define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */ +#define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */ +#define IXGBE_VMOLR_BAM 0x08000000 /* accept broadcast packets */ +#define IXGBE_VMOLR_MPE 0x10000000 /* multicast promiscuous */ + +/* VFRE bitmask */ +#define IXGBE_VFRE_ENABLE_ALL 0xFFFFFFFF + +#define IXGBE_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ + +/* RDHMPN and TDHMPN bitmasks */ +#define IXGBE_RDHMPN_RDICADDR 0x007FF800 +#define IXGBE_RDHMPN_RDICRDREQ 0x00800000 +#define IXGBE_RDHMPN_RDICADDR_SHIFT 11 +#define IXGBE_TDHMPN_TDICADDR 0x003FF800 +#define IXGBE_TDHMPN_TDICRDREQ 0x00800000 +#define IXGBE_TDHMPN_TDICADDR_SHIFT 11 + +#define IXGBE_RDMAM_MEM_SEL_SHIFT 13 +#define IXGBE_RDMAM_DWORD_SHIFT 9 +#define IXGBE_RDMAM_DESC_COMP_FIFO 1 +#define IXGBE_RDMAM_DFC_CMD_FIFO 2 +#define IXGBE_RDMAM_RSC_HEADER_ADDR 3 +#define IXGBE_RDMAM_TCN_STATUS_RAM 4 +#define IXGBE_RDMAM_WB_COLL_FIFO 5 +#define IXGBE_RDMAM_QSC_CNT_RAM 6 +#define IXGBE_RDMAM_QSC_FCOE_RAM 7 +#define IXGBE_RDMAM_QSC_QUEUE_CNT 8 +#define IXGBE_RDMAM_QSC_QUEUE_RAM 0xA +#define IXGBE_RDMAM_QSC_RSC_RAM 0xB +#define IXGBE_RDMAM_DESC_COM_FIFO_RANGE 135 +#define IXGBE_RDMAM_DESC_COM_FIFO_COUNT 4 +#define IXGBE_RDMAM_DFC_CMD_FIFO_RANGE 48 +#define IXGBE_RDMAM_DFC_CMD_FIFO_COUNT 7 +#define IXGBE_RDMAM_RSC_HEADER_ADDR_RANGE 32 +#define IXGBE_RDMAM_RSC_HEADER_ADDR_COUNT 4 +#define IXGBE_RDMAM_TCN_STATUS_RAM_RANGE 256 +#define IXGBE_RDMAM_TCN_STATUS_RAM_COUNT 9 +#define IXGBE_RDMAM_WB_COLL_FIFO_RANGE 8 +#define IXGBE_RDMAM_WB_COLL_FIFO_COUNT 4 +#define IXGBE_RDMAM_QSC_CNT_RAM_RANGE 64 +#define IXGBE_RDMAM_QSC_CNT_RAM_COUNT 4 +#define IXGBE_RDMAM_QSC_FCOE_RAM_RANGE 512 +#define IXGBE_RDMAM_QSC_FCOE_RAM_COUNT 5 +#define IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE 32 +#define IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT 4 +#define IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE 128 +#define IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT 8 +#define IXGBE_RDMAM_QSC_RSC_RAM_RANGE 32 +#define IXGBE_RDMAM_QSC_RSC_RAM_COUNT 8 + +#define IXGBE_TXDESCIC_READY 0x80000000 + +/* Receive Checksum Control */ +#define IXGBE_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ +#define IXGBE_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ + +/* FCRTL Bit Masks */ +#define IXGBE_FCRTL_XONE 0x80000000 /* XON enable */ +#define IXGBE_FCRTH_FCEN 0x80000000 /* Packet buffer fc enable */ + +/* PAP bit masks*/ +#define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */ + +/* RMCS Bit Masks */ +#define IXGBE_RMCS_RRM 0x00000002 /* Rx Recycle Mode enable */ +/* Receive Arbitration Control: 0 Round Robin, 1 DFP */ +#define IXGBE_RMCS_RAC 0x00000004 +/* Deficit Fixed Prio ena */ +#define IXGBE_RMCS_DFP IXGBE_RMCS_RAC +#define IXGBE_RMCS_TFCE_802_3X 0x00000008 /* Tx Priority FC ena */ +#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority FC ena */ +#define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */ + +/* FCCFG Bit Masks */ +#define IXGBE_FCCFG_TFCE_802_3X 0x00000008 /* Tx link FC enable */ +#define IXGBE_FCCFG_TFCE_PRIORITY 0x00000010 /* Tx priority FC enable */ + +/* Interrupt register bitmasks */ + +/* Extended Interrupt Cause Read */ +#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */ +#define IXGBE_EICR_FLOW_DIR 0x00010000 /* FDir Exception */ +#define IXGBE_EICR_RX_MISS 0x00020000 /* Packet Buffer Overrun */ +#define IXGBE_EICR_PCI 0x00040000 /* PCI Exception */ +#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */ +#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */ +#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */ +#define IXGBE_EICR_FW_EVENT 0x00200000 /* Async FW event */ +#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */ +#define IXGBE_EICR_TS 0x00800000 /* Thermal Sensor Event */ +#define IXGBE_EICR_TIMESYNC 0x01000000 /* Timesync Event */ +#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */ +#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */ +#define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */ +#define IXGBE_EICR_ECC 0x10000000 /* ECC Error */ +#define IXGBE_EICR_GPI_SDP0_X540 0x02000000 /* Gen Purpose Interrupt on SDP0 */ +#define IXGBE_EICR_GPI_SDP1_X540 0x04000000 /* Gen Purpose Interrupt on SDP1 */ +#define IXGBE_EICR_GPI_SDP2_X540 0x08000000 /* Gen Purpose Interrupt on SDP2 */ +#define IXGBE_EICR_GPI_SDP0_X550 IXGBE_EICR_GPI_SDP0_X540 +#define IXGBE_EICR_GPI_SDP1_X550 IXGBE_EICR_GPI_SDP1_X540 +#define IXGBE_EICR_GPI_SDP2_X550 IXGBE_EICR_GPI_SDP2_X540 +#define IXGBE_EICR_GPI_SDP0_X550EM_x IXGBE_EICR_GPI_SDP0_X540 +#define IXGBE_EICR_GPI_SDP1_X550EM_x IXGBE_EICR_GPI_SDP1_X540 +#define IXGBE_EICR_GPI_SDP2_X550EM_x IXGBE_EICR_GPI_SDP2_X540 +#define IXGBE_EICR_GPI_SDP0_X550EM_a IXGBE_EICR_GPI_SDP0_X540 +#define IXGBE_EICR_GPI_SDP1_X550EM_a IXGBE_EICR_GPI_SDP1_X540 +#define IXGBE_EICR_GPI_SDP2_X550EM_a IXGBE_EICR_GPI_SDP2_X540 +#define IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP0) +#define IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP1) +#define IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP2) + +#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */ +#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */ +#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */ +#define IXGBE_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ + +/* Extended Interrupt Cause Set */ +#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EICS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */ +#define IXGBE_EICS_RX_MISS IXGBE_EICR_RX_MISS /* Pkt Buffer Overrun */ +#define IXGBE_EICS_PCI IXGBE_EICR_PCI /* PCI Exception */ +#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ +#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */ +#define IXGBE_EICS_FW_EVENT IXGBE_EICR_FW_EVENT /* Async FW event */ +#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ +#define IXGBE_EICS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ +#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ +#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ +#define IXGBE_EICS_ECC IXGBE_EICR_ECC /* ECC Error */ +#define IXGBE_EICS_GPI_SDP0_BY_MAC(_hw) IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) +#define IXGBE_EICS_GPI_SDP1_BY_MAC(_hw) IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) +#define IXGBE_EICS_GPI_SDP2_BY_MAC(_hw) IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) +#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ +#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */ +#define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ +#define IXGBE_EICS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ + +/* Extended Interrupt Mask Set */ +#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EIMS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */ +#define IXGBE_EIMS_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */ +#define IXGBE_EIMS_PCI IXGBE_EICR_PCI /* PCI Exception */ +#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ +#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */ +#define IXGBE_EIMS_FW_EVENT IXGBE_EICR_FW_EVENT /* Async FW event */ +#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ +#define IXGBE_EIMS_TS IXGBE_EICR_TS /* Thermal Sensor Event */ +#define IXGBE_EIMS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ +#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ +#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ +#define IXGBE_EIMS_ECC IXGBE_EICR_ECC /* ECC Error */ +#define IXGBE_EIMS_GPI_SDP0_BY_MAC(_hw) IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) +#define IXGBE_EIMS_GPI_SDP1_BY_MAC(_hw) IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) +#define IXGBE_EIMS_GPI_SDP2_BY_MAC(_hw) IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) +#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ +#define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */ +#define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ +#define IXGBE_EIMS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ + +/* Extended Interrupt Mask Clear */ +#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EIMC_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */ +#define IXGBE_EIMC_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */ +#define IXGBE_EIMC_PCI IXGBE_EICR_PCI /* PCI Exception */ +#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ +#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */ +#define IXGBE_EIMC_FW_EVENT IXGBE_EICR_FW_EVENT /* Async FW event */ +#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ +#define IXGBE_EIMC_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ +#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ +#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ +#define IXGBE_EIMC_ECC IXGBE_EICR_ECC /* ECC Error */ +#define IXGBE_EIMC_GPI_SDP0_BY_MAC(_hw) IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) +#define IXGBE_EIMC_GPI_SDP1_BY_MAC(_hw) IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) +#define IXGBE_EIMC_GPI_SDP2_BY_MAC(_hw) IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) +#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ +#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */ +#define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ +#define IXGBE_EIMC_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ + +#define IXGBE_EIMS_ENABLE_MASK ( \ + IXGBE_EIMS_RTX_QUEUE | \ + IXGBE_EIMS_LSC | \ + IXGBE_EIMS_TCP_TIMER | \ + IXGBE_EIMS_OTHER) + +/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */ +#define IXGBE_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */ +#define IXGBE_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */ +#define IXGBE_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */ +#define IXGBE_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */ +#define IXGBE_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */ +#define IXGBE_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */ +#define IXGBE_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */ +#define IXGBE_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */ +#define IXGBE_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */ +#define IXGBE_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */ +#define IXGBE_IMIR_SIZE_BP_82599 0x00001000 /* Packet size bypass */ +#define IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */ +#define IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */ +#define IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */ +#define IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */ +#define IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */ +#define IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */ +#define IXGBE_IMIR_CTRL_BP_82599 0x00080000 /* Bypass chk of ctrl bits */ +#define IXGBE_IMIR_LLI_EN_82599 0x00100000 /* Enables low latency Int */ +#define IXGBE_IMIR_RX_QUEUE_MASK_82599 0x0000007F /* Rx Queue Mask */ +#define IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */ +#define IXGBE_IMIRVP_PRIORITY_MASK 0x00000007 /* VLAN priority mask */ +#define IXGBE_IMIRVP_PRIORITY_EN 0x00000008 /* VLAN priority enable */ + +#define IXGBE_MAX_FTQF_FILTERS 128 +#define IXGBE_FTQF_PROTOCOL_MASK 0x00000003 +#define IXGBE_FTQF_PROTOCOL_TCP 0x00000000 +#define IXGBE_FTQF_PROTOCOL_UDP 0x00000001 +#define IXGBE_FTQF_PROTOCOL_SCTP 2 +#define IXGBE_FTQF_PRIORITY_MASK 0x00000007 +#define IXGBE_FTQF_PRIORITY_SHIFT 2 +#define IXGBE_FTQF_POOL_MASK 0x0000003F +#define IXGBE_FTQF_POOL_SHIFT 8 +#define IXGBE_FTQF_5TUPLE_MASK_MASK 0x0000001F +#define IXGBE_FTQF_5TUPLE_MASK_SHIFT 25 +#define IXGBE_FTQF_SOURCE_ADDR_MASK 0x1E +#define IXGBE_FTQF_DEST_ADDR_MASK 0x1D +#define IXGBE_FTQF_SOURCE_PORT_MASK 0x1B +#define IXGBE_FTQF_DEST_PORT_MASK 0x17 +#define IXGBE_FTQF_PROTOCOL_COMP_MASK 0x0F +#define IXGBE_FTQF_POOL_MASK_EN 0x40000000 +#define IXGBE_FTQF_QUEUE_ENABLE 0x80000000 + +/* Interrupt clear mask */ +#define IXGBE_IRQ_CLEAR_MASK 0xFFFFFFFF + +/* Interrupt Vector Allocation Registers */ +#define IXGBE_IVAR_REG_NUM 25 +#define IXGBE_IVAR_REG_NUM_82599 64 +#define IXGBE_IVAR_TXRX_ENTRY 96 +#define IXGBE_IVAR_RX_ENTRY 64 +#define IXGBE_IVAR_RX_QUEUE(_i) (0 + (_i)) +#define IXGBE_IVAR_TX_QUEUE(_i) (64 + (_i)) +#define IXGBE_IVAR_TX_ENTRY 32 + +#define IXGBE_IVAR_TCP_TIMER_INDEX 96 /* 0 based index */ +#define IXGBE_IVAR_OTHER_CAUSES_INDEX 97 /* 0 based index */ + +#define IXGBE_MSIX_VECTOR(_i) (0 + (_i)) + +#define IXGBE_IVAR_ALLOC_VAL 0x80 /* Interrupt Allocation valid */ + +/* ETYPE Queue Filter/Select Bit Masks */ +#define IXGBE_MAX_ETQF_FILTERS 8 +#define IXGBE_ETQF_FCOE 0x08000000 /* bit 27 */ +#define IXGBE_ETQF_BCN 0x10000000 /* bit 28 */ +#define IXGBE_ETQF_TX_ANTISPOOF 0x20000000 /* bit 29 */ +#define IXGBE_ETQF_1588 0x40000000 /* bit 30 */ +#define IXGBE_ETQF_FILTER_EN 0x80000000 /* bit 31 */ +#define IXGBE_ETQF_POOL_ENABLE (1 << 26) /* bit 26 */ +#define IXGBE_ETQF_POOL_SHIFT 20 + +#define IXGBE_ETQS_RX_QUEUE 0x007F0000 /* bits 22:16 */ +#define IXGBE_ETQS_RX_QUEUE_SHIFT 16 +#define IXGBE_ETQS_LLI 0x20000000 /* bit 29 */ +#define IXGBE_ETQS_QUEUE_EN 0x80000000 /* bit 31 */ + +/* + * ETQF filter list: one static filter per filter consumer. This is + * to avoid filter collisions later. Add new filters + * here!! + * + * Current filters: + * EAPOL 802.1x (0x888e): Filter 0 + * FCoE (0x8906): Filter 2 + * 1588 (0x88f7): Filter 3 + * FIP (0x8914): Filter 4 + * LLDP (0x88CC): Filter 5 + * LACP (0x8809): Filter 6 + * FC (0x8808): Filter 7 + */ +#define IXGBE_ETQF_FILTER_EAPOL 0 +#define IXGBE_ETQF_FILTER_FCOE 2 +#define IXGBE_ETQF_FILTER_1588 3 +#define IXGBE_ETQF_FILTER_FIP 4 +#define IXGBE_ETQF_FILTER_LLDP 5 +#define IXGBE_ETQF_FILTER_LACP 6 +#define IXGBE_ETQF_FILTER_FC 7 +/* VLAN Control Bit Masks */ +#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ +#define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ +#define IXGBE_VLNCTRL_CFIEN 0x20000000 /* bit 29 */ +#define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */ +#define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */ + +/* VLAN pool filtering masks */ +#define IXGBE_VLVF_VIEN 0x80000000 /* filter is valid */ +#define IXGBE_VLVF_ENTRIES 64 +#define IXGBE_VLVF_VLANID_MASK 0x00000FFF +/* Per VF Port VLAN insertion rules */ +#define IXGBE_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ +#define IXGBE_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ + +#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */ + +/* STATUS Bit Masks */ +#define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */ +#define IXGBE_STATUS_LAN_ID_SHIFT 2 /* LAN ID Shift*/ +#define IXGBE_STATUS_GIO 0x00080000 /* GIO Primary Ena Status */ + +#define IXGBE_STATUS_LAN_ID_0 0x00000000 /* LAN ID 0 */ +#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */ + +/* ESDP Bit Masks */ +#define IXGBE_ESDP_SDP0 0x00000001 /* SDP0 Data Value */ +#define IXGBE_ESDP_SDP1 0x00000002 /* SDP1 Data Value */ +#define IXGBE_ESDP_SDP2 0x00000004 /* SDP2 Data Value */ +#define IXGBE_ESDP_SDP3 0x00000008 /* SDP3 Data Value */ +#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */ +#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */ +#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */ +#define IXGBE_ESDP_SDP7 0x00000080 /* SDP7 Data Value */ +#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */ +#define IXGBE_ESDP_SDP1_DIR 0x00000200 /* SDP1 IO direction */ +#define IXGBE_ESDP_SDP2_DIR 0x00000400 /* SDP1 IO direction */ +#define IXGBE_ESDP_SDP3_DIR 0x00000800 /* SDP3 IO direction */ +#define IXGBE_ESDP_SDP4_DIR 0x00001000 /* SDP4 IO direction */ +#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */ +#define IXGBE_ESDP_SDP6_DIR 0x00004000 /* SDP6 IO direction */ +#define IXGBE_ESDP_SDP7_DIR 0x00008000 /* SDP7 IO direction */ +#define IXGBE_ESDP_SDP0_NATIVE 0x00010000 /* SDP0 IO mode */ +#define IXGBE_ESDP_SDP1_NATIVE 0x00020000 /* SDP1 IO mode */ + + +/* LEDCTL Bit Masks */ +#define IXGBE_LED_IVRT_BASE 0x00000040 +#define IXGBE_LED_BLINK_BASE 0x00000080 +#define IXGBE_LED_MODE_MASK_BASE 0x0000000F +#define IXGBE_LED_OFFSET(_base, _i) (_base << (8 * (_i))) +#define IXGBE_LED_MODE_SHIFT(_i) (8*(_i)) +#define IXGBE_LED_IVRT(_i) IXGBE_LED_OFFSET(IXGBE_LED_IVRT_BASE, _i) +#define IXGBE_LED_BLINK(_i) IXGBE_LED_OFFSET(IXGBE_LED_BLINK_BASE, _i) +#define IXGBE_LED_MODE_MASK(_i) IXGBE_LED_OFFSET(IXGBE_LED_MODE_MASK_BASE, _i) +#define IXGBE_X557_LED_MANUAL_SET_MASK (1 << 8) +#define IXGBE_X557_MAX_LED_INDEX 3 +#define IXGBE_X557_LED_PROVISIONING 0xC430 + +/* LED modes */ +#define IXGBE_LED_LINK_UP 0x0 +#define IXGBE_LED_LINK_10G 0x1 +#define IXGBE_LED_MAC 0x2 +#define IXGBE_LED_FILTER 0x3 +#define IXGBE_LED_LINK_ACTIVE 0x4 +#define IXGBE_LED_LINK_1G 0x5 +#define IXGBE_LED_ON 0xE +#define IXGBE_LED_OFF 0xF + +/* AUTOC Bit Masks */ +#define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000 +#define IXGBE_AUTOC_KX4_SUPP 0x80000000 +#define IXGBE_AUTOC_KX_SUPP 0x40000000 +#define IXGBE_AUTOC_PAUSE 0x30000000 +#define IXGBE_AUTOC_ASM_PAUSE 0x20000000 +#define IXGBE_AUTOC_SYM_PAUSE 0x10000000 +#define IXGBE_AUTOC_RF 0x08000000 +#define IXGBE_AUTOC_PD_TMR 0x06000000 +#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000 +#define IXGBE_AUTOC_AN_RX_DRIFT 0x00800000 +#define IXGBE_AUTOC_AN_RX_ALIGN 0x007C0000 +#define IXGBE_AUTOC_FECA 0x00040000 +#define IXGBE_AUTOC_FECR 0x00020000 +#define IXGBE_AUTOC_KR_SUPP 0x00010000 +#define IXGBE_AUTOC_AN_RESTART 0x00001000 +#define IXGBE_AUTOC_FLU 0x00000001 +#define IXGBE_AUTOC_LMS_SHIFT 13 +#define IXGBE_AUTOC_LMS_10G_SERIAL (0x3 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_KX_KR (0x4 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_SGMII_1G_100M (0x5 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII (0x7 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) + +#define IXGBE_AUTOC_1G_PMA_PMD_MASK 0x00000200 +#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9 +#define IXGBE_AUTOC_10G_PMA_PMD_MASK 0x00000180 +#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7 +#define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_10G_KX4 (0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_10G_CX4 (0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_1G_BX (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_1G_KX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_1G_SFI (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_1G_KX_BX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) + +#define IXGBE_AUTOC2_UPPER_MASK 0xFFFF0000 +#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK 0x00030000 +#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT 16 +#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) +#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) +#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) +#define IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK 0x50000000 +#define IXGBE_AUTOC2_LINK_DISABLE_MASK 0x70000000 + +#define IXGBE_MACC_FLU 0x00000001 +#define IXGBE_MACC_FSV_10G 0x00030000 +#define IXGBE_MACC_FS 0x00040000 +#define IXGBE_MAC_RX2TX_LPBK 0x00000002 + +/* Veto Bit definiton */ +#define IXGBE_MMNGC_MNG_VETO 0x00000001 + +/* LINKS Bit Masks */ +#define IXGBE_LINKS_KX_AN_COMP 0x80000000 +#define IXGBE_LINKS_UP 0x40000000 +#define IXGBE_LINKS_SPEED 0x20000000 +#define IXGBE_LINKS_MODE 0x18000000 +#define IXGBE_LINKS_RX_MODE 0x06000000 +#define IXGBE_LINKS_TX_MODE 0x01800000 +#define IXGBE_LINKS_XGXS_EN 0x00400000 +#define IXGBE_LINKS_SGMII_EN 0x02000000 +#define IXGBE_LINKS_PCS_1G_EN 0x00200000 +#define IXGBE_LINKS_1G_AN_EN 0x00100000 +#define IXGBE_LINKS_KX_AN_IDLE 0x00080000 +#define IXGBE_LINKS_1G_SYNC 0x00040000 +#define IXGBE_LINKS_10G_ALIGN 0x00020000 +#define IXGBE_LINKS_10G_LANE_SYNC 0x00017000 +#define IXGBE_LINKS_TL_FAULT 0x00001000 +#define IXGBE_LINKS_SIGNAL 0x00000F00 + +#define IXGBE_LINKS_SPEED_NON_STD 0x08000000 +#define IXGBE_LINKS_SPEED_82599 0x30000000 +#define IXGBE_LINKS_SPEED_10G_82599 0x30000000 +#define IXGBE_LINKS_SPEED_1G_82599 0x20000000 +#define IXGBE_LINKS_SPEED_100_82599 0x10000000 +#define IXGBE_LINKS_SPEED_10_X550EM_A 0x00000000 +#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ +#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ + +#define IXGBE_LINKS2_AN_SUPPORTED 0x00000040 + +/* PCS1GLSTA Bit Masks */ +#define IXGBE_PCS1GLSTA_LINK_OK 1 +#define IXGBE_PCS1GLSTA_SYNK_OK 0x10 +#define IXGBE_PCS1GLSTA_AN_COMPLETE 0x10000 +#define IXGBE_PCS1GLSTA_AN_PAGE_RX 0x20000 +#define IXGBE_PCS1GLSTA_AN_TIMED_OUT 0x40000 +#define IXGBE_PCS1GLSTA_AN_REMOTE_FAULT 0x80000 +#define IXGBE_PCS1GLSTA_AN_ERROR_RWS 0x100000 + +#define IXGBE_PCS1GANA_SYM_PAUSE 0x80 +#define IXGBE_PCS1GANA_ASM_PAUSE 0x100 + +/* PCS1GLCTL Bit Masks */ +#define IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN 0x00040000 /* PCS 1G autoneg to en */ +#define IXGBE_PCS1GLCTL_FLV_LINK_UP 1 +#define IXGBE_PCS1GLCTL_FORCE_LINK 0x20 +#define IXGBE_PCS1GLCTL_LOW_LINK_LATCH 0x40 +#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000 +#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000 + +/* ANLP1 Bit Masks */ +#define IXGBE_ANLP1_PAUSE 0x0C00 +#define IXGBE_ANLP1_SYM_PAUSE 0x0400 +#define IXGBE_ANLP1_ASM_PAUSE 0x0800 +#define IXGBE_ANLP1_AN_STATE_MASK 0x000f0000 + +/* SW Semaphore Register bitmasks */ +#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define IXGBE_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ +#define IXGBE_SWFW_REGSMP 0x80000000 /* Register Semaphore bit 31 */ + +/* SW_FW_SYNC/GSSR definitions */ +#define IXGBE_GSSR_EEP_SM 0x0001 +#define IXGBE_GSSR_PHY0_SM 0x0002 +#define IXGBE_GSSR_PHY1_SM 0x0004 +#define IXGBE_GSSR_MAC_CSR_SM 0x0008 +#define IXGBE_GSSR_FLASH_SM 0x0010 +#define IXGBE_GSSR_NVM_UPDATE_SM 0x0200 +#define IXGBE_GSSR_SW_MNG_SM 0x0400 +#define IXGBE_GSSR_TOKEN_SM 0x40000000 /* SW bit for shared access */ +#define IXGBE_GSSR_SHARED_I2C_SM 0x1806 /* Wait for both phys and both I2Cs */ +#define IXGBE_GSSR_I2C_MASK 0x1800 +#define IXGBE_GSSR_NVM_PHY_MASK 0xF + +/* FW Status register bitmask */ +#define IXGBE_FWSTS_FWRI 0x00000200 /* Firmware Reset Indication */ + +/* EEC Register */ +#define IXGBE_EEC_SK 0x00000001 /* EEPROM Clock */ +#define IXGBE_EEC_CS 0x00000002 /* EEPROM Chip Select */ +#define IXGBE_EEC_DI 0x00000004 /* EEPROM Data In */ +#define IXGBE_EEC_DO 0x00000008 /* EEPROM Data Out */ +#define IXGBE_EEC_FWE_MASK 0x00000030 /* FLASH Write Enable */ +#define IXGBE_EEC_FWE_DIS 0x00000010 /* Disable FLASH writes */ +#define IXGBE_EEC_FWE_EN 0x00000020 /* Enable FLASH writes */ +#define IXGBE_EEC_FWE_SHIFT 4 +#define IXGBE_EEC_REQ 0x00000040 /* EEPROM Access Request */ +#define IXGBE_EEC_GNT 0x00000080 /* EEPROM Access Grant */ +#define IXGBE_EEC_PRES 0x00000100 /* EEPROM Present */ +#define IXGBE_EEC_ARD 0x00000200 /* EEPROM Auto Read Done */ +#define IXGBE_EEC_FLUP 0x00800000 /* Flash update command */ +#define IXGBE_EEC_SEC1VAL 0x02000000 /* Sector 1 Valid */ +#define IXGBE_EEC_FLUDONE 0x04000000 /* Flash update done */ +/* EEPROM Addressing bits based on type (0-small, 1-large) */ +#define IXGBE_EEC_ADDR_SIZE 0x00000400 +#define IXGBE_EEC_SIZE 0x00007800 /* EEPROM Size */ +#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD alows 14 bits for addr. */ + +#define IXGBE_EEC_SIZE_SHIFT 11 +#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6 +#define IXGBE_EEPROM_OPCODE_BITS 8 + +/* FLA Register */ +#define IXGBE_FLA_LOCKED 0x00000040 + +/* Part Number String Length */ +#define IXGBE_PBANUM_LENGTH 11 + +/* Checksum and EEPROM pointers */ +#define IXGBE_PBANUM_PTR_GUARD 0xFAFA +#define IXGBE_EEPROM_CHECKSUM 0x3F +#define IXGBE_EEPROM_SUM 0xBABA +#define IXGBE_EEPROM_CTRL_4 0x45 +#define IXGBE_EE_CTRL_4_INST_ID 0x10 +#define IXGBE_EE_CTRL_4_INST_ID_SHIFT 4 +#define IXGBE_PCIE_ANALOG_PTR 0x03 +#define IXGBE_ATLAS0_CONFIG_PTR 0x04 +#define IXGBE_PHY_PTR 0x04 +#define IXGBE_ATLAS1_CONFIG_PTR 0x05 +#define IXGBE_OPTION_ROM_PTR 0x05 +#define IXGBE_PCIE_GENERAL_PTR 0x06 +#define IXGBE_PCIE_CONFIG0_PTR 0x07 +#define IXGBE_PCIE_CONFIG1_PTR 0x08 +#define IXGBE_CORE0_PTR 0x09 +#define IXGBE_CORE1_PTR 0x0A +#define IXGBE_MAC0_PTR 0x0B +#define IXGBE_MAC1_PTR 0x0C +#define IXGBE_CSR0_CONFIG_PTR 0x0D +#define IXGBE_CSR1_CONFIG_PTR 0x0E +#define IXGBE_PCIE_ANALOG_PTR_X550 0x02 +#define IXGBE_SHADOW_RAM_SIZE_X550 0x4000 +#define IXGBE_IXGBE_PCIE_GENERAL_SIZE 0x24 +#define IXGBE_PCIE_CONFIG_SIZE 0x08 +#define IXGBE_EEPROM_LAST_WORD 0x41 +#define IXGBE_FW_PTR 0x0F +#define IXGBE_PBANUM0_PTR 0x15 +#define IXGBE_PBANUM1_PTR 0x16 +#define IXGBE_ALT_MAC_ADDR_PTR 0x37 +#define IXGBE_FREE_SPACE_PTR 0X3E + +/* External Thermal Sensor Config */ +#define IXGBE_ETS_CFG 0x26 +#define IXGBE_ETS_LTHRES_DELTA_MASK 0x07C0 +#define IXGBE_ETS_LTHRES_DELTA_SHIFT 6 +#define IXGBE_ETS_TYPE_MASK 0x0038 +#define IXGBE_ETS_TYPE_SHIFT 3 +#define IXGBE_ETS_TYPE_EMC 0x000 +#define IXGBE_ETS_NUM_SENSORS_MASK 0x0007 +#define IXGBE_ETS_DATA_LOC_MASK 0x3C00 +#define IXGBE_ETS_DATA_LOC_SHIFT 10 +#define IXGBE_ETS_DATA_INDEX_MASK 0x0300 +#define IXGBE_ETS_DATA_INDEX_SHIFT 8 +#define IXGBE_ETS_DATA_HTHRESH_MASK 0x00FF + +#define IXGBE_SAN_MAC_ADDR_PTR 0x28 +#define IXGBE_DEVICE_CAPS 0x2C +#define IXGBE_82599_SERIAL_NUMBER_MAC_ADDR 0x11 +#define IXGBE_X550_SERIAL_NUMBER_MAC_ADDR 0x04 + +#define IXGBE_PCIE_MSIX_LKV_CAPS 0xB2 +#define IXGBE_PCIE_MSIX_82599_CAPS 0x72 +#define IXGBE_MAX_MSIX_VECTORS_82599 0x40 +#define IXGBE_PCIE_MSIX_82598_CAPS 0x62 +#define IXGBE_MAX_MSIX_VECTORS_82598 0x13 + +/* MSI-X capability fields masks */ +#define IXGBE_PCIE_MSIX_TBL_SZ_MASK 0x7FF + +/* Legacy EEPROM word offsets */ +#define IXGBE_ISCSI_BOOT_CAPS 0x0033 +#define IXGBE_ISCSI_SETUP_PORT_0 0x0030 +#define IXGBE_ISCSI_SETUP_PORT_1 0x0034 + +/* EEPROM Commands - SPI */ +#define IXGBE_EEPROM_MAX_RETRY_SPI 5000 /* Max wait 5ms for RDY signal */ +#define IXGBE_EEPROM_STATUS_RDY_SPI 0x01 +#define IXGBE_EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */ +#define IXGBE_EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */ +#define IXGBE_EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = addr bit-8 */ +#define IXGBE_EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Ena latch */ +/* EEPROM reset Write Enable latch */ +#define IXGBE_EEPROM_WRDI_OPCODE_SPI 0x04 +#define IXGBE_EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status reg */ +#define IXGBE_EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status reg */ +#define IXGBE_EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */ +#define IXGBE_EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */ +#define IXGBE_EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */ + +/* EEPROM Read Register */ +#define IXGBE_EEPROM_RW_REG_DATA 16 /* data offset in EEPROM read reg */ +#define IXGBE_EEPROM_RW_REG_DONE 2 /* Offset to READ done bit */ +#define IXGBE_EEPROM_RW_REG_START 1 /* First bit to start operation */ +#define IXGBE_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define IXGBE_NVM_POLL_WRITE 1 /* Flag for polling for wr complete */ +#define IXGBE_NVM_POLL_READ 0 /* Flag for polling for rd complete */ + +#define NVM_INIT_CTRL_3 0x38 +#define NVM_INIT_CTRL_3_LPLU 0x8 +#define NVM_INIT_CTRL_3_D10GMP_PORT0 0x40 +#define NVM_INIT_CTRL_3_D10GMP_PORT1 0x100 + +#define IXGBE_ETH_LENGTH_OF_ADDRESS 6 + +#define IXGBE_EEPROM_PAGE_SIZE_MAX 128 +#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 256 /* words rd in burst */ +#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* words wr in burst */ +#define IXGBE_EEPROM_CTRL_2 1 /* EEPROM CTRL word 2 */ +#define IXGBE_EEPROM_CCD_BIT 2 + +#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS +#define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM attempts to gain grant */ +#endif + +#ifndef IXGBE_EERD_EEWR_ATTEMPTS +/* Number of 5 microseconds we wait for EERD read and + * EERW write to complete */ +#define IXGBE_EERD_EEWR_ATTEMPTS 100000 +#endif + +#ifndef IXGBE_FLUDONE_ATTEMPTS +/* # attempts we wait for flush update to complete */ +#define IXGBE_FLUDONE_ATTEMPTS 20000 +#endif + +#define IXGBE_PCIE_CTRL2 0x5 /* PCIe Control 2 Offset */ +#define IXGBE_PCIE_CTRL2_DUMMY_ENABLE 0x8 /* Dummy Function Enable */ +#define IXGBE_PCIE_CTRL2_LAN_DISABLE 0x2 /* LAN PCI Disable */ +#define IXGBE_PCIE_CTRL2_DISABLE_SELECT 0x1 /* LAN Disable Select */ + +#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0 +#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 +#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 +#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 +#define IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR (1 << 7) +#define IXGBE_FW_LESM_PARAMETERS_PTR 0x2 +#define IXGBE_FW_LESM_STATE_1 0x1 +#define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */ +#define IXGBE_FW_LESM_2_STATES_ENABLED_MASK 0x1F +#define IXGBE_FW_LESM_2_STATES_ENABLED 0x12 +#define IXGBE_FW_LESM_STATE0_10G_ENABLED 0x6FFF +#define IXGBE_FW_LESM_STATE1_10G_ENABLED 0x4FFF +#define IXGBE_FW_LESM_STATE0_10G_DISABLED 0x0FFF +#define IXGBE_FW_LESM_STATE1_10G_DISABLED 0x2FFF +#define IXGBE_FW_LESM_PORT0_STATE0_OFFSET 0x2 +#define IXGBE_FW_LESM_PORT0_STATE1_OFFSET 0x3 +#define IXGBE_FW_LESM_PORT1_STATE0_OFFSET 0x6 +#define IXGBE_FW_LESM_PORT1_STATE1_OFFSET 0x7 +#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 +#define IXGBE_FW_PATCH_VERSION_4 0x7 +#define IXGBE_FCOE_IBA_CAPS_BLK_PTR 0x33 /* iSCSI/FCOE block */ +#define IXGBE_FCOE_IBA_CAPS_FCOE 0x20 /* FCOE flags */ +#define IXGBE_ISCSI_FCOE_BLK_PTR 0x17 /* iSCSI/FCOE block */ +#define IXGBE_ISCSI_FCOE_FLAGS_OFFSET 0x0 /* FCOE flags */ +#define IXGBE_ISCSI_FCOE_FLAGS_ENABLE 0x1 /* FCOE flags enable bit */ +#define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR 0x27 /* Alt. SAN MAC block */ +#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET 0x0 /* Alt SAN MAC capability */ +#define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt SAN MAC 0 offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_PORT1_OFFSET 0x4 /* Alt SAN MAC 1 offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET 0x7 /* Alt WWNN prefix offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET 0x8 /* Alt WWPN prefix offset */ +#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_SANMAC 0x0 /* Alt SAN MAC exists */ +#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt WWN base exists */ + +/* FW header offset */ +#define IXGBE_X540_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 +#define IXGBE_X540_FW_MODULE_MASK 0x7FFF +/* 4KB multiplier */ +#define IXGBE_X540_FW_MODULE_LENGTH 0x1000 +/* version word 2 (month & day) */ +#define IXGBE_X540_FW_PATCH_VERSION_2 0x5 +/* version word 3 (silicon compatibility & year) */ +#define IXGBE_X540_FW_PATCH_VERSION_3 0x6 +/* version word 4 (major & minor numbers) */ +#define IXGBE_X540_FW_PATCH_VERSION_4 0x7 + +#define IXGBE_DEVICE_CAPS_WOL_PORT0_1 0x4 /* WoL supported on ports 0 & 1 */ +#define IXGBE_DEVICE_CAPS_WOL_PORT0 0x8 /* WoL supported on port 0 */ +#define IXGBE_DEVICE_CAPS_WOL_MASK 0xC /* Mask for WoL capabilities */ + +/* PCI Bus Info */ +#define IXGBE_PCI_DEVICE_STATUS 0xAA +#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020 +#define IXGBE_PCI_LINK_STATUS 0xB2 +#define IXGBE_PCI_LINK_STATUS_E610 0x82 +#define IXGBE_PCI_DEVICE_CONTROL2 0xC8 +#define IXGBE_PCI_LINK_WIDTH 0x3F0 +#define IXGBE_PCI_LINK_WIDTH_1 0x10 +#define IXGBE_PCI_LINK_WIDTH_2 0x20 +#define IXGBE_PCI_LINK_WIDTH_4 0x40 +#define IXGBE_PCI_LINK_WIDTH_8 0x80 +#define IXGBE_PCI_LINK_SPEED 0xF +#define IXGBE_PCI_LINK_SPEED_2500 0x1 +#define IXGBE_PCI_LINK_SPEED_5000 0x2 +#define IXGBE_PCI_LINK_SPEED_8000 0x3 +#define IXGBE_PCI_LINK_SPEED_16000 0x4 +#define IXGBE_PCI_HEADER_TYPE_REGISTER 0x0E +#define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80 +#define IXGBE_PCI_DEVICE_CONTROL2_16ms 0x0005 + +#define IXGBE_PCIDEVCTRL2_TIMEO_MASK 0xf +#define IXGBE_PCIDEVCTRL2_16_32ms_def 0x0 +#define IXGBE_PCIDEVCTRL2_50_100us 0x1 +#define IXGBE_PCIDEVCTRL2_1_2ms 0x2 +#define IXGBE_PCIDEVCTRL2_16_32ms 0x5 +#define IXGBE_PCIDEVCTRL2_65_130ms 0x6 +#define IXGBE_PCIDEVCTRL2_260_520ms 0x9 +#define IXGBE_PCIDEVCTRL2_1_2s 0xa +#define IXGBE_PCIDEVCTRL2_4_8s 0xd +#define IXGBE_PCIDEVCTRL2_17_34s 0xe + +/* Number of 100 microseconds we wait for PCI Express primary disable */ +#define IXGBE_PCI_PRIMARY_DISABLE_TIMEOUT 800 + +/* Check whether address is multicast. This is little-endian specific check.*/ +#define IXGBE_IS_MULTICAST(Address) \ + (bool)(((u8 *)(Address))[0] & ((u8)0x01)) + +/* Check whether an address is broadcast. */ +#define IXGBE_IS_BROADCAST(Address) \ + ((((u8 *)(Address))[0] == ((u8)0xff)) && \ + (((u8 *)(Address))[1] == ((u8)0xff))) + +/* RAH */ +#define IXGBE_RAH_VIND_MASK 0x003C0000 +#define IXGBE_RAH_VIND_SHIFT 18 +#define IXGBE_RAH_AV 0x80000000 +#define IXGBE_CLEAR_VMDQ_ALL 0xFFFFFFFF + +/* Header split receive */ +#define IXGBE_RFCTL_ISCSI_DIS 0x00000001 +#define IXGBE_RFCTL_ISCSI_DWC_MASK 0x0000003E +#define IXGBE_RFCTL_ISCSI_DWC_SHIFT 1 +#define IXGBE_RFCTL_RSC_DIS 0x00000020 +#define IXGBE_RFCTL_NFSW_DIS 0x00000040 +#define IXGBE_RFCTL_NFSR_DIS 0x00000080 +#define IXGBE_RFCTL_NFS_VER_MASK 0x00000300 +#define IXGBE_RFCTL_NFS_VER_SHIFT 8 +#define IXGBE_RFCTL_NFS_VER_2 0 +#define IXGBE_RFCTL_NFS_VER_3 1 +#define IXGBE_RFCTL_NFS_VER_4 2 +#define IXGBE_RFCTL_IPV6_DIS 0x00000400 +#define IXGBE_RFCTL_IPV6_XSUM_DIS 0x00000800 +#define IXGBE_RFCTL_IPFRSP_DIS 0x00004000 +#define IXGBE_RFCTL_IPV6_EX_DIS 0x00010000 +#define IXGBE_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 + +/* Transmit Config masks */ +#define IXGBE_TXDCTL_ENABLE 0x02000000 /* Ena specific Tx Queue */ +#define IXGBE_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. wr-bk flushing */ +#define IXGBE_TXDCTL_WTHRESH_SHIFT 16 /* shift to WTHRESH bits */ +/* Enable short packet padding to 64 bytes */ +#define IXGBE_TX_PAD_ENABLE 0x00000400 +#define IXGBE_JUMBO_FRAME_ENABLE 0x00000004 /* Allow jumbo frames */ +/* This allows for 16K packets + 4k for vlan */ +#define IXGBE_MAX_FRAME_SZ 0x40040000 + +#define IXGBE_TDWBAL_HEAD_WB_ENABLE 0x1 /* Tx head write-back enable */ +#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq# write-back enable */ + +/* Receive Config masks */ +#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */ +#define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Desc Monitor Bypass */ +#define IXGBE_RXDCTL_ENABLE 0x02000000 /* Ena specific Rx Queue */ +#define IXGBE_RXDCTL_SWFLSH 0x04000000 /* Rx Desc wr-bk flushing */ +#define IXGBE_RXDCTL_RLPMLMASK 0x00003FFF /* X540 supported only */ +#define IXGBE_RXDCTL_RLPML_EN 0x00008000 +#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */ + +#define IXGBE_TSAUXC_EN_CLK 0x00000004 +#define IXGBE_TSAUXC_SYNCLK 0x00000008 +#define IXGBE_TSAUXC_SDP0_INT 0x00000040 +#define IXGBE_TSAUXC_EN_TT0 0x00000001 +#define IXGBE_TSAUXC_EN_TT1 0x00000002 +#define IXGBE_TSAUXC_ST0 0x00000010 +#define IXGBE_TSAUXC_DISABLE_SYSTIME 0x80000000 + +#define IXGBE_TSSDP_TS_SDP0_SEL_MASK 0x000000C0 +#define IXGBE_TSSDP_TS_SDP0_CLK0 0x00000080 +#define IXGBE_TSSDP_TS_SDP0_EN 0x00000100 + +#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ +#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */ + +#define IXGBE_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */ +#define IXGBE_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */ +#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00 +#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02 +#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 +#define IXGBE_TSYNCRXCTL_TYPE_ALL 0x08 +#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A +#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */ +#define IXGBE_TSYNCRXCTL_TSIP_UT_EN 0x00800000 /* Rx Timestamp in Packet */ +#define IXGBE_TSYNCRXCTL_TSIP_UP_MASK 0xFF000000 /* Rx Timestamp UP Mask */ + +#define IXGBE_TSIM_SYS_WRAP 0x00000001 +#define IXGBE_TSIM_TXTS 0x00000002 +#define IXGBE_TSIM_TADJ 0x00000080 + +#define IXGBE_TSICR_SYS_WRAP IXGBE_TSIM_SYS_WRAP +#define IXGBE_TSICR_TXTS IXGBE_TSIM_TXTS +#define IXGBE_TSICR_TADJ IXGBE_TSIM_TADJ + +#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF +#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00 +#define IXGBE_RXMTRL_V1_DELAY_REQ_MSG 0x01 +#define IXGBE_RXMTRL_V1_FOLLOWUP_MSG 0x02 +#define IXGBE_RXMTRL_V1_DELAY_RESP_MSG 0x03 +#define IXGBE_RXMTRL_V1_MGMT_MSG 0x04 + +#define IXGBE_RXMTRL_V2_MSGID_MASK 0x0000FF00 +#define IXGBE_RXMTRL_V2_SYNC_MSG 0x0000 +#define IXGBE_RXMTRL_V2_DELAY_REQ_MSG 0x0100 +#define IXGBE_RXMTRL_V2_PDELAY_REQ_MSG 0x0200 +#define IXGBE_RXMTRL_V2_PDELAY_RESP_MSG 0x0300 +#define IXGBE_RXMTRL_V2_FOLLOWUP_MSG 0x0800 +#define IXGBE_RXMTRL_V2_DELAY_RESP_MSG 0x0900 +#define IXGBE_RXMTRL_V2_PDELAY_FOLLOWUP_MSG 0x0A00 +#define IXGBE_RXMTRL_V2_ANNOUNCE_MSG 0x0B00 +#define IXGBE_RXMTRL_V2_SIGNALLING_MSG 0x0C00 +#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00 + +#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */ +#define IXGBE_FCTRL_TPE 0x00000080 /* Tag Promiscuous Ena*/ +#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/ +#define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */ +#define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */ +#define IXGBE_FCTRL_PMCF 0x00001000 /* Pass MAC Control Frames */ +#define IXGBE_FCTRL_DPF 0x00002000 /* Discard Pause Frame */ +/* Receive Priority Flow Control Enable */ +#define IXGBE_FCTRL_RPFCE 0x00004000 +#define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */ +#define IXGBE_MFLCN_PMCF 0x00000001 /* Pass MAC Control Frames */ +#define IXGBE_MFLCN_DPF 0x00000002 /* Discard Pause Frame */ +#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */ +#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */ +#define IXGBE_MFLCN_RPFCE_MASK 0x00000FF4 /* Rx Priority FC bitmap mask */ +#define IXGBE_MFLCN_RPFCE_SHIFT 4 /* Rx Priority FC bitmap shift */ + +/* Multiple Receive Queue Control */ +#define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */ +#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */ +#define IXGBE_MRQC_RT8TCEN 0x00000002 /* 8 TC no RSS */ +#define IXGBE_MRQC_RT4TCEN 0x00000003 /* 4 TC no RSS */ +#define IXGBE_MRQC_RTRSS8TCEN 0x00000004 /* 8 TC w/ RSS */ +#define IXGBE_MRQC_RTRSS4TCEN 0x00000005 /* 4 TC w/ RSS */ +#define IXGBE_MRQC_VMDQEN 0x00000008 /* VMDq2 64 pools no RSS */ +#define IXGBE_MRQC_VMDQRSS32EN 0x0000000A /* VMDq2 32 pools w/ RSS */ +#define IXGBE_MRQC_VMDQRSS64EN 0x0000000B /* VMDq2 64 pools w/ RSS */ +#define IXGBE_MRQC_VMDQRT8TCEN 0x0000000C /* VMDq2/RT 16 pool 8 TC */ +#define IXGBE_MRQC_VMDQRT4TCEN 0x0000000D /* VMDq2/RT 32 pool 4 TC */ +#define IXGBE_MRQC_L3L4TXSWEN 0x00008000 /* Enable L3/L4 Tx switch */ +#define IXGBE_MRQC_RSS_FIELD_MASK 0xFFFF0000 +#define IXGBE_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 +#define IXGBE_MRQC_RSS_FIELD_IPV4 0x00020000 +#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP 0x00040000 +#define IXGBE_MRQC_RSS_FIELD_IPV6_EX 0x00080000 +#define IXGBE_MRQC_RSS_FIELD_IPV6 0x00100000 +#define IXGBE_MRQC_RSS_FIELD_IPV6_TCP 0x00200000 +#define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 +#define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 +#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000 +#define IXGBE_MRQC_MULTIPLE_RSS 0x00002000 +#define IXGBE_MRQC_L3L4TXSWEN 0x00008000 + +/* Queue Drop Enable */ +#define IXGBE_QDE_ENABLE 0x00000001 +#define IXGBE_QDE_HIDE_VLAN 0x00000002 +#define IXGBE_QDE_IDX_MASK 0x00007F00 +#define IXGBE_QDE_IDX_SHIFT 8 +#define IXGBE_QDE_WRITE 0x00010000 +#define IXGBE_QDE_READ 0x00020000 + +#define IXGBE_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ +#define IXGBE_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ +#define IXGBE_TXD_CMD_EOP 0x01000000 /* End of Packet */ +#define IXGBE_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ +#define IXGBE_TXD_CMD_IC 0x04000000 /* Insert Checksum */ +#define IXGBE_TXD_CMD_RS 0x08000000 /* Report Status */ +#define IXGBE_TXD_CMD_DEXT 0x20000000 /* Desc extension (0 = legacy) */ +#define IXGBE_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ +#define IXGBE_TXD_STAT_DD 0x00000001 /* Descriptor Done */ + +#define IXGBE_RXDADV_IPSEC_STATUS_SECP 0x00020000 +#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000 +#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000 +#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED 0x18000000 +#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000 +/* Multiple Transmit Queue Command Register */ +#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */ +#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */ +#define IXGBE_MTQC_NUM_TC_OR_Q 0xC /* Numer of TCs or TxQs per pool */ +#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */ +#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */ +#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */ +#define IXGBE_MTQC_4TC_4TQ 0x8 /* 4 TC if RT_ENA and VT_ENA */ +#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */ + +/* Receive Descriptor bit definitions */ +#define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */ +#define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */ +#define IXGBE_RXD_STAT_FLM 0x04 /* FDir Match */ +#define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define IXGBE_RXDADV_NEXTP_MASK 0x000FFFF0 /* Next Descriptor Index */ +#define IXGBE_RXDADV_NEXTP_SHIFT 0x00000004 +#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ +#define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */ +#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ +#define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */ +#define IXGBE_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */ +#define IXGBE_RXD_STAT_OUTERIPCS 0x100 /* Cloud IP xsum calculated */ +#define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */ +#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ +#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ +#define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */ +#define IXGBE_RXD_STAT_TSIP 0x08000 /* Time Stamp in packet buffer */ +#define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */ +#define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */ +#define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */ +#define IXGBE_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ +#define IXGBE_RXD_ERR_CE 0x01 /* CRC Error */ +#define IXGBE_RXD_ERR_LE 0x02 /* Length Error */ +#define IXGBE_RXD_ERR_PE 0x08 /* Packet Error */ +#define IXGBE_RXD_ERR_OSE 0x10 /* Oversize Error */ +#define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */ +#define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */ +#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */ +#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */ +#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */ +#define IXGBE_RXDADV_ERR_OUTERIPER 0x04000000 /* CRC IP Header error */ +#define IXGBE_RXDADV_ERR_RXE 0x20000000 /* Any MAC Error */ +#define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCEOFe/IPE */ +#define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */ +#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */ +#define IXGBE_RXDADV_ERR_FDIR_DROP 0x00200000 /* FDIR Drop error */ +#define IXGBE_RXDADV_ERR_FDIR_COLL 0x00400000 /* FDIR Collision error */ +#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */ +#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */ +#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */ +#define IXGBE_RXDADV_ERR_PE 0x08000000 /* Packet Error */ +#define IXGBE_RXDADV_ERR_OSE 0x10000000 /* Oversize Error */ +#define IXGBE_RXDADV_ERR_USE 0x20000000 /* Undersize Error */ +#define IXGBE_RXDADV_ERR_TCPE 0x40000000 /* TCP/UDP Checksum Error */ +#define IXGBE_RXDADV_ERR_IPE 0x80000000 /* IP Checksum Error */ +#define IXGBE_RXD_VLAN_ID_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ +#define IXGBE_RXD_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ +#define IXGBE_RXD_PRI_SHIFT 13 +#define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */ +#define IXGBE_RXD_CFI_SHIFT 12 + +#define IXGBE_RXDADV_STAT_DD IXGBE_RXD_STAT_DD /* Done */ +#define IXGBE_RXDADV_STAT_EOP IXGBE_RXD_STAT_EOP /* End of Packet */ +#define IXGBE_RXDADV_STAT_FLM IXGBE_RXD_STAT_FLM /* FDir Match */ +#define IXGBE_RXDADV_STAT_VP IXGBE_RXD_STAT_VP /* IEEE VLAN Pkt */ +#define IXGBE_RXDADV_STAT_MASK 0x000fffff /* Stat/NEXTP: bit 0-19 */ +#define IXGBE_RXDADV_STAT_FCEOFS 0x00000040 /* FCoE EOF/SOF Stat */ +#define IXGBE_RXDADV_STAT_FCSTAT 0x00000030 /* FCoE Pkt Stat */ +#define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */ +#define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */ +#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */ +#define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */ +#define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE1588 Time Stamp */ +#define IXGBE_RXDADV_STAT_TSIP 0x00008000 /* Time Stamp in packet buffer */ + +/* PSRTYPE bit definitions */ +#define IXGBE_PSRTYPE_TCPHDR 0x00000010 +#define IXGBE_PSRTYPE_UDPHDR 0x00000020 +#define IXGBE_PSRTYPE_IPV4HDR 0x00000100 +#define IXGBE_PSRTYPE_IPV6HDR 0x00000200 +#define IXGBE_PSRTYPE_L2HDR 0x00001000 + +/* SRRCTL bit definitions */ +#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */ +#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* 64byte resolution (>> 6) + * + at bit 8 offset (<< 8) + * = (<< 2) + */ +#define IXGBE_SRRCTL_RDMTS_SHIFT 22 +#define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000 +#define IXGBE_SRRCTL_DROP_EN 0x10000000 +#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00 +#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000 +#define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 +#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000 +#define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 +#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 +#define IXGBE_SRRCTL_DESCTYPE_MASK 0x0E000000 + +#define IXGBE_RXDPS_HDRSTAT_HDRSP 0x00008000 +#define IXGBE_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF + +#define IXGBE_RXDADV_RSSTYPE_MASK 0x0000000F +#define IXGBE_RXDADV_PKTTYPE_MASK 0x0000FFF0 +#define IXGBE_RXDADV_PKTTYPE_MASK_EX 0x0001FFF0 +#define IXGBE_RXDADV_HDRBUFLEN_MASK 0x00007FE0 +#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000 +#define IXGBE_RXDADV_RSCCNT_SHIFT 17 +#define IXGBE_RXDADV_HDRBUFLEN_SHIFT 5 +#define IXGBE_RXDADV_SPLITHEADER_EN 0x00001000 +#define IXGBE_RXDADV_SPH 0x8000 + +/* RSS Hash results */ +#define IXGBE_RXDADV_RSSTYPE_NONE 0x00000000 +#define IXGBE_RXDADV_RSSTYPE_IPV4_TCP 0x00000001 +#define IXGBE_RXDADV_RSSTYPE_IPV4 0x00000002 +#define IXGBE_RXDADV_RSSTYPE_IPV6_TCP 0x00000003 +#define IXGBE_RXDADV_RSSTYPE_IPV6_EX 0x00000004 +#define IXGBE_RXDADV_RSSTYPE_IPV6 0x00000005 +#define IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX 0x00000006 +#define IXGBE_RXDADV_RSSTYPE_IPV4_UDP 0x00000007 +#define IXGBE_RXDADV_RSSTYPE_IPV6_UDP 0x00000008 +#define IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009 + +/* RSS Packet Types as indicated in the receive descriptor. */ +#define IXGBE_RXDADV_PKTTYPE_NONE 0x00000000 +#define IXGBE_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPv4 hdr present */ +#define IXGBE_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPv4 hdr + extensions */ +#define IXGBE_RXDADV_PKTTYPE_IPV6 0x00000040 /* IPv6 hdr present */ +#define IXGBE_RXDADV_PKTTYPE_IPV6_EX 0x00000080 /* IPv6 hdr + extensions */ +#define IXGBE_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */ +#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ +#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ +#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ +#define IXGBE_RXDADV_PKTTYPE_GENEVE 0x00000800 /* GENEVE hdr present */ +#define IXGBE_RXDADV_PKTTYPE_VXLAN 0x00000800 /* VXLAN hdr present */ +#define IXGBE_RXDADV_PKTTYPE_TUNNEL 0x00010000 /* Tunnel type */ +#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ +#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */ +#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */ +#define IXGBE_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */ +#define IXGBE_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */ +#define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */ + +/* Security Processing bit Indication */ +#define IXGBE_RXDADV_LNKSEC_STATUS_SECP 0x00020000 +#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000 +#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000 +#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000 +#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000 + +/* Masks to determine if packets should be dropped due to frame errors */ +#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \ + IXGBE_RXD_ERR_CE | \ + IXGBE_RXD_ERR_LE | \ + IXGBE_RXD_ERR_PE | \ + IXGBE_RXD_ERR_OSE | \ + IXGBE_RXD_ERR_USE) + +#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \ + IXGBE_RXDADV_ERR_CE | \ + IXGBE_RXDADV_ERR_LE | \ + IXGBE_RXDADV_ERR_PE | \ + IXGBE_RXDADV_ERR_OSE | \ + IXGBE_RXDADV_ERR_USE) + +#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK_82599 IXGBE_RXDADV_ERR_RXE + +/* Multicast bit mask */ +#define IXGBE_MCSTCTRL_MFE 0x4 + +/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ +#define IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE 8 +#define IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE 8 +#define IXGBE_REQ_TX_BUFFER_GRANULARITY 1024 + +/* Vlan-specific macros */ +#define IXGBE_RX_DESC_SPECIAL_VLAN_MASK 0x0FFF /* VLAN ID in lower 12 bits */ +#define IXGBE_RX_DESC_SPECIAL_PRI_MASK 0xE000 /* Priority in upper 3 bits */ +#define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */ +#define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT +/* Translated register #defines */ +#define IXGBE_PVFCTRL(P) (0x00300 + (4 * (P))) +#define IXGBE_PVFSTATUS(P) (0x00008 + (0 * (P))) +#define IXGBE_PVFLINKS(P) (0x042A4 + (0 * (P))) +#define IXGBE_PVFRTIMER(P) (0x00048 + (0 * (P))) +#define IXGBE_PVFMAILBOX(P) (0x04C00 + (4 * (P))) +#define IXGBE_PVFRXMEMWRAP(P) (0x03190 + (0 * (P))) +#define IXGBE_PVTEICR(P) (0x00B00 + (4 * (P))) +#define IXGBE_PVTEICS(P) (0x00C00 + (4 * (P))) +#define IXGBE_PVTEIMS(P) (0x00D00 + (4 * (P))) +#define IXGBE_PVTEIMC(P) (0x00E00 + (4 * (P))) +#define IXGBE_PVTEIAC(P) (0x00F00 + (4 * (P))) +#define IXGBE_PVTEIAM(P) (0x04D00 + (4 * (P))) +#define IXGBE_PVTEITR(P) (((P) < 24) ? (0x00820 + ((P) * 4)) : \ + (0x012300 + (((P) - 24) * 4))) +#define IXGBE_PVTIVAR(P) (0x12500 + (4 * (P))) +#define IXGBE_PVTIVAR_MISC(P) (0x04E00 + (4 * (P))) +#define IXGBE_PVTRSCINT(P) (0x12000 + (4 * (P))) +#define IXGBE_VFPBACL(P) (0x110C8 + (4 * (P))) +#define IXGBE_PVFRDBAL(P) ((P < 64) ? (0x01000 + (0x40 * (P))) \ + : (0x0D000 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDBAH(P) ((P < 64) ? (0x01004 + (0x40 * (P))) \ + : (0x0D004 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDLEN(P) ((P < 64) ? (0x01008 + (0x40 * (P))) \ + : (0x0D008 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDH(P) ((P < 64) ? (0x01010 + (0x40 * (P))) \ + : (0x0D010 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDT(P) ((P < 64) ? (0x01018 + (0x40 * (P))) \ + : (0x0D018 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRXDCTL(P) ((P < 64) ? (0x01028 + (0x40 * (P))) \ + : (0x0D028 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFSRRCTL(P) ((P < 64) ? (0x01014 + (0x40 * (P))) \ + : (0x0D014 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFPSRTYPE(P) (0x0EA00 + (4 * (P))) +#define IXGBE_PVFTDBAL(P) (0x06000 + (0x40 * (P))) +#define IXGBE_PVFTDBAH(P) (0x06004 + (0x40 * (P))) +#define IXGBE_PVFTDLEN(P) (0x06008 + (0x40 * (P))) +#define IXGBE_PVFTDH(P) (0x06010 + (0x40 * (P))) +#define IXGBE_PVFTDT(P) (0x06018 + (0x40 * (P))) +#define IXGBE_PVFTXDCTL(P) (0x06028 + (0x40 * (P))) +#define IXGBE_PVFTDWBAL(P) (0x06038 + (0x40 * (P))) +#define IXGBE_PVFTDWBAH(P) (0x0603C + (0x40 * (P))) +#define IXGBE_PVFDCA_RXCTRL(P) (((P) < 64) ? (0x0100C + (0x40 * (P))) \ + : (0x0D00C + (0x40 * ((P) - 64)))) +#define IXGBE_PVFDCA_TXCTRL(P) (0x0600C + (0x40 * (P))) +#define IXGBE_PVFGPRC(x) (0x0101C + (0x40 * (x))) +#define IXGBE_PVFGPTC(x) (0x08300 + (0x04 * (x))) +#define IXGBE_PVFGORC_LSB(x) (0x01020 + (0x40 * (x))) +#define IXGBE_PVFGORC_MSB(x) (0x0D020 + (0x40 * (x))) +#define IXGBE_PVFGOTC_LSB(x) (0x08400 + (0x08 * (x))) +#define IXGBE_PVFGOTC_MSB(x) (0x08404 + (0x08 * (x))) +#define IXGBE_PVFMPRC(x) (0x0D01C + (0x40 * (x))) + +#define IXGBE_PVFTDWBALn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDWBAL((q_per_pool)*(vf_number) + (vf_q_index))) +#define IXGBE_PVFTDWBAHn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDWBAH((q_per_pool)*(vf_number) + (vf_q_index))) + +#define IXGBE_PVFTDHn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDH((q_per_pool)*(vf_number) + (vf_q_index))) +#define IXGBE_PVFTDTn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDT((q_per_pool)*(vf_number) + (vf_q_index))) + +/* Little Endian defines */ +#ifndef __le16 +#define __le16 u16 +#endif +#ifndef __le32 +#define __le32 u32 +#endif +#ifndef __le64 +#define __le64 u64 + +#endif +#ifndef __be16 +/* Big Endian defines */ +#define __be16 u16 +#define __be32 u32 +#define __be64 u64 + +#endif +enum ixgbe_fdir_pballoc_type { + IXGBE_FDIR_PBALLOC_NONE = 0, + IXGBE_FDIR_PBALLOC_64K = 1, + IXGBE_FDIR_PBALLOC_128K = 2, + IXGBE_FDIR_PBALLOC_256K = 3, +}; + +/* Flow Director register values */ +#define IXGBE_FDIRCTRL_PBALLOC_64K 0x00000001 +#define IXGBE_FDIRCTRL_PBALLOC_128K 0x00000002 +#define IXGBE_FDIRCTRL_PBALLOC_256K 0x00000003 +#define IXGBE_FDIRCTRL_INIT_DONE 0x00000008 +#define IXGBE_FDIRCTRL_PERFECT_MATCH 0x00000010 +#define IXGBE_FDIRCTRL_REPORT_STATUS 0x00000020 +#define IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS 0x00000080 +#define IXGBE_FDIRCTRL_DROP_Q_SHIFT 8 +#define IXGBE_FDIRCTRL_DROP_Q_MASK 0x00007F00 +#define IXGBE_FDIRCTRL_FLEX_SHIFT 16 +#define IXGBE_FDIRCTRL_DROP_NO_MATCH 0x00008000 +#define IXGBE_FDIRCTRL_FILTERMODE_SHIFT 21 +#define IXGBE_FDIRCTRL_FILTERMODE_MACVLAN 0x0001 /* bit 23:21, 001b */ +#define IXGBE_FDIRCTRL_FILTERMODE_CLOUD 0x0002 /* bit 23:21, 010b */ +#define IXGBE_FDIRCTRL_SEARCHLIM 0x00800000 +#define IXGBE_FDIRCTRL_FILTERMODE_MASK 0x00E00000 +#define IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT 24 +#define IXGBE_FDIRCTRL_FULL_THRESH_MASK 0xF0000000 +#define IXGBE_FDIRCTRL_FULL_THRESH_SHIFT 28 + +#define IXGBE_FDIRTCPM_DPORTM_SHIFT 16 +#define IXGBE_FDIRUDPM_DPORTM_SHIFT 16 +#define IXGBE_FDIRIP6M_DIPM_SHIFT 16 +#define IXGBE_FDIRM_VLANID 0x00000001 +#define IXGBE_FDIRM_VLANP 0x00000002 +#define IXGBE_FDIRM_POOL 0x00000004 +#define IXGBE_FDIRM_L4P 0x00000008 +#define IXGBE_FDIRM_FLEX 0x00000010 +#define IXGBE_FDIRM_DIPv6 0x00000020 +#define IXGBE_FDIRM_L3P 0x00000040 + +#define IXGBE_FDIRIP6M_INNER_MAC 0x03F0 /* bit 9:4 */ +#define IXGBE_FDIRIP6M_TUNNEL_TYPE 0x0800 /* bit 11 */ +#define IXGBE_FDIRIP6M_TNI_VNI 0xF000 /* bit 15:12 */ +#define IXGBE_FDIRIP6M_TNI_VNI_24 0x1000 /* bit 12 */ +#define IXGBE_FDIRIP6M_ALWAYS_MASK 0x040F /* bit 10, 3:0 */ + +#define IXGBE_FDIRFREE_FREE_MASK 0xFFFF +#define IXGBE_FDIRFREE_FREE_SHIFT 0 +#define IXGBE_FDIRFREE_COLL_MASK 0x7FFF0000 +#define IXGBE_FDIRFREE_COLL_SHIFT 16 +#define IXGBE_FDIRLEN_MAXLEN_MASK 0x3F +#define IXGBE_FDIRLEN_MAXLEN_SHIFT 0 +#define IXGBE_FDIRLEN_MAXHASH_MASK 0x7FFF0000 +#define IXGBE_FDIRLEN_MAXHASH_SHIFT 16 +#define IXGBE_FDIRUSTAT_ADD_MASK 0xFFFF +#define IXGBE_FDIRUSTAT_ADD_SHIFT 0 +#define IXGBE_FDIRUSTAT_REMOVE_MASK 0xFFFF0000 +#define IXGBE_FDIRUSTAT_REMOVE_SHIFT 16 +#define IXGBE_FDIRFSTAT_FADD_MASK 0x00FF +#define IXGBE_FDIRFSTAT_FADD_SHIFT 0 +#define IXGBE_FDIRFSTAT_FREMOVE_MASK 0xFF00 +#define IXGBE_FDIRFSTAT_FREMOVE_SHIFT 8 +#define IXGBE_FDIRPORT_DESTINATION_SHIFT 16 +#define IXGBE_FDIRVLAN_FLEX_SHIFT 16 +#define IXGBE_FDIRHASH_BUCKET_VALID_SHIFT 15 +#define IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT 16 + +#define IXGBE_FDIRCMD_CMD_MASK 0x00000003 +#define IXGBE_FDIRCMD_CMD_ADD_FLOW 0x00000001 +#define IXGBE_FDIRCMD_CMD_REMOVE_FLOW 0x00000002 +#define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT 0x00000003 +#define IXGBE_FDIRCMD_FILTER_VALID 0x00000004 +#define IXGBE_FDIRCMD_FILTER_UPDATE 0x00000008 +#define IXGBE_FDIRCMD_IPv6DMATCH 0x00000010 +#define IXGBE_FDIRCMD_L4TYPE_UDP 0x00000020 +#define IXGBE_FDIRCMD_L4TYPE_TCP 0x00000040 +#define IXGBE_FDIRCMD_L4TYPE_SCTP 0x00000060 +#define IXGBE_FDIRCMD_IPV6 0x00000080 +#define IXGBE_FDIRCMD_CLEARHT 0x00000100 +#define IXGBE_FDIRCMD_DROP 0x00000200 +#define IXGBE_FDIRCMD_INT 0x00000400 +#define IXGBE_FDIRCMD_LAST 0x00000800 +#define IXGBE_FDIRCMD_COLLISION 0x00001000 +#define IXGBE_FDIRCMD_QUEUE_EN 0x00008000 +#define IXGBE_FDIRCMD_FLOW_TYPE_SHIFT 5 +#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16 +#define IXGBE_FDIRCMD_TUNNEL_FILTER_SHIFT 23 +#define IXGBE_FDIRCMD_VT_POOL_SHIFT 24 +#define IXGBE_FDIR_INIT_DONE_POLL 10 +#define IXGBE_FDIRCMD_CMD_POLL 10 +#define IXGBE_FDIRCMD_TUNNEL_FILTER 0x00800000 +#define IXGBE_FDIR_DROP_QUEUE 127 + +/* Manageablility Host Interface defines */ +#define IXGBE_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */ +#define IXGBE_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */ +#define IXGBE_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */ +#define IXGBE_HI_FLASH_ERASE_TIMEOUT 1000 /* Process Erase command limit */ +#define IXGBE_HI_FLASH_UPDATE_TIMEOUT 5000 /* Process Update command limit */ +#define IXGBE_HI_FLASH_APPLY_TIMEOUT 0 /* Process Apply command limit */ +#define IXGBE_HI_PHY_MGMT_REQ_TIMEOUT 2000 /* Wait up to 2 seconds */ + +/* CEM Support */ +#define FW_CEM_HDR_LEN 0x4 +#define FW_CEM_CMD_DRIVER_INFO 0xDD +#define FW_CEM_CMD_DRIVER_INFO_LEN 0x5 +#define FW_CEM_CMD_RESERVED 0X0 +#define FW_CEM_UNUSED_VER 0x0 +#define FW_CEM_MAX_RETRIES 3 +#define FW_CEM_RESP_STATUS_SUCCESS 0x1 +#define FW_CEM_DRIVER_VERSION_SIZE 39 /* +9 would send 48 bytes to fw */ +#define FW_READ_SHADOW_RAM_CMD 0x31 +#define FW_READ_SHADOW_RAM_LEN 0x6 +#define FW_WRITE_SHADOW_RAM_CMD 0x33 +#define FW_WRITE_SHADOW_RAM_LEN 0xA /* 8 plus 1 WORD to write */ +#define FW_SHADOW_RAM_DUMP_CMD 0x36 +#define FW_SHADOW_RAM_DUMP_LEN 0 +#define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ +#define FW_NVM_DATA_OFFSET 3 +#define FW_ANVM_DATA_OFFSET 3 +#define FW_MAX_READ_BUFFER_SIZE 1024 +#define FW_DISABLE_RXEN_CMD 0xDE +#define FW_DISABLE_RXEN_LEN 0x1 +#define FW_PHY_MGMT_REQ_CMD 0x20 +#define FW_PHY_TOKEN_REQ_CMD 0xA +#define FW_PHY_TOKEN_REQ_LEN 2 +#define FW_PHY_TOKEN_REQ 0 +#define FW_PHY_TOKEN_REL 1 +#define FW_PHY_TOKEN_OK 1 +#define FW_PHY_TOKEN_RETRY 0x80 +#define FW_PHY_TOKEN_DELAY 5 /* milliseconds */ +#define FW_PHY_TOKEN_WAIT 5 /* seconds */ +#define FW_PHY_TOKEN_RETRIES ((FW_PHY_TOKEN_WAIT * 1000) / FW_PHY_TOKEN_DELAY) +#define FW_INT_PHY_REQ_CMD 0xB +#define FW_INT_PHY_REQ_LEN 10 +#define FW_INT_PHY_REQ_READ 0 +#define FW_INT_PHY_REQ_WRITE 1 +#define FW_PHY_ACT_REQ_CMD 5 +#define FW_PHY_ACT_DATA_COUNT 4 +#define FW_PHY_ACT_REQ_LEN (4 + 4 * FW_PHY_ACT_DATA_COUNT) +#define FW_PHY_ACT_INIT_PHY 1 +#define FW_PHY_ACT_SETUP_LINK 2 +#define FW_PHY_ACT_LINK_SPEED_10 (1u << 0) +#define FW_PHY_ACT_LINK_SPEED_100 (1u << 1) +#define FW_PHY_ACT_LINK_SPEED_1G (1u << 2) +#define FW_PHY_ACT_LINK_SPEED_2_5G (1u << 3) +#define FW_PHY_ACT_LINK_SPEED_5G (1u << 4) +#define FW_PHY_ACT_LINK_SPEED_10G (1u << 5) +#define FW_PHY_ACT_LINK_SPEED_20G (1u << 6) +#define FW_PHY_ACT_LINK_SPEED_25G (1u << 7) +#define FW_PHY_ACT_LINK_SPEED_40G (1u << 8) +#define FW_PHY_ACT_LINK_SPEED_50G (1u << 9) +#define FW_PHY_ACT_LINK_SPEED_100G (1u << 10) +#define FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT 16 +#define FW_PHY_ACT_SETUP_LINK_PAUSE_MASK (3u << \ + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT) +#define FW_PHY_ACT_SETUP_LINK_PAUSE_NONE 0u +#define FW_PHY_ACT_SETUP_LINK_PAUSE_TX 1u +#define FW_PHY_ACT_SETUP_LINK_PAUSE_RX 2u +#define FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX 3u +#define FW_PHY_ACT_SETUP_LINK_LP (1u << 18) +#define FW_PHY_ACT_SETUP_LINK_HP (1u << 19) +#define FW_PHY_ACT_SETUP_LINK_EEE (1u << 20) +#define FW_PHY_ACT_SETUP_LINK_AN (1u << 22) +#define FW_PHY_ACT_SETUP_LINK_RSP_DOWN (1u << 0) +#define FW_PHY_ACT_GET_LINK_INFO 3 +#define FW_PHY_ACT_GET_LINK_INFO_EEE (1u << 19) +#define FW_PHY_ACT_GET_LINK_INFO_FC_TX (1u << 20) +#define FW_PHY_ACT_GET_LINK_INFO_FC_RX (1u << 21) +#define FW_PHY_ACT_GET_LINK_INFO_POWER (1u << 22) +#define FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE (1u << 24) +#define FW_PHY_ACT_GET_LINK_INFO_TEMP (1u << 25) +#define FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX (1u << 28) +#define FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX (1u << 29) +#define FW_PHY_ACT_FORCE_LINK_DOWN 4 +#define FW_PHY_ACT_FORCE_LINK_DOWN_OFF (1u << 0) +#define FW_PHY_ACT_PHY_SW_RESET 5 +#define FW_PHY_ACT_PHY_HW_RESET 6 +#define FW_PHY_ACT_GET_PHY_INFO 7 +#define FW_PHY_ACT_UD_2 0x1002 +#define FW_PHY_ACT_UD_2_10G_KR_EEE (1u << 6) +#define FW_PHY_ACT_UD_2_10G_KX4_EEE (1u << 5) +#define FW_PHY_ACT_UD_2_1G_KX_EEE (1u << 4) +#define FW_PHY_ACT_UD_2_10G_T_EEE (1u << 3) +#define FW_PHY_ACT_UD_2_1G_T_EEE (1u << 2) +#define FW_PHY_ACT_UD_2_100M_TX_EEE (1u << 1) +#define FW_PHY_ACT_RETRIES 50 +#define FW_PHY_INFO_SPEED_MASK 0xFFFu +#define FW_PHY_INFO_ID_HI_MASK 0xFFFF0000u +#define FW_PHY_INFO_ID_LO_MASK 0x0000FFFFu + +#define IXGBE_SR_IMMEDIATE_VALUES_PTR 0x4E + +/* Host Interface Command Structures */ + +#pragma pack(push, 1) + +struct ixgbe_hic_hdr { + u8 cmd; + u8 buf_len; + union { + u8 cmd_resv; + u8 ret_status; + } cmd_or_resp; + u8 checksum; +}; + +struct ixgbe_hic_hdr2_req { + u8 cmd; + u8 buf_lenh; + u8 buf_lenl; + u8 checksum; +}; + +struct ixgbe_hic_hdr2_rsp { + u8 cmd; + u8 buf_lenl; + u8 buf_lenh_status; /* 7-5: high bits of buf_len, 4-0: status */ + u8 checksum; +}; + +union ixgbe_hic_hdr2 { + struct ixgbe_hic_hdr2_req req; + struct ixgbe_hic_hdr2_rsp rsp; +}; + +struct ixgbe_hic_drv_info { + struct ixgbe_hic_hdr hdr; + u8 port_num; + u8 ver_sub; + u8 ver_build; + u8 ver_min; + u8 ver_maj; + u8 pad; /* end spacing to ensure length is mult. of dword */ + u16 pad2; /* end spacing to ensure length is mult. of dword2 */ +}; + +struct ixgbe_hic_drv_info2 { + struct ixgbe_hic_hdr hdr; + u8 port_num; + u8 ver_sub; + u8 ver_build; + u8 ver_min; + u8 ver_maj; + char driver_string[FW_CEM_DRIVER_VERSION_SIZE]; +}; + +/* These need to be dword aligned */ +struct ixgbe_hic_read_shadow_ram { + union ixgbe_hic_hdr2 hdr; + u32 address; + u16 length; + u16 pad2; + u16 data; + u16 pad3; +}; + +struct ixgbe_hic_write_shadow_ram { + union ixgbe_hic_hdr2 hdr; + u32 address; + u16 length; + u16 pad2; + u16 data; + u16 pad3; +}; + +struct ixgbe_hic_disable_rxen { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 pad2; + u16 pad3; +}; + +struct ixgbe_hic_phy_token_req { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 command_type; + u16 pad; +}; + +struct ixgbe_hic_internal_phy_req { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 command_type; + __be16 address; + u16 rsv1; + __be32 write_data; + u16 pad; +}; + +struct ixgbe_hic_internal_phy_resp { + struct ixgbe_hic_hdr hdr; + __be32 read_data; +}; + +struct ixgbe_hic_phy_activity_req { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 pad; + __le16 activity_id; + __be32 data[FW_PHY_ACT_DATA_COUNT]; +}; + +struct ixgbe_hic_phy_activity_resp { + struct ixgbe_hic_hdr hdr; + __be32 data[FW_PHY_ACT_DATA_COUNT]; +}; + +#pragma pack(pop) + +/* Transmit Descriptor - Legacy */ +struct ixgbe_legacy_tx_desc { + u64 buffer_addr; /* Address of the descriptor's data buffer */ + union { + __le32 data; + struct { + __le16 length; /* Data buffer length */ + u8 cso; /* Checksum offset */ + u8 cmd; /* Descriptor control */ + } flags; + } lower; + union { + __le32 data; + struct { + u8 status; /* Descriptor status */ + u8 css; /* Checksum start */ + __le16 vlan; + } fields; + } upper; +}; + +/* Transmit Descriptor - Advanced */ +union ixgbe_adv_tx_desc { + struct { + __le64 buffer_addr; /* Address of descriptor's data buf */ + __le32 cmd_type_len; + __le32 olinfo_status; + } read; + struct { + __le64 rsvd; /* Reserved */ + __le32 nxtseq_seed; + __le32 status; + } wb; +}; + +/* Receive Descriptor - Legacy */ +struct ixgbe_legacy_rx_desc { + __le64 buffer_addr; /* Address of the descriptor's data buffer */ + __le16 length; /* Length of data DMAed into data buffer */ + __le16 csum; /* Packet checksum */ + u8 status; /* Descriptor status */ + u8 errors; /* Descriptor Errors */ + __le16 vlan; +}; + +/* Receive Descriptor - Advanced */ +union ixgbe_adv_rx_desc { + struct { + __le64 pkt_addr; /* Packet buffer address */ + __le64 hdr_addr; /* Header buffer address */ + } read; + struct { + struct { + union { + __le32 data; + struct { + __le16 pkt_info; /* RSS, Pkt type */ + __le16 hdr_info; /* Splithdr, hdrlen */ + } hs_rss; + } lo_dword; + union { + __le32 rss; /* RSS Hash */ + struct { + __le16 ip_id; /* IP id */ + __le16 csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + __le32 status_error; /* ext status/error */ + __le16 length; /* Packet length */ + __le16 vlan; /* VLAN tag */ + } upper; + } wb; /* writeback */ +}; + +/* Context descriptors */ +struct ixgbe_adv_tx_context_desc { + __le32 vlan_macip_lens; + __le32 seqnum_seed; + __le32 type_tucmd_mlhl; + __le32 mss_l4len_idx; +}; + +/* Adv Transmit Descriptor Config Masks */ +#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */ +#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */ +#define IXGBE_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 time stamp */ +#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */ +#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */ +#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */ +#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Adv Context Desc */ +#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Adv Data Descriptor */ +#define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */ +#define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */ +#define IXGBE_ADVTXD_DCMD_RS IXGBE_TXD_CMD_RS /* Report Status */ +#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */ +#define IXGBE_ADVTXD_DCMD_DEXT IXGBE_TXD_CMD_DEXT /* Desc ext 1=Adv */ +#define IXGBE_ADVTXD_DCMD_VLE IXGBE_TXD_CMD_VLE /* VLAN pkt enable */ +#define IXGBE_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */ +#define IXGBE_ADVTXD_STAT_DD IXGBE_TXD_STAT_DD /* Descriptor Done */ +#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED pres in WB */ +#define IXGBE_ADVTXD_STAT_RSV 0x0000000C /* STA Reserved */ +#define IXGBE_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */ +#define IXGBE_ADVTXD_CC 0x00000080 /* Check Context */ +#define IXGBE_ADVTXD_POPTS_SHIFT 8 /* Adv desc POPTS shift */ +#define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \ + IXGBE_ADVTXD_POPTS_SHIFT) +#define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \ + IXGBE_ADVTXD_POPTS_SHIFT) +#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */ +/* 1st&Last TSO-full iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 +#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */ +#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ +#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ +#define IXGBE_ADVTXD_MACLEN_MASK (0x7F << IXGBE_ADVTXD_MACLEN_SHIFT) /* Adv ctxt desc mac len mask */ +#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */ +#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ +#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ +#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ +#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ +#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ +#define IXGBE_ADVTXD_TUCMD_L4T_RSV 0x00001800 /* RSV L4 Packet TYPE */ +#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /* req Markers and CRC */ +#define IXGBE_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */ +#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */ +#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */ +#define IXGBE_ADVTXT_TUCMD_FCOE 0x00008000 /* FCoE Frame Type */ +#define IXGBE_ADVTXD_FCOEF_EOF_MASK (0x3 << 10) /* FC EOF index */ +#define IXGBE_ADVTXD_FCOEF_SOF ((1 << 2) << 10) /* FC SOF index */ +#define IXGBE_ADVTXD_FCOEF_PARINC ((1 << 3) << 10) /* Rel_Off in F_CTL */ +#define IXGBE_ADVTXD_FCOEF_ORIE ((1 << 4) << 10) /* Orientation End */ +#define IXGBE_ADVTXD_FCOEF_ORIS ((1 << 5) << 10) /* Orientation Start */ +#define IXGBE_ADVTXD_FCOEF_EOF_N (0x0 << 10) /* 00: EOFn */ +#define IXGBE_ADVTXD_FCOEF_EOF_T (0x1 << 10) /* 01: EOFt */ +#define IXGBE_ADVTXD_FCOEF_EOF_NI (0x2 << 10) /* 10: EOFni */ +#define IXGBE_ADVTXD_FCOEF_EOF_A (0x3 << 10) /* 11: EOFa */ +#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ +#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ + +#define IXGBE_ADVTXD_OUTER_IPLEN 16 /* Adv ctxt OUTERIPLEN shift */ +#define IXGBE_ADVTXD_TUNNEL_LEN 24 /* Adv ctxt TUNNELLEN shift */ +#define IXGBE_ADVTXD_TUNNEL_TYPE_SHIFT 16 /* Adv Tx Desc Tunnel Type shift */ +#define IXGBE_ADVTXD_OUTERIPCS_SHIFT 17 /* Adv Tx Desc OUTERIPCS Shift */ +#define IXGBE_ADVTXD_TUNNEL_TYPE_NVGRE 1 /* Adv Tx Desc Tunnel Type NVGRE */ +/* Adv Tx Desc OUTERIPCS Shift for X550EM_a */ +#define IXGBE_ADVTXD_OUTERIPCS_SHIFT_X550EM_a 26 +/* Autonegotiation advertised speeds */ +typedef u32 ixgbe_autoneg_advertised; +/* Link speed */ +typedef u32 ixgbe_link_speed; +#define IXGBE_LINK_SPEED_UNKNOWN 0 +#define IXGBE_LINK_SPEED_10_FULL 0x0002 +#define IXGBE_LINK_SPEED_100_FULL 0x0008 +#define IXGBE_LINK_SPEED_1GB_FULL 0x0020 +#define IXGBE_LINK_SPEED_2_5GB_FULL 0x0400 +#define IXGBE_LINK_SPEED_5GB_FULL 0x0800 +#define IXGBE_LINK_SPEED_10GB_FULL 0x0080 +#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \ + IXGBE_LINK_SPEED_10GB_FULL) +#define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \ + IXGBE_LINK_SPEED_1GB_FULL | \ + IXGBE_LINK_SPEED_10GB_FULL) + +/* Physical layer type */ +typedef u64 ixgbe_physical_layer; +#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0 +#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x00001 +#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x00002 +#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x00004 +#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x00008 +#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x00010 +#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x00020 +#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x00040 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x00080 +#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x00100 +#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x00200 +#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x00400 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x00800 +#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x01000 +#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x02000 +#define IXGBE_PHYSICAL_LAYER_1000BASE_SX 0x04000 +#define IXGBE_PHYSICAL_LAYER_10BASE_T 0x08000 +#define IXGBE_PHYSICAL_LAYER_2500BASE_KX 0x10000 +#define IXGBE_PHYSICAL_LAYER_2500BASE_T 0x20000 +#define IXGBE_PHYSICAL_LAYER_5000BASE_T 0x40000 + +/* Flow Control Data Sheet defined values + * Calculation and defines taken from 802.1bb Annex O + */ + +/* BitTimes (BT) conversion */ +#define IXGBE_BT2KB(BT) ((BT + (8 * 1024 - 1)) / (8 * 1024)) +#define IXGBE_B2BT(BT) (BT * 8) + +/* Calculate Delay to respond to PFC */ +#define IXGBE_PFC_D 672 + +/* Calculate Cable Delay */ +#define IXGBE_CABLE_DC 5556 /* Delay Copper */ +#define IXGBE_CABLE_DO 5000 /* Delay Optical */ + +/* Calculate Interface Delay X540 */ +#define IXGBE_PHY_DC 25600 /* Delay 10G BASET */ +#define IXGBE_MAC_DC 8192 /* Delay Copper XAUI interface */ +#define IXGBE_XAUI_DC (2 * 2048) /* Delay Copper Phy */ + +#define IXGBE_ID_X540 (IXGBE_MAC_DC + IXGBE_XAUI_DC + IXGBE_PHY_DC) + +/* Calculate Interface Delay 82598, 82599 */ +#define IXGBE_PHY_D 12800 +#define IXGBE_MAC_D 4096 +#define IXGBE_XAUI_D (2 * 1024) + +#define IXGBE_ID (IXGBE_MAC_D + IXGBE_XAUI_D + IXGBE_PHY_D) + +/* Calculate Delay incurred from higher layer */ +#define IXGBE_HD 6144 + +/* Calculate PCI Bus delay for low thresholds */ +#define IXGBE_PCI_DELAY 10000 + +/* Calculate X540 delay value in bit times */ +#define IXGBE_DV_X540(_max_frame_link, _max_frame_tc) \ + ((36 * \ + (IXGBE_B2BT(_max_frame_link) + \ + IXGBE_PFC_D + \ + (2 * IXGBE_CABLE_DC) + \ + (2 * IXGBE_ID_X540) + \ + IXGBE_HD) / 25 + 1) + \ + 2 * IXGBE_B2BT(_max_frame_tc)) + +/* Calculate 82599, 82598 delay value in bit times */ +#define IXGBE_DV(_max_frame_link, _max_frame_tc) \ + ((36 * \ + (IXGBE_B2BT(_max_frame_link) + \ + IXGBE_PFC_D + \ + (2 * IXGBE_CABLE_DC) + \ + (2 * IXGBE_ID) + \ + IXGBE_HD) / 25 + 1) + \ + 2 * IXGBE_B2BT(_max_frame_tc)) + +/* Calculate low threshold delay values */ +#define IXGBE_LOW_DV_X540(_max_frame_tc) \ + (2 * IXGBE_B2BT(_max_frame_tc) + \ + (36 * IXGBE_PCI_DELAY / 25) + 1) +#define IXGBE_LOW_DV(_max_frame_tc) \ + (2 * IXGBE_LOW_DV_X540(_max_frame_tc)) + +/* Software ATR hash keys */ +#define IXGBE_ATR_BUCKET_HASH_KEY 0x3DAD14E2 +#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x174D3614 + +/* Software ATR input stream values and masks */ +#define IXGBE_ATR_HASH_MASK 0x7fff +#define IXGBE_ATR_L4TYPE_MASK 0x3 +#define IXGBE_ATR_L4TYPE_UDP 0x1 +#define IXGBE_ATR_L4TYPE_TCP 0x2 +#define IXGBE_ATR_L4TYPE_SCTP 0x3 +#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4 +#define IXGBE_ATR_L4TYPE_TUNNEL_MASK 0x10 +enum ixgbe_atr_flow_type { + IXGBE_ATR_FLOW_TYPE_IPV4 = 0x0, + IXGBE_ATR_FLOW_TYPE_UDPV4 = 0x1, + IXGBE_ATR_FLOW_TYPE_TCPV4 = 0x2, + IXGBE_ATR_FLOW_TYPE_SCTPV4 = 0x3, + IXGBE_ATR_FLOW_TYPE_IPV6 = 0x4, + IXGBE_ATR_FLOW_TYPE_UDPV6 = 0x5, + IXGBE_ATR_FLOW_TYPE_TCPV6 = 0x6, + IXGBE_ATR_FLOW_TYPE_SCTPV6 = 0x7, + IXGBE_ATR_FLOW_TYPE_TUNNELED_IPV4 = 0x10, + IXGBE_ATR_FLOW_TYPE_TUNNELED_UDPV4 = 0x11, + IXGBE_ATR_FLOW_TYPE_TUNNELED_TCPV4 = 0x12, + IXGBE_ATR_FLOW_TYPE_TUNNELED_SCTPV4 = 0x13, + IXGBE_ATR_FLOW_TYPE_TUNNELED_IPV6 = 0x14, + IXGBE_ATR_FLOW_TYPE_TUNNELED_UDPV6 = 0x15, + IXGBE_ATR_FLOW_TYPE_TUNNELED_TCPV6 = 0x16, + IXGBE_ATR_FLOW_TYPE_TUNNELED_SCTPV6 = 0x17, +}; + +/* Flow Director ATR input struct. */ +union ixgbe_atr_input { + /* + * Byte layout in order, all values with MSB first: + * + * vm_pool - 1 byte + * flow_type - 1 byte + * vlan_id - 2 bytes + * src_ip - 16 bytes + * inner_mac - 6 bytes + * cloud_mode - 2 bytes + * tni_vni - 4 bytes + * dst_ip - 16 bytes + * src_port - 2 bytes + * dst_port - 2 bytes + * flex_bytes - 2 bytes + * bkt_hash - 2 bytes + */ + struct { + u8 vm_pool; + u8 flow_type; + __be16 vlan_id; + __be32 dst_ip[4]; + __be32 src_ip[4]; + u8 inner_mac[6]; + __be16 tunnel_type; + __be32 tni_vni; + __be16 src_port; + __be16 dst_port; + __be16 flex_bytes; + __be16 bkt_hash; + } formatted; + __be32 dword_stream[14]; +}; + +/* Flow Director compressed ATR hash input struct */ +union ixgbe_atr_hash_dword { + struct { + u8 vm_pool; + u8 flow_type; + __be16 vlan_id; + } formatted; + __be32 ip; + struct { + __be16 src; + __be16 dst; + } port; + __be16 flex_bytes; + __be32 dword; +}; + +#define IXGBE_MVALS_INIT(m) \ + IXGBE_CAT(EEC, m), \ + IXGBE_CAT(FLA, m), \ + IXGBE_CAT(GRC, m), \ + IXGBE_CAT(SRAMREL, m), \ + IXGBE_CAT(FACTPS, m), \ + IXGBE_CAT(SWSM, m), \ + IXGBE_CAT(SWFW_SYNC, m), \ + IXGBE_CAT(FWSM, m), \ + IXGBE_CAT(SDP0_GPIEN, m), \ + IXGBE_CAT(SDP1_GPIEN, m), \ + IXGBE_CAT(SDP2_GPIEN, m), \ + IXGBE_CAT(EICR_GPI_SDP0, m), \ + IXGBE_CAT(EICR_GPI_SDP1, m), \ + IXGBE_CAT(EICR_GPI_SDP2, m), \ + IXGBE_CAT(CIAA, m), \ + IXGBE_CAT(CIAD, m), \ + IXGBE_CAT(I2C_CLK_IN, m), \ + IXGBE_CAT(I2C_CLK_OUT, m), \ + IXGBE_CAT(I2C_DATA_IN, m), \ + IXGBE_CAT(I2C_DATA_OUT, m), \ + IXGBE_CAT(I2C_DATA_OE_N_EN, m), \ + IXGBE_CAT(I2C_BB_EN, m), \ + IXGBE_CAT(I2C_CLK_OE_N_EN, m), \ + IXGBE_CAT(I2CCTL, m) + +enum ixgbe_mvals { + IXGBE_MVALS_INIT(_IDX), + IXGBE_MVALS_IDX_LIMIT +}; + +/* + * Unavailable: The FCoE Boot Option ROM is not present in the flash. + * Disabled: Present; boot order is not set for any targets on the port. + * Enabled: Present; boot order is set for at least one target on the port. + */ +enum ixgbe_fcoe_boot_status { + ixgbe_fcoe_bootstatus_disabled = 0, + ixgbe_fcoe_bootstatus_enabled = 1, + ixgbe_fcoe_bootstatus_unavailable = 0xFFFF +}; + +enum ixgbe_eeprom_type { + ixgbe_eeprom_uninitialized = 0, + ixgbe_eeprom_spi, + ixgbe_flash, + ixgbe_eeprom_none /* No NVM support */ +}; + +enum ixgbe_mac_type { + ixgbe_mac_unknown = 0, + ixgbe_mac_82598EB, + ixgbe_mac_82599EB, + ixgbe_mac_X540, + ixgbe_mac_X550, + ixgbe_mac_X550EM_x, + ixgbe_mac_X550EM_a, + ixgbe_mac_E610, + ixgbe_num_macs +}; + +enum ixgbe_phy_type { + ixgbe_phy_unknown = 0, + ixgbe_phy_none, + ixgbe_phy_tn, + ixgbe_phy_aq, + ixgbe_phy_x550em_kr, + ixgbe_phy_x550em_kx4, + ixgbe_phy_x550em_xfi, + ixgbe_phy_x550em_ext_t, + ixgbe_phy_ext_1g_t, + ixgbe_phy_cu_unknown, + ixgbe_phy_qt, + ixgbe_phy_xaui, + ixgbe_phy_nl, + ixgbe_phy_sfp_passive_tyco, + ixgbe_phy_sfp_passive_unknown, + ixgbe_phy_sfp_active_unknown, + ixgbe_phy_sfp_avago, + ixgbe_phy_sfp_ftl, + ixgbe_phy_sfp_ftl_active, + ixgbe_phy_sfp_unknown, + ixgbe_phy_sfp_intel, + ixgbe_phy_qsfp_passive_unknown, + ixgbe_phy_qsfp_active_unknown, + ixgbe_phy_qsfp_intel, + ixgbe_phy_qsfp_unknown, + ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/ + ixgbe_phy_sgmii, + ixgbe_phy_fw, + ixgbe_phy_generic +}; + +/* + * SFP+ module type IDs: + * + * ID Module Type + * ============= + * 0 SFP_DA_CU + * 1 SFP_SR + * 2 SFP_LR + * 3 SFP_DA_CU_CORE0 - 82599-specific + * 4 SFP_DA_CU_CORE1 - 82599-specific + * 5 SFP_SR/LR_CORE0 - 82599-specific + * 6 SFP_SR/LR_CORE1 - 82599-specific + */ +enum ixgbe_sfp_type { + ixgbe_sfp_type_da_cu = 0, + ixgbe_sfp_type_sr = 1, + ixgbe_sfp_type_lr = 2, + ixgbe_sfp_type_da_cu_core0 = 3, + ixgbe_sfp_type_da_cu_core1 = 4, + ixgbe_sfp_type_srlr_core0 = 5, + ixgbe_sfp_type_srlr_core1 = 6, + ixgbe_sfp_type_da_act_lmt_core0 = 7, + ixgbe_sfp_type_da_act_lmt_core1 = 8, + ixgbe_sfp_type_1g_cu_core0 = 9, + ixgbe_sfp_type_1g_cu_core1 = 10, + ixgbe_sfp_type_1g_sx_core0 = 11, + ixgbe_sfp_type_1g_sx_core1 = 12, + ixgbe_sfp_type_1g_lx_core0 = 13, + ixgbe_sfp_type_1g_lx_core1 = 14, + ixgbe_sfp_type_not_present = 0xFFFE, + ixgbe_sfp_type_unknown = 0xFFFF +}; + +enum ixgbe_media_type { + ixgbe_media_type_unknown = 0, + ixgbe_media_type_fiber, + ixgbe_media_type_fiber_qsfp, + ixgbe_media_type_copper, + ixgbe_media_type_backplane, + ixgbe_media_type_cx4, + ixgbe_media_type_virtual, + ixgbe_media_type_da, + ixgbe_media_type_aui +}; + +/* Flow Control Settings */ +enum ixgbe_fc_mode { + ixgbe_fc_none = 0, + ixgbe_fc_rx_pause, + ixgbe_fc_tx_pause, + ixgbe_fc_full, + ixgbe_fc_pfc, + ixgbe_fc_default +}; + +/* Smart Speed Settings */ +#define IXGBE_SMARTSPEED_MAX_RETRIES 3 +enum ixgbe_smart_speed { + ixgbe_smart_speed_auto = 0, + ixgbe_smart_speed_on, + ixgbe_smart_speed_off +}; + +/* PCI bus types */ +enum ixgbe_bus_type { + ixgbe_bus_type_unknown = 0, + ixgbe_bus_type_pci, + ixgbe_bus_type_pcix, + ixgbe_bus_type_pci_express, + ixgbe_bus_type_internal, + ixgbe_bus_type_reserved +}; + +/* PCI bus speeds */ +enum ixgbe_bus_speed { + ixgbe_bus_speed_unknown = 0, + ixgbe_bus_speed_33 = 33, + ixgbe_bus_speed_66 = 66, + ixgbe_bus_speed_100 = 100, + ixgbe_bus_speed_120 = 120, + ixgbe_bus_speed_133 = 133, + ixgbe_bus_speed_2500 = 2500, + ixgbe_bus_speed_5000 = 5000, + ixgbe_bus_speed_8000 = 8000, + ixgbe_bus_speed_16000 = 16000, + ixgbe_bus_speed_reserved +}; + +/* PCI bus widths */ +enum ixgbe_bus_width { + ixgbe_bus_width_unknown = 0, + ixgbe_bus_width_pcie_x1 = 1, + ixgbe_bus_width_pcie_x2 = 2, + ixgbe_bus_width_pcie_x4 = 4, + ixgbe_bus_width_pcie_x8 = 8, + ixgbe_bus_width_32 = 32, + ixgbe_bus_width_64 = 64, + ixgbe_bus_width_reserved +}; + +struct ixgbe_addr_filter_info { + u32 num_mc_addrs; + u32 rar_used_count; + u32 mta_in_use; + u32 overflow_promisc; + bool user_set_promisc; +}; + +/* Bus parameters */ +struct ixgbe_bus_info { + enum ixgbe_bus_speed speed; + enum ixgbe_bus_width width; + enum ixgbe_bus_type type; + + u16 func; + u8 lan_id; + u16 instance_id; +}; + +/* Flow control parameters */ +struct ixgbe_fc_info { + u32 high_water[IXGBE_DCB_MAX_TRAFFIC_CLASS]; /* Flow Ctrl High-water */ + u32 low_water[IXGBE_DCB_MAX_TRAFFIC_CLASS]; /* Flow Ctrl Low-water */ + u16 pause_time; /* Flow Control Pause timer */ + bool send_xon; /* Flow control send XON */ + bool strict_ieee; /* Strict IEEE mode */ + bool disable_fc_autoneg; /* Do not autonegotiate FC */ + bool fc_was_autonegged; /* Is current_mode the result of autonegging? */ + enum ixgbe_fc_mode current_mode; /* FC mode in effect */ + enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */ +}; + +/* Statistics counters collected by the MAC */ +struct ixgbe_hw_stats { + u64 crcerrs; + u64 illerrc; + u64 errbc; + u64 mspdc; + u64 mpctotal; + u64 mpc[8]; + u64 mlfc; + u64 mrfc; + u64 rlec; + u64 tlpic; + u64 rlpic; + u64 lxontxc; + u64 lxonrxc; + u64 lxofftxc; + u64 lxoffrxc; + u64 pxontxc[8]; + u64 pxonrxc[8]; + u64 pxofftxc[8]; + u64 pxoffrxc[8]; + u64 prc64; + u64 prc127; + u64 prc255; + u64 prc511; + u64 prc1023; + u64 prc1522; + u64 gprc; + u64 bprc; + u64 mprc; + u64 gptc; + u64 gorc; + u64 gotc; + u64 rnbc[8]; + u64 ruc; + u64 rfc; + u64 roc; + u64 rjc; + u64 mngprc; + u64 mngpdc; + u64 mngptc; + u64 tor; + u64 tpr; + u64 tpt; + u64 ptc64; + u64 ptc127; + u64 ptc255; + u64 ptc511; + u64 ptc1023; + u64 ptc1522; + u64 mptc; + u64 bptc; + u64 xec; + u64 qprc[16]; + u64 qptc[16]; + u64 qbrc[16]; + u64 qbtc[16]; + u64 qprdc[16]; + u64 pxon2offc[8]; + u64 fdirustat_add; + u64 fdirustat_remove; + u64 fdirfstat_fadd; + u64 fdirfstat_fremove; + u64 fdirmatch; + u64 fdirmiss; + u64 fccrc; + u64 fclast; + u64 fcoerpdc; + u64 fcoeprc; + u64 fcoeptc; + u64 fcoedwrc; + u64 fcoedwtc; + u64 fcoe_noddp; + u64 fcoe_noddp_ext_buff; + u64 ldpcec; + u64 pcrc8ec; + u64 b2ospc; + u64 b2ogprc; + u64 o2bgptc; + u64 o2bspc; +}; + +/* NVM Update commands */ +#define IXGBE_NVMUPD_CMD_REG_READ 0x0000000B +#define IXGBE_NVMUPD_CMD_REG_WRITE 0x0000000C + +/* NVM Update features API */ +#define IXGBE_NVMUPD_FEATURES_API_VER_MAJOR 0 +#define IXGBE_NVMUPD_FEATURES_API_VER_MINOR 0 +#define IXGBE_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN 12 +#define IXGBE_NVMUPD_EXEC_FEATURES 0xe +#define IXGBE_NVMUPD_FEATURE_FLAT_NVM_SUPPORT BIT(0) +#define IXGBE_NVMUPD_FEATURE_REGISTER_ACCESS_SUPPORT BIT(1) + +#define IXGBE_NVMUPD_MOD_PNT_MASK 0xFF + +struct ixgbe_nvm_access { + u32 command; + u32 config; + u32 offset; /* in bytes */ + u32 data_size; /* in bytes */ + u8 data[1]; +}; + +struct ixgbe_nvm_features { + u8 major; + u8 minor; + u16 size; + u8 features[IXGBE_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN]; +}; + +/* forward declaration */ +struct ixgbe_hw; + +/* iterator type for walking multicast address lists */ +typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr, + u32 *vmdq); + +/* Function pointer table */ +struct ixgbe_eeprom_operations { + s32 (*init_params)(struct ixgbe_hw *); + s32 (*read)(struct ixgbe_hw *, u16, u16 *); + s32 (*read_buffer)(struct ixgbe_hw *, u16, u16, u16 *); + s32 (*write)(struct ixgbe_hw *, u16, u16); + s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *); + s32 (*validate_checksum)(struct ixgbe_hw *, u16 *); + s32 (*update_checksum)(struct ixgbe_hw *); + s32 (*calc_checksum)(struct ixgbe_hw *); + s32 (*read_pba_string)(struct ixgbe_hw *, u8 *, u32); +}; + +struct ixgbe_mac_operations { + s32 (*init_hw)(struct ixgbe_hw *); + s32 (*reset_hw)(struct ixgbe_hw *); + s32 (*start_hw)(struct ixgbe_hw *); + s32 (*clear_hw_cntrs)(struct ixgbe_hw *); + enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); + u64 (*get_supported_physical_layer)(struct ixgbe_hw *); + s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*get_device_caps)(struct ixgbe_hw *, u16 *); + s32 (*get_wwn_prefix)(struct ixgbe_hw *, u16 *, u16 *); + s32 (*get_fcoe_boot_status)(struct ixgbe_hw *, u16 *); + s32 (*stop_adapter)(struct ixgbe_hw *); + s32 (*get_bus_info)(struct ixgbe_hw *); + void (*set_lan_id)(struct ixgbe_hw *); + s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*); + s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8); + s32 (*setup_sfp)(struct ixgbe_hw *); + s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); + s32 (*disable_sec_rx_path)(struct ixgbe_hw *); + s32 (*enable_sec_rx_path)(struct ixgbe_hw *); + s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32); + void (*release_swfw_sync)(struct ixgbe_hw *, u32); + void (*init_swfw_sync)(struct ixgbe_hw *); + s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *); + s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool); + + /* Link */ + void (*disable_tx_laser)(struct ixgbe_hw *); + void (*enable_tx_laser)(struct ixgbe_hw *); + void (*flap_tx_laser)(struct ixgbe_hw *); + s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool); + s32 (*setup_mac_link)(struct ixgbe_hw *, ixgbe_link_speed, bool); + s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); + s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, + bool *); + void (*set_rate_select_speed)(struct ixgbe_hw *, ixgbe_link_speed); + + /* Packet Buffer manipulation */ + void (*setup_rxpba)(struct ixgbe_hw *, int, u32, int); + + /* LED */ + s32 (*led_on)(struct ixgbe_hw *, u32); + s32 (*led_off)(struct ixgbe_hw *, u32); + s32 (*blink_led_start)(struct ixgbe_hw *, u32); + s32 (*blink_led_stop)(struct ixgbe_hw *, u32); + s32 (*init_led_link_act)(struct ixgbe_hw *); + + /* RAR, Multicast, VLAN */ + s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32); + s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *); + s32 (*clear_rar)(struct ixgbe_hw *, u32); + s32 (*insert_mac_addr)(struct ixgbe_hw *, u8 *, u32); + s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); + s32 (*set_vmdq_san_mac)(struct ixgbe_hw *, u32); + s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); + s32 (*init_rx_addrs)(struct ixgbe_hw *); + s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32, + ixgbe_mc_addr_itr); + s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32, + ixgbe_mc_addr_itr, bool clear); + s32 (*enable_mc)(struct ixgbe_hw *); + s32 (*disable_mc)(struct ixgbe_hw *); + s32 (*clear_vfta)(struct ixgbe_hw *); + s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool, bool); + s32 (*set_vlvf)(struct ixgbe_hw *, u32, u32, bool, u32 *, u32, + bool); + s32 (*init_uta_tables)(struct ixgbe_hw *); + void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int); + void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int); + s32 (*toggle_txdctl)(struct ixgbe_hw *hw, u32 vf_index); + + /* Flow Control */ + s32 (*fc_enable)(struct ixgbe_hw *); + s32 (*setup_fc)(struct ixgbe_hw *); + void (*fc_autoneg)(struct ixgbe_hw *); + + /* Manageability interface */ + s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8, u16, + const char *); + s32 (*get_thermal_sensor_data)(struct ixgbe_hw *); + s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw); + void (*get_rtrup2tc)(struct ixgbe_hw *hw, u8 *map); + void (*disable_rx)(struct ixgbe_hw *hw); + void (*enable_rx)(struct ixgbe_hw *hw); + void (*set_source_address_pruning)(struct ixgbe_hw *, bool, + unsigned int); + void (*set_ethertype_anti_spoofing)(struct ixgbe_hw *, bool, int); + s32 (*dmac_update_tcs)(struct ixgbe_hw *hw); + s32 (*dmac_config_tcs)(struct ixgbe_hw *hw); + s32 (*dmac_config)(struct ixgbe_hw *hw); + s32 (*setup_eee)(struct ixgbe_hw *hw, bool enable_eee); + s32 (*read_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32 *); + s32 (*write_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32); + void (*disable_mdd)(struct ixgbe_hw *hw); + void (*enable_mdd)(struct ixgbe_hw *hw); + void (*mdd_event)(struct ixgbe_hw *hw, u32 *vf_bitmap); + void (*restore_mdd_vf)(struct ixgbe_hw *hw, u32 vf); + bool (*fw_recovery_mode)(struct ixgbe_hw *hw); + bool (*fw_rollback_mode)(struct ixgbe_hw *hw); + bool (*get_fw_tsam_mode)(struct ixgbe_hw *hw); + s32 (*get_fw_version)(struct ixgbe_hw *hw); + s32 (*get_nvm_version)(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm); +}; + +struct ixgbe_phy_operations { + s32 (*identify)(struct ixgbe_hw *); + s32 (*identify_sfp)(struct ixgbe_hw *); + s32 (*init)(struct ixgbe_hw *); + s32 (*reset)(struct ixgbe_hw *); + s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *); + s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16); + s32 (*read_reg_mdi)(struct ixgbe_hw *, u32, u32, u16 *); + s32 (*write_reg_mdi)(struct ixgbe_hw *, u32, u32, u16); + s32 (*setup_link)(struct ixgbe_hw *); + s32 (*setup_internal_link)(struct ixgbe_hw *); + s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool); + s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *); + s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *); + s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *); + s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8); + s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *); + s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); + s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); + void (*i2c_bus_clear)(struct ixgbe_hw *); + s32 (*check_overtemp)(struct ixgbe_hw *); + s32 (*set_phy_power)(struct ixgbe_hw *, bool on); + s32 (*enter_lplu)(struct ixgbe_hw *); + s32 (*handle_lasi)(struct ixgbe_hw *hw); + s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, + u8 *value); + s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, + u8 value); +}; + +struct ixgbe_link_operations { + s32 (*read_link)(struct ixgbe_hw *, u8 addr, u16 reg, u16 *val); + s32 (*read_link_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, + u16 *val); + s32 (*write_link)(struct ixgbe_hw *, u8 addr, u16 reg, u16 val); + s32 (*write_link_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg, + u16 val); +}; + +struct ixgbe_link_info { + struct ixgbe_link_operations ops; + u8 addr; + struct ixgbe_link_status link_info; + struct ixgbe_link_status link_info_old; + u8 get_link_info; +}; + +struct ixgbe_eeprom_info { + struct ixgbe_eeprom_operations ops; + enum ixgbe_eeprom_type type; + u32 semaphore_delay; + u32 word_size; + u16 address_bits; + u16 word_page_size; + u16 ctrl_word_3; +}; + +#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01 +struct ixgbe_mac_info { + struct ixgbe_mac_operations ops; + enum ixgbe_mac_type type; + u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + u8 san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + /* prefix for World Wide Node Name (WWNN) */ + u16 wwnn_prefix; + /* prefix for World Wide Port Name (WWPN) */ + u16 wwpn_prefix; +#define IXGBE_MAX_MTA 128 + u32 mta_shadow[IXGBE_MAX_MTA]; + s32 mc_filter_type; + u32 mcft_size; + u32 vft_size; + u32 num_rar_entries; + u32 rar_highwater; + u32 rx_pb_size; + u32 max_tx_queues; + u32 max_rx_queues; + u32 orig_autoc; + u8 san_mac_rar_index; + bool get_link_status; + u32 orig_autoc2; + u16 max_msix_vectors; + bool arc_subsystem_valid; + bool orig_link_settings_stored; + bool autotry_restart; + u8 flags; + struct ixgbe_thermal_sensor_data thermal_sensor_data; + bool thermal_sensor_enabled; + struct ixgbe_dmac_config dmac_config; + bool set_lben; + u32 max_link_up_time; + u8 led_link_act; +}; + +struct ixgbe_phy_info { + struct ixgbe_phy_operations ops; + enum ixgbe_phy_type type; + u32 addr; + u32 id; + enum ixgbe_sfp_type sfp_type; + bool sfp_setup_needed; + u32 revision; + enum ixgbe_media_type media_type; + u32 phy_semaphore_mask; + bool reset_disable; + ixgbe_autoneg_advertised autoneg_advertised; + ixgbe_link_speed speeds_supported; + ixgbe_link_speed eee_speeds_supported; + ixgbe_link_speed eee_speeds_advertised; + enum ixgbe_smart_speed smart_speed; + bool smart_speed_active; + bool multispeed_fiber; + bool reset_if_overtemp; + bool qsfp_shared_i2c_bus; + u32 nw_mng_if_sel; + u64 phy_type_low; + u64 phy_type_high; + struct ixgbe_aci_cmd_set_phy_cfg_data curr_user_phy_cfg; +}; + +#include "ixgbe_mbx.h" + +struct ixgbe_hw { + u8 IOMEM *hw_addr; + void *back; + struct ixgbe_mac_info mac; + struct ixgbe_addr_filter_info addr_ctrl; + struct ixgbe_fc_info fc; + struct ixgbe_phy_info phy; + struct ixgbe_link_info link; + struct ixgbe_eeprom_info eeprom; + struct ixgbe_bus_info bus; + struct ixgbe_mbx_info mbx; + const u32 *mvals; + u16 device_id; + u16 vendor_id; + u16 subsystem_device_id; + u16 subsystem_vendor_id; + u8 revision_id; + bool adapter_stopped; + int api_version; + bool force_full_reset; + bool allow_unsupported_sfp; + bool wol_enabled; + bool need_crosstalk_fix; + /* NVM Update features */ + struct ixgbe_nvm_features nvmupd_features; + u32 fw_rst_cnt; + u8 api_branch; + u8 api_maj_ver; + u8 api_min_ver; + u8 api_patch; + u8 fw_branch; + u8 fw_maj_ver; + u8 fw_min_ver; + u8 fw_patch; + u32 fw_build; + struct ixgbe_aci_info aci; + struct ixgbe_flash_info flash; + struct ixgbe_hw_dev_caps dev_caps; + struct ixgbe_hw_func_caps func_caps; + struct ixgbe_fwlog_cfg fwlog_cfg; + bool fwlog_support_ena; + struct ixgbe_fwlog_ring fwlog_ring; +}; + +#define ixgbe_call_func(hw, func, params, error) \ + (func != NULL) ? func params : error + +/* Error Codes */ +#define IXGBE_SUCCESS 0 +#define IXGBE_ERR_EEPROM -1 +#define IXGBE_ERR_EEPROM_CHECKSUM -2 +#define IXGBE_ERR_PHY -3 +#define IXGBE_ERR_CONFIG -4 +#define IXGBE_ERR_PARAM -5 +#define IXGBE_ERR_MAC_TYPE -6 +#define IXGBE_ERR_UNKNOWN_PHY -7 +#define IXGBE_ERR_LINK_SETUP -8 +#define IXGBE_ERR_ADAPTER_STOPPED -9 +#define IXGBE_ERR_INVALID_MAC_ADDR -10 +#define IXGBE_ERR_DEVICE_NOT_SUPPORTED -11 +#define IXGBE_ERR_PRIMARY_REQUESTS_PENDING -12 +#define IXGBE_ERR_INVALID_LINK_SETTINGS -13 +#define IXGBE_ERR_AUTONEG_NOT_COMPLETE -14 +#define IXGBE_ERR_RESET_FAILED -15 +#define IXGBE_ERR_SWFW_SYNC -16 +#define IXGBE_ERR_PHY_ADDR_INVALID -17 +#define IXGBE_ERR_I2C -18 +#define IXGBE_ERR_SFP_NOT_SUPPORTED -19 +#define IXGBE_ERR_SFP_NOT_PRESENT -20 +#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21 +#define IXGBE_ERR_NO_SAN_ADDR_PTR -22 +#define IXGBE_ERR_FDIR_REINIT_FAILED -23 +#define IXGBE_ERR_EEPROM_VERSION -24 +#define IXGBE_ERR_NO_SPACE -25 +#define IXGBE_ERR_OVERTEMP -26 +#define IXGBE_ERR_FC_NOT_NEGOTIATED -27 +#define IXGBE_ERR_FC_NOT_SUPPORTED -28 +#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 +#define IXGBE_ERR_PBA_SECTION -31 +#define IXGBE_ERR_INVALID_ARGUMENT -32 +#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 +#define IXGBE_ERR_OUT_OF_MEM -34 +#define IXGBE_ERR_FEATURE_NOT_SUPPORTED -36 +#define IXGBE_ERR_EEPROM_PROTECTED_REGION -37 +#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 +#define IXGBE_ERR_FW_RESP_INVALID -39 +#define IXGBE_ERR_TOKEN_RETRY -40 +#define IXGBE_ERR_MBX -41 +#define IXGBE_ERR_MBX_NOMSG -42 +#define IXGBE_ERR_TIMEOUT -43 +#define IXGBE_ERR_NOT_SUPPORTED -45 +#define IXGBE_ERR_OUT_OF_RANGE -46 + +#define IXGBE_ERR_NVM -50 +#define IXGBE_ERR_NVM_CHECKSUM -51 +#define IXGBE_ERR_BUF_TOO_SHORT -52 +#define IXGBE_ERR_NVM_BLANK_MODE -53 +#define IXGBE_ERR_INVAL_SIZE -54 +#define IXGBE_ERR_DOES_NOT_EXIST -55 + +#define IXGBE_ERR_ACI_ERROR -100 +#define IXGBE_ERR_ACI_DISABLED -101 +#define IXGBE_ERR_ACI_TIMEOUT -102 +#define IXGBE_ERR_ACI_BUSY -103 +#define IXGBE_ERR_ACI_NO_WORK -104 +#define IXGBE_ERR_ACI_NO_EVENTS -105 +#define IXGBE_ERR_FW_API_VER -106 +#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF + +#define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4)) +#define IXGBE_FUSES0_300MHZ (1 << 5) +#define IXGBE_FUSES0_REV_MASK (3 << 6) + +#define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010) +#define IXGBE_KRM_LINK_S1(P) ((P) ? 0x8200 : 0x4200) +#define IXGBE_KRM_LINK_CTRL_1(P) ((P) ? 0x820C : 0x420C) +#define IXGBE_KRM_AN_CNTL_1(P) ((P) ? 0x822C : 0x422C) +#define IXGBE_KRM_AN_CNTL_4(P) ((P) ? 0x8238 : 0x4238) +#define IXGBE_KRM_AN_CNTL_8(P) ((P) ? 0x8248 : 0x4248) +#define IXGBE_KRM_PCS_KX_AN(P) ((P) ? 0x9918 : 0x5918) +#define IXGBE_KRM_PCS_KX_AN_LP(P) ((P) ? 0x991C : 0x591C) +#define IXGBE_KRM_SGMII_CTRL(P) ((P) ? 0x82A0 : 0x42A0) +#define IXGBE_KRM_LP_BASE_PAGE_HIGH(P) ((P) ? 0x836C : 0x436C) +#define IXGBE_KRM_DSP_TXFFE_STATE_4(P) ((P) ? 0x8634 : 0x4634) +#define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P) ? 0x8638 : 0x4638) +#define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P) ((P) ? 0x8B00 : 0x4B00) +#define IXGBE_KRM_PMD_DFX_BURNIN(P) ((P) ? 0x8E00 : 0x4E00) +#define IXGBE_KRM_PMD_FLX_MASK_ST20(P) ((P) ? 0x9054 : 0x5054) +#define IXGBE_KRM_TX_COEFF_CTRL_1(P) ((P) ? 0x9520 : 0x5520) +#define IXGBE_KRM_RX_ANA_CTL(P) ((P) ? 0x9A00 : 0x5A00) + +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA ~(0x3 << 20) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR (1u << 20) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_LR (0x2 << 20) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN (1u << 25) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN (1u << 26) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN (1u << 27) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10M ~(0x7 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_100M (1u << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G (0x2 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G (0x3 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN (0x4 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_2_5G (0x7 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK (0x7 << 28) +#define IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART (1u << 31) + +#define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B (1 << 9) +#define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS (1 << 11) + +#define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK (0x7 << 8) +#define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G (2 << 8) +#define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G (4 << 8) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN (1 << 12) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN (1 << 13) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ (1 << 14) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC (1 << 15) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX (1 << 16) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR (1 << 18) +#define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX (1 << 24) +#define IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR (1 << 26) +#define IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE (1 << 28) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE (1 << 29) +#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART (1 << 31) + +#define IXGBE_KRM_AN_CNTL_1_SYM_PAUSE (1 << 28) +#define IXGBE_KRM_AN_CNTL_1_ASM_PAUSE (1 << 29) +#define IXGBE_KRM_PCS_KX_AN_SYM_PAUSE (1 << 1) +#define IXGBE_KRM_PCS_KX_AN_ASM_PAUSE (1 << 2) +#define IXGBE_KRM_PCS_KX_AN_LP_SYM_PAUSE (1 << 2) +#define IXGBE_KRM_PCS_KX_AN_LP_ASM_PAUSE (1 << 3) +#define IXGBE_KRM_AN_CNTL_4_ECSR_AN37_OVER_73 (1 << 29) +#define IXGBE_KRM_AN_CNTL_8_LINEAR (1 << 0) +#define IXGBE_KRM_AN_CNTL_8_LIMITING (1 << 1) + +#define IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE (1 << 10) +#define IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE (1 << 11) + +#define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D (1 << 12) +#define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D (1 << 19) + +#define IXGBE_KRM_DSP_TXFFE_STATE_C0_EN (1 << 6) +#define IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN (1 << 15) +#define IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN (1 << 16) + +#define IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL (1 << 4) +#define IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS (1 << 2) + +#define IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK (0x3 << 16) + +#define IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN (1 << 1) +#define IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN (1 << 2) +#define IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN (1 << 3) +#define IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN (1 << 31) + +#define IXGBE_SB_IOSF_INDIRECT_CTRL 0x00011144 +#define IXGBE_SB_IOSF_INDIRECT_DATA 0x00011148 + +#define IXGBE_SB_IOSF_CTRL_ADDR_SHIFT 0 +#define IXGBE_SB_IOSF_CTRL_ADDR_MASK 0xFF +#define IXGBE_SB_IOSF_CTRL_RESP_STAT_SHIFT 18 +#define IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK \ + (0x3 << IXGBE_SB_IOSF_CTRL_RESP_STAT_SHIFT) +#define IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT 20 +#define IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK \ + (0xFF << IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT) +#define IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT 28 +#define IXGBE_SB_IOSF_CTRL_TARGET_SELECT_MASK 0x7 +#define IXGBE_SB_IOSF_CTRL_BUSY_SHIFT 31 +#define IXGBE_SB_IOSF_CTRL_BUSY (1 << IXGBE_SB_IOSF_CTRL_BUSY_SHIFT) +#define IXGBE_SB_IOSF_TARGET_KR_PHY 0 + +#define IXGBE_NW_MNG_IF_SEL 0x00011178 +#define IXGBE_NW_MNG_IF_SEL_MDIO_ACT (1u << 1) +#define IXGBE_NW_MNG_IF_SEL_MDIO_IF_MODE (1u << 2) +#define IXGBE_NW_MNG_IF_SEL_EN_SHARED_MDIO (1u << 13) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_10M (1u << 17) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_100M (1u << 18) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_1G (1u << 19) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G (1u << 20) +#define IXGBE_NW_MNG_IF_SEL_PHY_SPEED_10G (1u << 21) +#define IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE (1u << 25) +#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE (1 << 24) /* X552 reg field only */ +#define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT 3 +#define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD \ + (0x1F << IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT) + +/* Code Command (Flash I/F Interface) */ +#define IXGBE_HOST_INTERFACE_FLASH_READ_CMD 0x30 +#define IXGBE_HOST_INTERFACE_SHADOW_RAM_READ_CMD 0x31 +#define IXGBE_HOST_INTERFACE_FLASH_WRITE_CMD 0x32 +#define IXGBE_HOST_INTERFACE_SHADOW_RAM_WRITE_CMD 0x33 +#define IXGBE_HOST_INTERFACE_FLASH_MODULE_UPDATE_CMD 0x34 +#define IXGBE_HOST_INTERFACE_FLASH_BLOCK_EREASE_CMD 0x35 +#define IXGBE_HOST_INTERFACE_SHADOW_RAM_DUMP_CMD 0x36 +#define IXGBE_HOST_INTERFACE_FLASH_INFO_CMD 0x37 +#define IXGBE_HOST_INTERFACE_APPLY_UPDATE_CMD 0x38 +#define IXGBE_HOST_INTERFACE_MASK_CMD 0x000000FF + +#include "ixgbe_osdep2.h" + +#endif /* _IXGBE_TYPE_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type_e610.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type_e610.h new file mode 100644 index 0000000000..7f92c56fd5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_type_e610.h @@ -0,0 +1,2591 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_TYPE_E610_H_ +#define _IXGBE_TYPE_E610_H_ + +/* Little Endian defines */ +#ifndef __le16 +#define __le16 u16 +#endif +#ifndef __le32 +#define __le32 u32 +#endif +#ifndef __le64 +#define __le64 u64 +#endif + +/* Generic defines */ +#ifndef BIT +#define BIT(a) (1UL << (a)) +#endif /* !BIT */ +#ifndef BIT_ULL +#define BIT_ULL(a) (1ULL << (a)) +#endif /* !BIT_ULL */ +#define BITS_PER_BYTE 8 +#define DIVIDE_AND_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) + +/** + * ROUND_UP - round up to next arbitrary multiple (not a power of 2) + * @a: value to round up + * @b: arbitrary multiple + * + * Round up to the next multiple of the arbitrary b. + */ +#define ROUND_UP(a, b) ((b) * DIVIDE_AND_ROUND_UP((a), (b))) + +#define MAKEMASK(mask, shift) (mask << shift) + +#define BYTES_PER_WORD 2 +#define BYTES_PER_DWORD 4 + +#ifndef BITS_PER_LONG +#define BITS_PER_LONG 64 +#endif /* !BITS_PER_LONG */ +#ifndef BITS_PER_LONG_LONG +#define BITS_PER_LONG_LONG 64 +#endif /* !BITS_PER_LONG_LONG */ +#undef GENMASK +#define GENMASK(h, l) \ + (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) +#undef GENMASK_ULL +#define GENMASK_ULL(h, l) \ + (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + +/* Data type manipulation macros. */ +#define HI_DWORD(x) ((u32)((((x) >> 16) >> 16) & 0xFFFFFFFF)) +#define LO_DWORD(x) ((u32)((x) & 0xFFFFFFFF)) +#define HI_WORD(x) ((u16)(((x) >> 16) & 0xFFFF)) +#define LO_WORD(x) ((u16)((x) & 0xFFFF)) +#define HI_BYTE(x) ((u8)(((x) >> 8) & 0xFF)) +#define LO_BYTE(x) ((u8)((x) & 0xFF)) + +#ifndef MIN_T +#define MIN_T(_t, _a, _b) min((_t)(_a), (_t)(_b)) +#endif + +#define IS_ASCII(_ch) ((_ch) < 0x80) + +#define STRUCT_HACK_VAR_LEN +/** + * ixgbe_struct_size - size of struct with C99 flexible array member + * @ptr: pointer to structure + * @field: flexible array member (last member of the structure) + * @num: number of elements of that flexible array member + */ +#define ixgbe_struct_size(ptr, field, num) \ + (sizeof(*(ptr)) + sizeof(*(ptr)->field) * (num)) + +/* General E610 defines */ +#define IXGBE_MAX_VSI 768 + +/* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */ +#define E610_SR_VPD_SIZE_WORDS 512 +#define E610_SR_PCIE_ALT_SIZE_WORDS 512 + +/* Checksum and Shadow RAM pointers */ +#define E610_SR_NVM_DEV_STARTER_VER 0x18 +#define E610_NVM_VER_LO_SHIFT 0 +#define E610_NVM_VER_LO_MASK (0xff << E610_NVM_VER_LO_SHIFT) +#define E610_NVM_VER_HI_SHIFT 12 +#define E610_NVM_VER_HI_MASK (0xf << E610_NVM_VER_HI_SHIFT) +#define E610_SR_NVM_MAP_VER 0x29 +#define E610_SR_NVM_EETRACK_LO 0x2D +#define E610_SR_NVM_EETRACK_HI 0x2E +#define E610_SR_VPD_PTR 0x2F +#define E610_SR_PCIE_ALT_AUTO_LOAD_PTR 0x3E +#define E610_SR_SW_CHECKSUM_WORD 0x3F +#define E610_SR_PFA_PTR 0x40 +#define E610_SR_1ST_NVM_BANK_PTR 0x42 +#define E610_SR_NVM_BANK_SIZE 0x43 +#define E610_SR_1ST_OROM_BANK_PTR 0x44 +#define E610_SR_OROM_BANK_SIZE 0x45 +#define E610_SR_NETLIST_BANK_PTR 0x46 +#define E610_SR_NETLIST_BANK_SIZE 0x47 +#define E610_SR_POINTER_TYPE_BIT BIT(15) +#define E610_SR_POINTER_MASK 0x7fff +#define E610_SR_HALF_4KB_SECTOR_UNITS 2048 +#define E610_GET_PFA_POINTER_IN_WORDS(offset) \ + ((offset & E610_SR_POINTER_TYPE_BIT) == E610_SR_POINTER_TYPE_BIT) ? \ + ((offset & E610_SR_POINTER_MASK) * E610_SR_HALF_4KB_SECTOR_UNITS) : \ + (offset & E610_SR_POINTER_MASK) + +/* Checksum and Shadow RAM pointers */ +#define E610_SR_NVM_CTRL_WORD 0x00 +#define E610_SR_PBA_BLOCK_PTR 0x16 + +/* The Orom version topology */ +#define IXGBE_OROM_VER_PATCH_SHIFT 0 +#define IXGBE_OROM_VER_PATCH_MASK (0xff << IXGBE_OROM_VER_PATCH_SHIFT) +#define IXGBE_OROM_VER_BUILD_SHIFT 8 +#define IXGBE_OROM_VER_BUILD_MASK (0xffff << IXGBE_OROM_VER_BUILD_SHIFT) +#define IXGBE_OROM_VER_SHIFT 24 +#define IXGBE_OROM_VER_MASK (0xff << IXGBE_OROM_VER_SHIFT) + +/* CSS Header words */ +#define IXGBE_NVM_CSS_HDR_LEN_L 0x02 +#define IXGBE_NVM_CSS_HDR_LEN_H 0x03 +#define IXGBE_NVM_CSS_SREV_L 0x14 +#define IXGBE_NVM_CSS_SREV_H 0x15 + +/* Length of Authentication header section in words */ +#define IXGBE_NVM_AUTH_HEADER_LEN 0x08 + +/* The Netlist ID Block is located after all of the Link Topology nodes. */ +#define IXGBE_NETLIST_ID_BLK_SIZE 0x30 +#define IXGBE_NETLIST_ID_BLK_OFFSET(n) IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0004 + 2 * (n)) + +/* netlist ID block field offsets (word offsets) */ +#define IXGBE_NETLIST_ID_BLK_MAJOR_VER_LOW 0x02 +#define IXGBE_NETLIST_ID_BLK_MAJOR_VER_HIGH 0x03 +#define IXGBE_NETLIST_ID_BLK_MINOR_VER_LOW 0x04 +#define IXGBE_NETLIST_ID_BLK_MINOR_VER_HIGH 0x05 +#define IXGBE_NETLIST_ID_BLK_TYPE_LOW 0x06 +#define IXGBE_NETLIST_ID_BLK_TYPE_HIGH 0x07 +#define IXGBE_NETLIST_ID_BLK_REV_LOW 0x08 +#define IXGBE_NETLIST_ID_BLK_REV_HIGH 0x09 +#define IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(n) (0x0A + (n)) +#define IXGBE_NETLIST_ID_BLK_CUST_VER 0x2F + +/* The Link Topology Netlist section is stored as a series of words. It is + * stored in the NVM as a TLV, with the first two words containing the type + * and length. + */ +#define IXGBE_NETLIST_LINK_TOPO_MOD_ID 0x011B +#define IXGBE_NETLIST_TYPE_OFFSET 0x0000 +#define IXGBE_NETLIST_LEN_OFFSET 0x0001 + +/* The Link Topology section follows the TLV header. When reading the netlist + * using ixgbe_read_netlist_module, we need to account for the 2-word TLV + * header. + */ +#define IXGBE_NETLIST_LINK_TOPO_OFFSET(n) ((n) + 2) +#define IXGBE_LINK_TOPO_MODULE_LEN IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0000) +#define IXGBE_LINK_TOPO_NODE_COUNT IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0001) +#define IXGBE_LINK_TOPO_NODE_COUNT_M MAKEMASK(0x3FF, 0) + +/* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */ +#define IXGBE_SR_CTRL_WORD_1_S 0x06 +#define IXGBE_SR_CTRL_WORD_1_M (0x03 << IXGBE_SR_CTRL_WORD_1_S) +#define IXGBE_SR_CTRL_WORD_VALID 0x1 +#define IXGBE_SR_CTRL_WORD_OROM_BANK BIT(3) +#define IXGBE_SR_CTRL_WORD_NETLIST_BANK BIT(4) +#define IXGBE_SR_CTRL_WORD_NVM_BANK BIT(5) +#define IXGBE_SR_NVM_PTR_4KB_UNITS BIT(15) + +/* These macros strip from NVM Image Revision the particular part of NVM ver: + major ver, minor ver and image id */ +#define E610_NVM_MAJOR_VER(x) ((x & 0xF000) >> 12) +#define E610_NVM_MINOR_VER(x) (x & 0x00FF) + +/* Minimal Security Revision */ + +/* Shadow RAM related */ +#define IXGBE_SR_SECTOR_SIZE_IN_WORDS 0x800 +#define IXGBE_SR_WORDS_IN_1KB 512 +/* Checksum should be calculated such that after adding all the words, + * including the checksum word itself, the sum should be 0xBABA. + */ +#define IXGBE_SR_SW_CHECKSUM_BASE 0xBABA + +/* Netlist */ +#define IXGBE_MAX_NETLIST_SIZE 10 + +/* General registers */ + +/* Firmware Status Register (GL_FWSTS) */ +#define GL_FWSTS 0x00083048 /* Reset Source: POR */ +#define GL_FWSTS_FWS0B_S 0 +#define GL_FWSTS_FWS0B_M MAKEMASK(0xFF, 0) +#define GL_FWSTS_FWROWD_S 8 +#define GL_FWSTS_FWROWD_M BIT(8) +#define GL_FWSTS_FWRI_S 9 +#define GL_FWSTS_FWRI_M BIT(9) +#define GL_FWSTS_FWS1B_S 16 +#define GL_FWSTS_FWS1B_M MAKEMASK(0xFF, 16) +#define GL_FWSTS_EP_PF0 BIT(24) +#define GL_FWSTS_EP_PF1 BIT(25) + +/* Recovery mode values of Firmware Status 1 Byte (FWS1B) bitfield */ +#define GL_FWSTS_FWS1B_RECOVERY_MODE_CORER_LEGACY 0x0B +#define GL_FWSTS_FWS1B_RECOVERY_MODE_GLOBR_LEGACY 0x0C +#define GL_FWSTS_FWS1B_RECOVERY_MODE_CORER 0x30 +#define GL_FWSTS_FWS1B_RECOVERY_MODE_GLOBR 0x31 +#define GL_FWSTS_FWS1B_RECOVERY_MODE_TRANSITION 0x32 +#define GL_FWSTS_FWS1B_RECOVERY_MODE_NVM 0x33 + +/* Firmware Status (GL_MNG_FWSM) */ +#define GL_MNG_FWSM 0x000B6134 /* Reset Source: POR */ +#define GL_MNG_FWSM_FW_MODES_S 0 +#define GL_MNG_FWSM_FW_MODES_M MAKEMASK(0x7, 0) +#define GL_MNG_FWSM_RSV0_S 2 +#define GL_MNG_FWSM_RSV0_M MAKEMASK(0xFF, 2) +#define GL_MNG_FWSM_EEP_RELOAD_IND_S 10 +#define GL_MNG_FWSM_EEP_RELOAD_IND_M BIT(10) +#define GL_MNG_FWSM_RSV1_S 11 +#define GL_MNG_FWSM_RSV1_M MAKEMASK(0xF, 11) +#define GL_MNG_FWSM_RSV2_S 15 +#define GL_MNG_FWSM_RSV2_M BIT(15) +#define GL_MNG_FWSM_PCIR_AL_FAILURE_S 16 +#define GL_MNG_FWSM_PCIR_AL_FAILURE_M BIT(16) +#define GL_MNG_FWSM_POR_AL_FAILURE_S 17 +#define GL_MNG_FWSM_POR_AL_FAILURE_M BIT(17) +#define GL_MNG_FWSM_RSV3_S 18 +#define GL_MNG_FWSM_RSV3_M BIT(18) +#define GL_MNG_FWSM_EXT_ERR_IND_S 19 +#define GL_MNG_FWSM_EXT_ERR_IND_M MAKEMASK(0x3F, 19) +#define GL_MNG_FWSM_RSV4_S 25 +#define GL_MNG_FWSM_RSV4_M BIT(25) +#define GL_MNG_FWSM_RESERVED_11_S 26 +#define GL_MNG_FWSM_RESERVED_11_M MAKEMASK(0xF, 26) +#define GL_MNG_FWSM_RSV5_S 30 +#define GL_MNG_FWSM_RSV5_M MAKEMASK(0x3, 30) + +/* FW mode indications */ +#define GL_MNG_FWSM_FW_MODES_DEBUG_M BIT(0) +#define GL_MNG_FWSM_FW_MODES_RECOVERY_M BIT(1) +#define GL_MNG_FWSM_FW_MODES_ROLLBACK_M BIT(2) + +/* PF - Manageability Registers */ + +/* Global NVM General Status Register */ +#define GLNVM_GENS 0x000B6100 /* Reset Source: POR */ +#define GLNVM_GENS_NVM_PRES_S 0 +#define GLNVM_GENS_NVM_PRES_M BIT(0) +#define GLNVM_GENS_SR_SIZE_S 5 +#define GLNVM_GENS_SR_SIZE_M MAKEMASK(0x7, 5) +#define GLNVM_GENS_BANK1VAL_S 8 +#define GLNVM_GENS_BANK1VAL_M BIT(8) +#define GLNVM_GENS_ALT_PRST_S 23 +#define GLNVM_GENS_ALT_PRST_M BIT(23) +#define GLNVM_GENS_FL_AUTO_RD_S 25 +#define GLNVM_GENS_FL_AUTO_RD_M BIT(25) + +/* Flash Access Register */ +#define GLNVM_FLA 0x000B6108 /* Reset Source: POR */ +#define GLNVM_FLA_LOCKED_S 6 +#define GLNVM_FLA_LOCKED_M BIT(6) + +/* Bit Bang registers */ +#define RDASB_MSGCTL 0x000B6820 +#define RDASB_MSGCTL_HDR_DWS_S 0 +#define RDASB_MSGCTL_EXP_RDW_S 8 +#define RDASB_MSGCTL_CMDV_M BIT(31) +#define RDASB_RSPCTL 0x000B6824 +#define RDASB_RSPCTL_BAD_LENGTH_M BIT(30) +#define RDASB_RSPCTL_NOT_SUCCESS_M BIT(31) +#define RDASB_WHDR0 0x000B68F4 +#define RDASB_WHDR1 0x000B68F8 +#define RDASB_WHDR2 0x000B68FC +#define RDASB_WHDR3 0x000B6900 +#define RDASB_WHDR4 0x000B6904 +#define RDASB_RHDR0 0x000B6AFC +#define RDASB_RHDR0_RESPONSE_S 27 +#define RDASB_RHDR0_RESPONSE_M MAKEMASK(0x7, 27) +#define RDASB_RDATA0 0x000B6B00 +#define RDASB_RDATA1 0x000B6B04 + +/* SPI Registers */ +#define SPISB_MSGCTL 0x000B7020 +#define SPISB_MSGCTL_HDR_DWS_S 0 +#define SPISB_MSGCTL_EXP_RDW_S 8 +#define SPISB_MSGCTL_MSG_MODE_S 26 +#define SPISB_MSGCTL_TOKEN_MODE_S 28 +#define SPISB_MSGCTL_BARCLR_S 30 +#define SPISB_MSGCTL_CMDV_S 31 +#define SPISB_MSGCTL_CMDV_M BIT(31) +#define SPISB_RSPCTL 0x000B7024 +#define SPISB_RSPCTL_BAD_LENGTH_M BIT(30) +#define SPISB_RSPCTL_NOT_SUCCESS_M BIT(31) +#define SPISB_WHDR0 0x000B70F4 +#define SPISB_WHDR0_DEST_SEL_S 12 +#define SPISB_WHDR0_OPCODE_SEL_S 16 +#define SPISB_WHDR0_TAG_S 24 +#define SPISB_WHDR1 0x000B70F8 +#define SPISB_WHDR2 0x000B70FC +#define SPISB_RDATA 0x000B7300 +#define SPISB_WDATA 0x000B7100 + +/* Firmware Reset Count register */ +#define GL_FWRESETCNT 0x00083100 /* Reset Source: POR */ +#define GL_FWRESETCNT_FWRESETCNT_S 0 +#define GL_FWRESETCNT_FWRESETCNT_M MAKEMASK(0xFFFFFFFF, 0) + +/* Admin Command Interface (ACI) registers */ +#define PF_HIDA(_i) (0x00085000 + ((_i) * 4)) +#define PF_HIDA_2(_i) (0x00085020 + ((_i) * 4)) +#define PF_HIBA(_i) (0x00084000 + ((_i) * 4)) +#define PF_HICR 0x00082048 + +#define PF_HIDA_MAX_INDEX 15 +#define PF_HIBA_MAX_INDEX 1023 + +#define PF_HICR_EN BIT(0) +#define PF_HICR_C BIT(1) +#define PF_HICR_SV BIT(2) +#define PF_HICR_EV BIT(3) + +#define GL_HIDA(_i) (0x00082000 + ((_i) * 4)) +#define GL_HIDA_2(_i) (0x00082020 + ((_i) * 4)) +#define GL_HIBA(_i) (0x00081000 + ((_i) * 4)) +#define GL_HICR 0x00082040 + +#define GL_HIDA_MAX_INDEX 15 +#define GL_HIBA_MAX_INDEX 1023 + +#define GL_HICR_C BIT(1) +#define GL_HICR_SV BIT(2) +#define GL_HICR_EV BIT(3) + +#define GL_HICR_EN 0x00082044 + +#define GL_HICR_EN_CHECK BIT(0) + +/* Admin Command Interface (ACI) defines */ +/* Defines that help manage the driver vs FW API checks. + */ +#define IXGBE_FW_API_VER_BRANCH 0x00 +#define IXGBE_FW_API_VER_MAJOR 0x01 +#define IXGBE_FW_API_VER_MINOR 0x07 +#define IXGBE_FW_API_VER_DIFF_ALLOWED 0x02 + +#define IXGBE_ACI_DESC_SIZE 32 +#define IXGBE_ACI_DESC_SIZE_IN_DWORDS IXGBE_ACI_DESC_SIZE / BYTES_PER_DWORD + +#define IXGBE_ACI_MAX_BUFFER_SIZE 4096 /* Size in bytes */ +#define IXGBE_ACI_DESC_COOKIE_L_DWORD_OFFSET 3 +#define IXGBE_ACI_SEND_DELAY_TIME_MS 10 +#define IXGBE_ACI_SEND_MAX_EXECUTE 3 +#define IXGBE_ACI_MAX_DEBUG_STRING_LENGTH 128 +/* [ms] timeout of waiting for sync response */ +#define IXGBE_ACI_SYNC_RESPONSE_TIMEOUT 100000 +/* [ms] timeout of waiting for async response */ +#define IXGBE_ACI_ASYNC_RESPONSE_TIMEOUT 150000 +/* [ms] timeout of waiting for resource release */ +#define IXGBE_ACI_RELEASE_RES_TIMEOUT 10000 + +/* Timestamp spacing for Tools ACI: queue is active if spacing is within the range [LO..HI] */ +#define IXGBE_TOOLS_ACI_ACTIVE_STAMP_SPACING_LO 0 +#define IXGBE_TOOLS_ACI_ACTIVE_STAMP_SPACING_HI 200 + +/* Timestamp spacing for Tools ACI: queue is expired if spacing is outside the range [LO..HI] */ +#define IXGBE_TOOLS_ACI_EXPIRED_STAMP_SPACING_LO -5 +#define IXGBE_TOOLS_ACI_EXPIRED_STAMP_SPACING_HI 205 + +/* FW defined boundary for a large buffer, 4k >= Large buffer > 512 bytes */ +#define IXGBE_ACI_LG_BUF 512 + +/* Flags sub-structure + * |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 |15 | + * |DD |CMP|ERR|VFE| * * RESERVED * * |LB |RD |VFC|BUF|SI |EI |FE | + */ + +/* command flags and offsets */ +#define IXGBE_ACI_FLAG_DD_S 0 +#define IXGBE_ACI_FLAG_CMP_S 1 +#define IXGBE_ACI_FLAG_ERR_S 2 +#define IXGBE_ACI_FLAG_VFE_S 3 +#define IXGBE_ACI_FLAG_LB_S 9 +#define IXGBE_ACI_FLAG_RD_S 10 +#define IXGBE_ACI_FLAG_VFC_S 11 +#define IXGBE_ACI_FLAG_BUF_S 12 +#define IXGBE_ACI_FLAG_SI_S 13 +#define IXGBE_ACI_FLAG_EI_S 14 +#define IXGBE_ACI_FLAG_FE_S 15 + +#define IXGBE_ACI_FLAG_DD BIT(IXGBE_ACI_FLAG_DD_S) /* 0x1 */ +#define IXGBE_ACI_FLAG_CMP BIT(IXGBE_ACI_FLAG_CMP_S) /* 0x2 */ +#define IXGBE_ACI_FLAG_ERR BIT(IXGBE_ACI_FLAG_ERR_S) /* 0x4 */ +#define IXGBE_ACI_FLAG_VFE BIT(IXGBE_ACI_FLAG_VFE_S) /* 0x8 */ +#define IXGBE_ACI_FLAG_LB BIT(IXGBE_ACI_FLAG_LB_S) /* 0x200 */ +#define IXGBE_ACI_FLAG_RD BIT(IXGBE_ACI_FLAG_RD_S) /* 0x400 */ +#define IXGBE_ACI_FLAG_VFC BIT(IXGBE_ACI_FLAG_VFC_S) /* 0x800 */ +#define IXGBE_ACI_FLAG_BUF BIT(IXGBE_ACI_FLAG_BUF_S) /* 0x1000 */ +#define IXGBE_ACI_FLAG_SI BIT(IXGBE_ACI_FLAG_SI_S) /* 0x2000 */ +#define IXGBE_ACI_FLAG_EI BIT(IXGBE_ACI_FLAG_EI_S) /* 0x4000 */ +#define IXGBE_ACI_FLAG_FE BIT(IXGBE_ACI_FLAG_FE_S) /* 0x8000 */ + +/* Admin Command Interface (ACI) error codes */ +enum ixgbe_aci_err { + IXGBE_ACI_RC_OK = 0, /* Success */ + IXGBE_ACI_RC_EPERM = 1, /* Operation not permitted */ + IXGBE_ACI_RC_ENOENT = 2, /* No such element */ + IXGBE_ACI_RC_ESRCH = 3, /* Bad opcode */ + IXGBE_ACI_RC_EINTR = 4, /* Operation interrupted */ + IXGBE_ACI_RC_EIO = 5, /* I/O error */ + IXGBE_ACI_RC_ENXIO = 6, /* No such resource */ + IXGBE_ACI_RC_E2BIG = 7, /* Arg too long */ + IXGBE_ACI_RC_EAGAIN = 8, /* Try again */ + IXGBE_ACI_RC_ENOMEM = 9, /* Out of memory */ + IXGBE_ACI_RC_EACCES = 10, /* Permission denied */ + IXGBE_ACI_RC_EFAULT = 11, /* Bad address */ + IXGBE_ACI_RC_EBUSY = 12, /* Device or resource busy */ + IXGBE_ACI_RC_EEXIST = 13, /* Object already exists */ + IXGBE_ACI_RC_EINVAL = 14, /* Invalid argument */ + IXGBE_ACI_RC_ENOTTY = 15, /* Not a typewriter */ + IXGBE_ACI_RC_ENOSPC = 16, /* No space left or allocation failure */ + IXGBE_ACI_RC_ENOSYS = 17, /* Function not implemented */ + IXGBE_ACI_RC_ERANGE = 18, /* Parameter out of range */ + IXGBE_ACI_RC_EFLUSHED = 19, /* Cmd flushed due to prev cmd error */ + IXGBE_ACI_RC_BAD_ADDR = 20, /* Descriptor contains a bad pointer */ + IXGBE_ACI_RC_EMODE = 21, /* Op not allowed in current dev mode */ + IXGBE_ACI_RC_EFBIG = 22, /* File too big */ + IXGBE_ACI_RC_ESBCOMP = 23, /* SB-IOSF completion unsuccessful */ + IXGBE_ACI_RC_ENOSEC = 24, /* Missing security manifest */ + IXGBE_ACI_RC_EBADSIG = 25, /* Bad RSA signature */ + IXGBE_ACI_RC_ESVN = 26, /* SVN number prohibits this package */ + IXGBE_ACI_RC_EBADMAN = 27, /* Manifest hash mismatch */ + IXGBE_ACI_RC_EBADBUF = 28, /* Buffer hash mismatches manifest */ + IXGBE_ACI_RC_EACCES_BMCU = 29, /* BMC Update in progress */ +}; + +/* Admin Command Interface (ACI) opcodes */ +enum ixgbe_aci_opc { + ixgbe_aci_opc_get_ver = 0x0001, + ixgbe_aci_opc_driver_ver = 0x0002, + ixgbe_aci_opc_get_exp_err = 0x0005, + + /* resource ownership */ + ixgbe_aci_opc_req_res = 0x0008, + ixgbe_aci_opc_release_res = 0x0009, + + /* device/function capabilities */ + ixgbe_aci_opc_list_func_caps = 0x000A, + ixgbe_aci_opc_list_dev_caps = 0x000B, + + /* safe disable of RXEN */ + ixgbe_aci_opc_disable_rxen = 0x000C, + + /* FW events */ + ixgbe_aci_opc_get_fw_event = 0x0014, + + /* PHY commands */ + ixgbe_aci_opc_get_phy_caps = 0x0600, + ixgbe_aci_opc_set_phy_cfg = 0x0601, + ixgbe_aci_opc_restart_an = 0x0605, + ixgbe_aci_opc_get_link_status = 0x0607, + ixgbe_aci_opc_set_event_mask = 0x0613, +#ifndef NO_PTP_SUPPORT + ixgbe_aci_opc_set_ptp_by_phy = 0x0634, + ixgbe_aci_opc_get_ptp_by_phy = 0x0635, +#endif /* !NO_PTP_SUPPORT */ + ixgbe_aci_opc_get_link_topo = 0x06E0, +#if !defined(NO_PTP_SUPPORT) + ixgbe_aci_opc_get_link_topo_pin = 0x06E1, +#endif /* !NO_PTP_SUPPORT */ + ixgbe_aci_opc_read_i2c = 0x06E2, + ixgbe_aci_opc_write_i2c = 0x06E3, + ixgbe_aci_opc_read_mdio = 0x06E4, + ixgbe_aci_opc_write_mdio = 0x06E5, + ixgbe_aci_opc_set_gpio_by_func = 0x06E6, + ixgbe_aci_opc_get_gpio_by_func = 0x06E7, + ixgbe_aci_opc_set_port_id_led = 0x06E9, + ixgbe_aci_opc_set_gpio = 0x06EC, + ixgbe_aci_opc_get_gpio = 0x06ED, + ixgbe_aci_opc_sff_eeprom = 0x06EE, + ixgbe_aci_opc_prog_topo_dev_nvm = 0x06F2, + ixgbe_aci_opc_read_topo_dev_nvm = 0x06F3, + + /* NVM commands */ + ixgbe_aci_opc_nvm_read = 0x0701, + ixgbe_aci_opc_nvm_erase = 0x0702, + ixgbe_aci_opc_nvm_write = 0x0703, + ixgbe_aci_opc_nvm_cfg_read = 0x0704, + ixgbe_aci_opc_nvm_cfg_write = 0x0705, + ixgbe_aci_opc_nvm_checksum = 0x0706, + ixgbe_aci_opc_nvm_write_activate = 0x0707, + ixgbe_aci_opc_nvm_sr_dump = 0x0707, + ixgbe_aci_opc_nvm_save_factory_settings = 0x0708, + ixgbe_aci_opc_nvm_update_empr = 0x0709, + ixgbe_aci_opc_nvm_pkg_data = 0x070A, + ixgbe_aci_opc_nvm_pass_component_tbl = 0x070B, + ixgbe_aci_opc_nvm_sanitization = 0x070C, + + /* Alternate Structure Commands */ + ixgbe_aci_opc_write_alt_direct = 0x0900, + ixgbe_aci_opc_write_alt_indirect = 0x0901, + ixgbe_aci_opc_read_alt_direct = 0x0902, + ixgbe_aci_opc_read_alt_indirect = 0x0903, + ixgbe_aci_opc_done_alt_write = 0x0904, + ixgbe_aci_opc_clear_port_alt_write = 0x0906, + + ixgbe_aci_opc_temp_tca_event = 0x0C94, + + /* debug commands */ + ixgbe_aci_opc_debug_dump_internals = 0xFF08, + + /* SystemDiagnostic commands */ + ixgbe_aci_opc_set_health_status_config = 0xFF20, + ixgbe_aci_opc_get_supported_health_status_codes = 0xFF21, + ixgbe_aci_opc_get_health_status = 0xFF22, + ixgbe_aci_opc_clear_health_status = 0xFF23, + + /* FW Logging Commands */ + ixgbe_aci_opc_fw_logs_config = 0xFF30, + ixgbe_aci_opc_fw_logs_register = 0xFF31, + ixgbe_aci_opc_fw_logs_query = 0xFF32, + ixgbe_aci_opc_fw_logs_event = 0xFF33, + ixgbe_aci_opc_fw_logs_get = 0xFF34, + ixgbe_aci_opc_fw_logs_clear = 0xFF35 +}; + +/* This macro is used to generate a compilation error if a structure + * is not exactly the correct length. It gives a divide by zero error if the + * structure is not of the correct size, otherwise it creates an enum that is + * never used. + */ +#define IXGBE_CHECK_STRUCT_LEN(n, X) enum ixgbe_static_assert_enum_##X \ + { ixgbe_static_assert_##X = (n) / ((sizeof(struct X) == (n)) ? 1 : 0) } + +/* This macro is used to generate a compilation error if a variable-length + * structure is not exactly the correct length assuming a single element of + * the variable-length object as the last element of the structure. It gives + * a divide by zero error if the structure is not of the correct size, + * otherwise it creates an enum that is never used. + */ +#define IXGBE_CHECK_VAR_LEN_STRUCT_LEN(n, X, T) enum ixgbe_static_assert_enum_##X \ + { ixgbe_static_assert_##X = (n) / \ + (((sizeof(struct X) + sizeof(T)) == (n)) ? 1 : 0) } + +/* This macro is used to ensure that parameter structures (i.e. structures + * in the params union member of struct ixgbe_aci_desc) are 16 bytes in length. + * + * NOT intended to be used to check the size of an indirect command/response + * additional data buffer (e.g. struct foo) which should just happen to be 16 + * bytes (instead, use IXGBE_CHECK_STRUCT_LEN(16, foo) for that). + */ +#define IXGBE_CHECK_PARAM_LEN(X) IXGBE_CHECK_STRUCT_LEN(16, X) + +struct ixgbe_aci_cmd_generic { + __le32 param0; + __le32 param1; + __le32 addr_high; + __le32 addr_low; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_generic); + +/* Get version (direct 0x0001) */ +struct ixgbe_aci_cmd_get_ver { + __le32 rom_ver; + __le32 fw_build; + u8 fw_branch; + u8 fw_major; + u8 fw_minor; + u8 fw_patch; + u8 api_branch; + u8 api_major; + u8 api_minor; + u8 api_patch; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_ver); + +#define IXGBE_DRV_VER_STR_LEN_E610 32 + +struct ixgbe_driver_ver { + u8 major_ver; + u8 minor_ver; + u8 build_ver; + u8 subbuild_ver; + u8 driver_string[IXGBE_DRV_VER_STR_LEN_E610]; +}; + +/* Send driver version (indirect 0x0002) */ +struct ixgbe_aci_cmd_driver_ver { + u8 major_ver; + u8 minor_ver; + u8 build_ver; + u8 subbuild_ver; + u8 reserved[4]; + __le32 addr_high; + __le32 addr_low; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_driver_ver); + +/* Get Expanded Error Code (0x0005, direct) */ +struct ixgbe_aci_cmd_get_exp_err { + __le32 reason; +#define IXGBE_ACI_EXPANDED_ERROR_NOT_PROVIDED 0xFFFFFFFF + __le32 identifier; + u8 rsvd[8]; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_exp_err); + +/* FW update timeout definitions are in milliseconds */ +#define IXGBE_NVM_TIMEOUT 180000 +#define IXGBE_CHANGE_LOCK_TIMEOUT 1000 +#define IXGBE_GLOBAL_CFG_LOCK_TIMEOUT 3000 + +enum ixgbe_aci_res_access_type { + IXGBE_RES_READ = 1, + IXGBE_RES_WRITE +}; + +enum ixgbe_aci_res_ids { + IXGBE_NVM_RES_ID = 1, + IXGBE_SPD_RES_ID, + IXGBE_CHANGE_LOCK_RES_ID, + IXGBE_GLOBAL_CFG_LOCK_RES_ID +}; + +/* Request resource ownership (direct 0x0008) + * Release resource ownership (direct 0x0009) + */ +struct ixgbe_aci_cmd_req_res { + __le16 res_id; +#define IXGBE_ACI_RES_ID_NVM 1 +#define IXGBE_ACI_RES_ID_SDP 2 +#define IXGBE_ACI_RES_ID_CHNG_LOCK 3 +#define IXGBE_ACI_RES_ID_GLBL_LOCK 4 + __le16 access_type; +#define IXGBE_ACI_RES_ACCESS_READ 1 +#define IXGBE_ACI_RES_ACCESS_WRITE 2 + + /* Upon successful completion, FW writes this value and driver is + * expected to release resource before timeout. This value is provided + * in milliseconds. + */ + __le32 timeout; +#define IXGBE_ACI_RES_NVM_READ_DFLT_TIMEOUT_MS 3000 +#define IXGBE_ACI_RES_NVM_WRITE_DFLT_TIMEOUT_MS 180000 +#define IXGBE_ACI_RES_CHNG_LOCK_DFLT_TIMEOUT_MS 1000 +#define IXGBE_ACI_RES_GLBL_LOCK_DFLT_TIMEOUT_MS 3000 + /* For SDP: pin ID of the SDP */ + __le32 res_number; + /* Status is only used for IXGBE_ACI_RES_ID_GLBL_LOCK */ + __le16 status; +#define IXGBE_ACI_RES_GLBL_SUCCESS 0 +#define IXGBE_ACI_RES_GLBL_IN_PROG 1 +#define IXGBE_ACI_RES_GLBL_DONE 2 + u8 reserved[2]; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_req_res); + +/* Get function capabilities (indirect 0x000A) + * Get device capabilities (indirect 0x000B) + */ +struct ixgbe_aci_cmd_list_caps { + u8 cmd_flags; + u8 pf_index; + u8 reserved[2]; + __le32 count; + __le32 addr_high; + __le32 addr_low; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_list_caps); + +/* Device/Function buffer entry, repeated per reported capability */ +struct ixgbe_aci_cmd_list_caps_elem { + __le16 cap; +#define IXGBE_ACI_CAPS_VALID_FUNCTIONS 0x0005 +#define IXGBE_ACI_MAX_VALID_FUNCTIONS 0x8 +#define IXGBE_ACI_CAPS_VMDQ 0x0014 +#define IXGBE_ACI_CAPS_VSI 0x0017 +#define IXGBE_ACI_CAPS_DCB 0x0018 +#define IXGBE_ACI_CAPS_RSS 0x0040 +#define IXGBE_ACI_CAPS_RXQS 0x0041 +#define IXGBE_ACI_CAPS_TXQS 0x0042 +#define IXGBE_ACI_CAPS_MSIX 0x0043 +#define IXGBE_ACI_CAPS_FD 0x0045 +#ifndef NO_PTP_SUPPORT +#define IXGBE_ACI_CAPS_1588 0x0046 +#endif /* !NO_PTP_SUPPORT */ +#define IXGBE_ACI_CAPS_MAX_MTU 0x0047 +#define IXGBE_ACI_CAPS_NVM_VER 0x0048 +#define IXGBE_ACI_CAPS_PENDING_NVM_VER 0x0049 +#define IXGBE_ACI_CAPS_OROM_VER 0x004A +#define IXGBE_ACI_CAPS_PENDING_OROM_VER 0x004B +#define IXGBE_ACI_CAPS_PENDING_NET_VER 0x004D +#define IXGBE_ACI_CAPS_INLINE_IPSEC 0x0070 +#define IXGBE_ACI_CAPS_NUM_ENABLED_PORTS 0x0072 +#define IXGBE_ACI_CAPS_PCIE_RESET_AVOIDANCE 0x0076 +#define IXGBE_ACI_CAPS_POST_UPDATE_RESET_RESTRICT 0x0077 +#define IXGBE_ACI_CAPS_NVM_MGMT 0x0080 +#define IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0 0x0081 +#define IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG1 0x0082 +#define IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG2 0x0083 +#define IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG3 0x0084 +#define IXGBE_ACI_CAPS_OROM_RECOVERY_UPDATE 0x0090 +#define IXGBE_ACI_CAPS_NEXT_CLUSTER_ID 0x0096 +#ifndef NO_PTP_SUPPORT +#define IXGBE_ACI_CAPS_PTP_BY_PHY 0x0097 +#define IXGBE_ACI_CAPS_PTP_BY_PHY_SUPP BIT(0) +#define IXGBE_ACI_CAPS_PTP_BY_PHY_LL BIT(1) +#endif /* !NO_PTP_SUPPORT */ +#define IXGBE_ACI_CAPS_EEE 0x009B + u8 major_ver; + u8 minor_ver; + /* Number of resources described by this capability */ + __le32 number; + /* Only meaningful for some types of resources */ + __le32 logical_id; + /* Only meaningful for some types of resources */ + __le32 phys_id; + __le64 rsvd1; + __le64 rsvd2; +}; + +IXGBE_CHECK_STRUCT_LEN(32, ixgbe_aci_cmd_list_caps_elem); + +/* Disable RXEN (direct 0x000C) */ +struct ixgbe_aci_cmd_disable_rxen { + u8 lport_num; + u8 reserved[15]; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_disable_rxen); + +/* Get FW Event (indirect 0x0014) */ +struct ixgbe_aci_cmd_get_fw_event { + __le16 fw_buf_status; +#define IXGBE_ACI_GET_FW_EVENT_STATUS_OBTAINED BIT(0) +#define IXGBE_ACI_GET_FW_EVENT_STATUS_PENDING BIT(1) + u8 rsvd[14]; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_fw_event); + +/* Get PHY capabilities (indirect 0x0600) */ +struct ixgbe_aci_cmd_get_phy_caps { + u8 lport_num; + u8 reserved; + __le16 param0; + /* 18.0 - Report qualified modules */ +#define IXGBE_ACI_GET_PHY_RQM BIT(0) + /* 18.1 - 18.3 : Report mode + * 000b - Report topology capabilities, without media + * 001b - Report topology capabilities, with media + * 010b - Report Active configuration + * 011b - Report PHY Type and FEC mode capabilities + * 100b - Report Default capabilities + */ +#define IXGBE_ACI_REPORT_MODE_S 1 +#define IXGBE_ACI_REPORT_MODE_M (7 << IXGBE_ACI_REPORT_MODE_S) +#define IXGBE_ACI_REPORT_TOPO_CAP_NO_MEDIA 0 +#define IXGBE_ACI_REPORT_TOPO_CAP_MEDIA BIT(1) +#define IXGBE_ACI_REPORT_ACTIVE_CFG BIT(2) +#define IXGBE_ACI_REPORT_DFLT_CFG BIT(3) + __le32 reserved1; + __le32 addr_high; + __le32 addr_low; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_phy_caps); + +/* This is #define of PHY type (Extended): + * The first set of defines is for phy_type_low. + */ +#define IXGBE_PHY_TYPE_LOW_100BASE_TX BIT_ULL(0) +#define IXGBE_PHY_TYPE_LOW_100M_SGMII BIT_ULL(1) +#define IXGBE_PHY_TYPE_LOW_1000BASE_T BIT_ULL(2) +#define IXGBE_PHY_TYPE_LOW_1000BASE_SX BIT_ULL(3) +#define IXGBE_PHY_TYPE_LOW_1000BASE_LX BIT_ULL(4) +#define IXGBE_PHY_TYPE_LOW_1000BASE_KX BIT_ULL(5) +#define IXGBE_PHY_TYPE_LOW_1G_SGMII BIT_ULL(6) +#define IXGBE_PHY_TYPE_LOW_2500BASE_T BIT_ULL(7) +#define IXGBE_PHY_TYPE_LOW_2500BASE_X BIT_ULL(8) +#define IXGBE_PHY_TYPE_LOW_2500BASE_KX BIT_ULL(9) +#define IXGBE_PHY_TYPE_LOW_5GBASE_T BIT_ULL(10) +#define IXGBE_PHY_TYPE_LOW_5GBASE_KR BIT_ULL(11) +#define IXGBE_PHY_TYPE_LOW_10GBASE_T BIT_ULL(12) +#define IXGBE_PHY_TYPE_LOW_10G_SFI_DA BIT_ULL(13) +#define IXGBE_PHY_TYPE_LOW_10GBASE_SR BIT_ULL(14) +#define IXGBE_PHY_TYPE_LOW_10GBASE_LR BIT_ULL(15) +#define IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1 BIT_ULL(16) +#define IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC BIT_ULL(17) +#define IXGBE_PHY_TYPE_LOW_10G_SFI_C2C BIT_ULL(18) +#define IXGBE_PHY_TYPE_LOW_25GBASE_T BIT_ULL(19) +#define IXGBE_PHY_TYPE_LOW_25GBASE_CR BIT_ULL(20) +#define IXGBE_PHY_TYPE_LOW_25GBASE_CR_S BIT_ULL(21) +#define IXGBE_PHY_TYPE_LOW_25GBASE_CR1 BIT_ULL(22) +#define IXGBE_PHY_TYPE_LOW_25GBASE_SR BIT_ULL(23) +#define IXGBE_PHY_TYPE_LOW_25GBASE_LR BIT_ULL(24) +#define IXGBE_PHY_TYPE_LOW_25GBASE_KR BIT_ULL(25) +#define IXGBE_PHY_TYPE_LOW_25GBASE_KR_S BIT_ULL(26) +#define IXGBE_PHY_TYPE_LOW_25GBASE_KR1 BIT_ULL(27) +#define IXGBE_PHY_TYPE_LOW_25G_AUI_AOC_ACC BIT_ULL(28) +#define IXGBE_PHY_TYPE_LOW_25G_AUI_C2C BIT_ULL(29) +#define IXGBE_PHY_TYPE_LOW_MAX_INDEX 29 +/* The second set of defines is for phy_type_high. */ +#define IXGBE_PHY_TYPE_HIGH_10BASE_T BIT_ULL(1) +#define IXGBE_PHY_TYPE_HIGH_10M_SGMII BIT_ULL(2) +#define IXGBE_PHY_TYPE_HIGH_2500M_SGMII BIT_ULL(56) +#define IXGBE_PHY_TYPE_HIGH_100M_USXGMII BIT_ULL(57) +#define IXGBE_PHY_TYPE_HIGH_1G_USXGMII BIT_ULL(58) +#define IXGBE_PHY_TYPE_HIGH_2500M_USXGMII BIT_ULL(59) +#define IXGBE_PHY_TYPE_HIGH_5G_USXGMII BIT_ULL(60) +#define IXGBE_PHY_TYPE_HIGH_10G_USXGMII BIT_ULL(61) +#define IXGBE_PHY_TYPE_HIGH_MAX_INDEX 61 + +struct ixgbe_aci_cmd_get_phy_caps_data { + __le64 phy_type_low; /* Use values from IXGBE_PHY_TYPE_LOW_* */ + __le64 phy_type_high; /* Use values from IXGBE_PHY_TYPE_HIGH_* */ + u8 caps; +#define IXGBE_ACI_PHY_EN_TX_LINK_PAUSE BIT(0) +#define IXGBE_ACI_PHY_EN_RX_LINK_PAUSE BIT(1) +#define IXGBE_ACI_PHY_LOW_POWER_MODE BIT(2) +#define IXGBE_ACI_PHY_EN_LINK BIT(3) +#define IXGBE_ACI_PHY_AN_MODE BIT(4) +#define IXGBE_ACI_PHY_EN_MOD_QUAL BIT(5) +#define IXGBE_ACI_PHY_EN_LESM BIT(6) +#define IXGBE_ACI_PHY_EN_AUTO_FEC BIT(7) +#define IXGBE_ACI_PHY_CAPS_MASK MAKEMASK(0xff, 0) + u8 low_power_ctrl_an; +#define IXGBE_ACI_PHY_EN_D3COLD_LOW_POWER_AUTONEG BIT(0) +#define IXGBE_ACI_PHY_AN_EN_CLAUSE28 BIT(1) +#define IXGBE_ACI_PHY_AN_EN_CLAUSE73 BIT(2) +#define IXGBE_ACI_PHY_AN_EN_CLAUSE37 BIT(3) + __le16 eee_cap; +#define IXGBE_ACI_PHY_EEE_EN_100BASE_TX BIT(0) +#define IXGBE_ACI_PHY_EEE_EN_1000BASE_T BIT(1) +#define IXGBE_ACI_PHY_EEE_EN_10GBASE_T BIT(2) +#define IXGBE_ACI_PHY_EEE_EN_5GBASE_T BIT(11) +#define IXGBE_ACI_PHY_EEE_EN_2_5GBASE_T BIT(12) + __le16 eeer_value; + u8 phy_id_oui[4]; /* PHY/Module ID connected on the port */ + u8 phy_fw_ver[8]; + u8 link_fec_options; +#define IXGBE_ACI_PHY_FEC_10G_KR_40G_KR4_EN BIT(0) +#define IXGBE_ACI_PHY_FEC_10G_KR_40G_KR4_REQ BIT(1) +#define IXGBE_ACI_PHY_FEC_25G_RS_528_REQ BIT(2) +#define IXGBE_ACI_PHY_FEC_25G_KR_REQ BIT(3) +#define IXGBE_ACI_PHY_FEC_25G_RS_544_REQ BIT(4) +#define IXGBE_ACI_PHY_FEC_25G_RS_CLAUSE91_EN BIT(6) +#define IXGBE_ACI_PHY_FEC_25G_KR_CLAUSE74_EN BIT(7) +#define IXGBE_ACI_PHY_FEC_MASK MAKEMASK(0xdf, 0) + u8 module_compliance_enforcement; +#define IXGBE_ACI_MOD_ENFORCE_STRICT_MODE BIT(0) + u8 extended_compliance_code; +#define IXGBE_ACI_MODULE_TYPE_TOTAL_BYTE 3 + u8 module_type[IXGBE_ACI_MODULE_TYPE_TOTAL_BYTE]; +#define IXGBE_ACI_MOD_TYPE_BYTE0_SFP_PLUS 0xA0 +#define IXGBE_ACI_MOD_TYPE_BYTE0_QSFP_PLUS 0x80 +#define IXGBE_ACI_MOD_TYPE_IDENT 1 +#define IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE BIT(0) +#define IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE BIT(1) +#define IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_SR BIT(4) +#define IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LR BIT(5) +#define IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LRM BIT(6) +#define IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_ER BIT(7) +#define IXGBE_ACI_MOD_TYPE_BYTE2_SFP_PLUS 0xA0 +#define IXGBE_ACI_MOD_TYPE_BYTE2_QSFP_PLUS 0x86 + u8 qualified_module_count; + u8 rsvd2; + __le16 eee_entry_delay; + u8 rsvd3[4]; +#define IXGBE_ACI_QUAL_MOD_COUNT_MAX 16 + struct { + u8 v_oui[3]; + u8 rsvd3; + u8 v_part[16]; + __le32 v_rev; + __le64 rsvd4; + } qual_modules[IXGBE_ACI_QUAL_MOD_COUNT_MAX]; +}; + +IXGBE_CHECK_STRUCT_LEN(560, ixgbe_aci_cmd_get_phy_caps_data); + +/* Set PHY capabilities (direct 0x0601) + * NOTE: This command must be followed by setup link and restart auto-neg + */ +struct ixgbe_aci_cmd_set_phy_cfg { + u8 reserved[8]; + __le32 addr_high; + __le32 addr_low; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_set_phy_cfg); + +/* Set PHY config obsolete command data structure (= this entry are invalid */ +}; + +struct ixgbe_fwlog_module_entry { + /* module ID for the corresponding firmware logging event */ + u16 module_id; + /* verbosity level for the module_id */ + u8 log_level; +}; + +struct ixgbe_fwlog_cfg { + /* list of modules for configuring log level */ + struct ixgbe_fwlog_module_entry module_entries[IXGBE_ACI_FW_LOG_ID_MAX]; +#define IXGBE_FWLOG_OPTION_ARQ_ENA BIT(0) +#define IXGBE_FWLOG_OPTION_UART_ENA BIT(1) + /* set before calling ixgbe_fwlog_init() so the PF registers for firmware + * logging on initialization + */ +#define IXGBE_FWLOG_OPTION_REGISTER_ON_INIT BIT(2) + /* set in the ixgbe_fwlog_get() response if the PF is registered for FW + * logging events over ARQ + */ +#define IXGBE_FWLOG_OPTION_IS_REGISTERED BIT(3) + /* options used to configure firmware logging */ + u16 options; + /* minimum number of log events sent per Admin Receive Queue event */ + u8 log_resolution; +}; + +struct ixgbe_fwlog_data { + u16 data_size; + u8 *data; +}; + +struct ixgbe_fwlog_ring { + struct ixgbe_fwlog_data *rings; + u16 size; + u16 head; + u16 tail; +}; + +#define IXGBE_FWLOG_RING_SIZE_DFLT 256 +#define IXGBE_FWLOG_RING_SIZE_MAX 512 + +/* Set FW Logging configuration (indirect 0xFF30) + * Register for FW Logging (indirect 0xFF31) + * Query FW Logging (indirect 0xFF32) + * FW Log Event (indirect 0xFF33) + * Get FW Log (indirect 0xFF34) + * Clear FW Log (indirect 0xFF35) + */ +struct ixgbe_aci_cmd_fw_log { + u8 cmd_flags; +#define IXGBE_ACI_FW_LOG_CONF_UART_EN BIT(0) +#define IXGBE_ACI_FW_LOG_CONF_AQ_EN BIT(1) +#define IXGBE_ACI_FW_LOG_QUERY_REGISTERED BIT(2) +#define IXGBE_ACI_FW_LOG_CONF_SET_VALID BIT(3) +#define IXGBE_ACI_FW_LOG_AQ_REGISTER BIT(0) +#define IXGBE_ACI_FW_LOG_AQ_QUERY BIT(2) +#define IXGBE_ACI_FW_LOG_PERSISTENT BIT(0) + u8 rsp_flag; +#define IXGBE_ACI_FW_LOG_MORE_DATA BIT(1) + __le16 fw_rt_msb; + union { + struct { + __le32 fw_rt_lsb; + } sync; + struct { + __le16 log_resolution; +#define IXGBE_ACI_FW_LOG_MIN_RESOLUTION (1) +#define IXGBE_ACI_FW_LOG_MAX_RESOLUTION (128) + __le16 mdl_cnt; + } cfg; + } ops; + __le32 addr_high; + __le32 addr_low; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_fw_log); + +/* Response Buffer for: + * Set Firmware Logging Configuration (0xFF30) + * Query FW Logging (0xFF32) + */ +struct ixgbe_aci_cmd_fw_log_cfg_resp { + __le16 module_identifier; + u8 log_level; + u8 rsvd0; +}; + +IXGBE_CHECK_STRUCT_LEN(4, ixgbe_aci_cmd_fw_log_cfg_resp); + +/** + * struct ixgbe_aq_desc - Admin Command (AC) descriptor + * @flags: IXGBE_ACI_FLAG_* flags + * @opcode: Admin command opcode + * @datalen: length in bytes of indirect/external data buffer + * @retval: return value from firmware + * @cookie_high: opaque data high-half + * @cookie_low: opaque data low-half + * @params: command-specific parameters + * + * Descriptor format for commands the driver posts via the Admin Command Interface + * (ACI). The firmware writes back onto the command descriptor and returns + * the result of the command. Asynchronous events that are not an immediate + * result of the command are written to the Admin Command Interface (ACI) using + * the same descriptor format. Descriptors are in little-endian notation with + * 32-bit words. + */ +struct ixgbe_aci_desc { + __le16 flags; + __le16 opcode; + __le16 datalen; + __le16 retval; + __le32 cookie_high; + __le32 cookie_low; + union { + u8 raw[16]; + struct ixgbe_aci_cmd_generic generic; + struct ixgbe_aci_cmd_get_ver get_ver; + struct ixgbe_aci_cmd_driver_ver driver_ver; + struct ixgbe_aci_cmd_get_exp_err exp_err; + struct ixgbe_aci_cmd_req_res res_owner; + struct ixgbe_aci_cmd_list_caps get_cap; + struct ixgbe_aci_cmd_disable_rxen disable_rxen; + struct ixgbe_aci_cmd_get_fw_event get_fw_event; + struct ixgbe_aci_cmd_get_phy_caps get_phy; + struct ixgbe_aci_cmd_set_phy_cfg set_phy; + struct ixgbe_aci_cmd_restart_an restart_an; + struct ixgbe_aci_cmd_get_link_status get_link_status; + struct ixgbe_aci_cmd_set_event_mask set_event_mask; +#ifndef NO_PTP_SUPPORT + struct ixgbe_aci_cmd_set_ptp_by_phy set_ptp_by_phy; + struct ixgbe_aci_cmd_get_ptp_by_phy_resp get_ptp_by_phy_resp; +#endif /* !NO_PTP_SUPPORT */ + struct ixgbe_aci_cmd_get_link_topo get_link_topo; +#if !defined(NO_PTP_SUPPORT) + struct ixgbe_aci_cmd_get_link_topo_pin get_link_topo_pin; +#endif /* !NO_PTP_SUPPORT */ + struct ixgbe_aci_cmd_i2c read_write_i2c; + struct ixgbe_aci_cmd_read_i2c_resp read_i2c_resp; + struct ixgbe_aci_cmd_mdio read_write_mdio; + struct ixgbe_aci_cmd_mdio read_mdio; + struct ixgbe_aci_cmd_mdio write_mdio; + struct ixgbe_aci_cmd_set_port_id_led set_port_id_led; + struct ixgbe_aci_cmd_gpio_by_func read_write_gpio_by_func; + struct ixgbe_aci_cmd_gpio read_write_gpio; + struct ixgbe_aci_cmd_sff_eeprom read_write_sff_param; + struct ixgbe_aci_cmd_prog_topo_dev_nvm prog_topo_dev_nvm; + struct ixgbe_aci_cmd_read_topo_dev_nvm read_topo_dev_nvm; + struct ixgbe_aci_cmd_nvm nvm; + struct ixgbe_aci_cmd_nvm_cfg nvm_cfg; + struct ixgbe_aci_cmd_nvm_checksum nvm_checksum; + struct ixgbe_aci_cmd_nvm_pkg_data pkg_data; + struct ixgbe_aci_cmd_nvm_pass_comp_tbl pass_comp_tbl; + struct ixgbe_aci_cmd_read_write_alt_direct read_write_alt_direct; + struct ixgbe_aci_cmd_read_write_alt_indirect read_write_alt_indirect; + struct ixgbe_aci_cmd_done_alt_write done_alt_write; + struct ixgbe_aci_cmd_clear_port_alt_write clear_port_alt_write; + struct ixgbe_aci_cmd_debug_dump_internals debug_dump; + struct ixgbe_aci_cmd_set_health_status_config + set_health_status_config; + struct ixgbe_aci_cmd_get_supported_health_status_codes + get_supported_health_status_codes; + struct ixgbe_aci_cmd_get_health_status get_health_status; + struct ixgbe_aci_cmd_clear_health_status clear_health_status; + struct ixgbe_aci_cmd_fw_log fw_log; + struct ixgbe_aci_cmd_nvm_sanitization nvm_sanitization; + } params; +}; + +/* LKV-specific adapter context structures */ + +struct ixgbe_link_status { + /* Refer to ixgbe_aci_phy_type for bits definition */ + u64 phy_type_low; + u64 phy_type_high; + u8 topo_media_conflict; + u16 max_frame_size; + u16 link_speed; + u16 req_speeds; + u8 link_cfg_err; + u8 lse_ena; /* Link Status Event notification */ + u8 link_info; + u8 an_info; + u8 ext_info; + u8 fec_info; + u8 pacing; + /* Refer to #define from module_type[IXGBE_ACI_MODULE_TYPE_TOTAL_BYTE] of + * ixgbe_aci_get_phy_caps structure + */ + u8 module_type[IXGBE_ACI_MODULE_TYPE_TOTAL_BYTE]; + u8 eee_status; +}; + +/* Common HW capabilities for SW use */ +struct ixgbe_hw_common_caps { + /* Write CSR protection */ + u64 wr_csr_prot; + u32 switching_mode; + /* switching mode supported - EVB switching (including cloud) */ +#define IXGBE_NVM_IMAGE_TYPE_EVB 0x0 + + /* Manageability mode & supported protocols over MCTP */ + u32 mgmt_mode; +#define IXGBE_MGMT_MODE_PASS_THRU_MODE_M 0xF +#define IXGBE_MGMT_MODE_CTL_INTERFACE_M 0xF0 +#define IXGBE_MGMT_MODE_REDIR_SB_INTERFACE_M 0xF00 + + u32 mgmt_protocols_mctp; +#define IXGBE_MGMT_MODE_PROTO_RSVD BIT(0) +#define IXGBE_MGMT_MODE_PROTO_PLDM BIT(1) +#define IXGBE_MGMT_MODE_PROTO_OEM BIT(2) +#define IXGBE_MGMT_MODE_PROTO_NC_SI BIT(3) + + u32 os2bmc; + u32 valid_functions; + /* DCB capabilities */ + u32 active_tc_bitmap; + u32 maxtc; + + /* RSS related capabilities */ + u32 rss_table_size; /* 512 for PFs and 64 for VFs */ + u32 rss_table_entry_width; /* RSS Entry width in bits */ + + /* Tx/Rx queues */ + u32 num_rxq; /* Number/Total Rx queues */ + u32 rxq_first_id; /* First queue ID for Rx queues */ + u32 num_txq; /* Number/Total Tx queues */ + u32 txq_first_id; /* First queue ID for Tx queues */ + + /* MSI-X vectors */ + u32 num_msix_vectors; + u32 msix_vector_first_id; + + /* Max MTU for function or device */ + u32 max_mtu; + + /* WOL related */ + u32 num_wol_proxy_fltr; + u32 wol_proxy_vsi_seid; + + /* LED/SDP pin count */ + u32 led_pin_num; + u32 sdp_pin_num; + + /* LED/SDP - Supports up to 12 LED pins and 8 SDP signals */ +#define IXGBE_MAX_SUPPORTED_GPIO_LED 12 +#define IXGBE_MAX_SUPPORTED_GPIO_SDP 8 + u8 led[IXGBE_MAX_SUPPORTED_GPIO_LED]; + u8 sdp[IXGBE_MAX_SUPPORTED_GPIO_SDP]; + /* VMDQ */ + u8 vmdq; /* VMDQ supported */ + + /* EVB capabilities */ + u8 evb_802_1_qbg; /* Edge Virtual Bridging */ + u8 evb_802_1_qbh; /* Bridge Port Extension */ + + u8 dcb; + u8 iscsi; +#ifndef NO_PTP_SUPPORT + u8 ieee_1588; +#endif + u8 mgmt_cem; + + /* WoL and APM support */ +#define IXGBE_WOL_SUPPORT_M BIT(0) +#define IXGBE_ACPI_PROG_MTHD_M BIT(1) +#define IXGBE_PROXY_SUPPORT_M BIT(2) + u8 apm_wol_support; + u8 acpi_prog_mthd; + u8 proxy_support; + u8 eee_support; +#define IXGBE_EEE_SUPPORT_100BASE_TX BIT(0) +#define IXGBE_EEE_SUPPORT_1000BASE_T BIT(1) +#define IXGBE_EEE_SUPPORT_10GBASE_T BIT(2) +#define IXGBE_EEE_SUPPORT_5GBASE_T BIT(3) +#define IXGBE_EEE_SUPPORT_2_5GBASE_T BIT(4) + bool nvm_update_pending_nvm; + bool nvm_update_pending_orom; + bool nvm_update_pending_netlist; +#define IXGBE_NVM_PENDING_NVM_IMAGE BIT(0) +#define IXGBE_NVM_PENDING_OROM BIT(1) +#define IXGBE_NVM_PENDING_NETLIST BIT(2) + bool sec_rev_disabled; + bool update_disabled; + bool nvm_unified_update; + bool netlist_auth; +#define IXGBE_NVM_MGMT_SEC_REV_DISABLED BIT(0) +#define IXGBE_NVM_MGMT_UPDATE_DISABLED BIT(1) +#define IXGBE_NVM_MGMT_UNIFIED_UPD_SUPPORT BIT(3) +#define IXGBE_NVM_MGMT_NETLIST_AUTH_SUPPORT BIT(5) + bool no_drop_policy_support; + /* PCIe reset avoidance */ + bool pcie_reset_avoidance; /* false: not supported, true: supported */ + /* Post update reset restriction */ + bool reset_restrict_support; /* false: not supported, true: supported */ + + /* External topology device images within the NVM */ +#define IXGBE_EXT_TOPO_DEV_IMG_COUNT 4 + u32 ext_topo_dev_img_ver_high[IXGBE_EXT_TOPO_DEV_IMG_COUNT]; + u32 ext_topo_dev_img_ver_low[IXGBE_EXT_TOPO_DEV_IMG_COUNT]; + u8 ext_topo_dev_img_part_num[IXGBE_EXT_TOPO_DEV_IMG_COUNT]; +#define IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_S 8 +#define IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_M \ + MAKEMASK(0xFF, IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_S) + bool ext_topo_dev_img_load_en[IXGBE_EXT_TOPO_DEV_IMG_COUNT]; +#define IXGBE_EXT_TOPO_DEV_IMG_LOAD_EN BIT(0) + bool ext_topo_dev_img_prog_en[IXGBE_EXT_TOPO_DEV_IMG_COUNT]; +#define IXGBE_EXT_TOPO_DEV_IMG_PROG_EN BIT(1) + /* Support for OROM update in Recovery Mode. */ + bool orom_recovery_update; + bool next_cluster_id_support; +#ifndef NO_PTP_SUPPORT + bool ptp_by_phy_support : 1; + bool ptp_by_phy_ll : 1; +#endif /* !NO_PTP_SUPPORT */ +}; + +#ifndef NO_PTP_SUPPORT +/* IEEE 1588 TIME_SYNC specific info */ +/* Function specific definitions */ +#define IXGBE_TS_FUNC_ENA_M BIT(0) +#define IXGBE_TS_SRC_TMR_OWND_M BIT(1) +#define IXGBE_TS_TMR_ENA_M BIT(2) +#define IXGBE_TS_TMR_IDX_OWND_S 4 +#define IXGBE_TS_TMR_IDX_OWND_M BIT(4) +#define IXGBE_TS_CLK_FREQ_S 16 +#define IXGBE_TS_CLK_FREQ_M MAKEMASK(0x7, IXGBE_TS_CLK_FREQ_S) +#define IXGBE_TS_CLK_SRC_S 20 +#define IXGBE_TS_CLK_SRC_M BIT(20) +#define IXGBE_TS_TMR_IDX_ASSOC_S 24 +#define IXGBE_TS_TMR_IDX_ASSOC_M BIT(24) + +/* TIME_REF clock rate specification */ +enum ixgbe_time_ref_freq { + IXGBE_TIME_REF_FREQ_25_000 = 0, + IXGBE_TIME_REF_FREQ_122_880 = 1, + IXGBE_TIME_REF_FREQ_125_000 = 2, + IXGBE_TIME_REF_FREQ_153_600 = 3, + IXGBE_TIME_REF_FREQ_156_250 = 4, + IXGBE_TIME_REF_FREQ_245_760 = 5, + + NUM_IXGBE_TIME_REF_FREQ +}; + +struct ixgbe_ts_func_info { + /* Function specific info */ + enum ixgbe_time_ref_freq time_ref; + u8 clk_freq; + u8 clk_src; + u8 tmr_index_assoc; + u8 ena; + u8 tmr_index_owned; + u8 src_tmr_owned; + u8 tmr_ena; +}; + +/* Device specific definitions */ +#define IXGBE_TS_TMR0_OWNR_M 0x7 +#define IXGBE_TS_TMR0_OWND_M BIT(3) +#define IXGBE_TS_TMR1_OWNR_S 4 +#define IXGBE_TS_TMR1_OWNR_M MAKEMASK(0x7, IXGBE_TS_TMR1_OWNR_S) +#define IXGBE_TS_TMR1_OWND_M BIT(7) +#define IXGBE_TS_DEV_ENA_M BIT(24) +#define IXGBE_TS_TMR0_ENA_M BIT(25) +#define IXGBE_TS_TMR1_ENA_M BIT(26) + +struct ixgbe_ts_dev_info { + /* Device specific info */ + u32 ena_ports; + u32 tmr_own_map; + u32 tmr0_owner; + u32 tmr1_owner; + u8 tmr0_owned; + u8 tmr1_owned; + u8 ena; + u8 tmr0_ena; + u8 tmr1_ena; +}; +#endif /* !NO_PTP_SUPPORT */ + +#pragma pack(1) +struct ixgbe_orom_civd_info { + u8 signature[4]; /* Must match ASCII '$CIV' characters */ + u8 checksum; /* Simple modulo 256 sum of all structure bytes must equal 0 */ + __le32 combo_ver; /* Combo Image Version number */ + u8 combo_name_len; /* Length of the unicode combo image version string, max of 32 */ + __le16 combo_name[32]; /* Unicode string representing the Combo Image version */ +}; +#pragma pack() + +/* Function specific capabilities */ +struct ixgbe_hw_func_caps { + struct ixgbe_hw_common_caps common_cap; + u32 guar_num_vsi; +#ifndef NO_PTP_SUPPORT + struct ixgbe_ts_func_info ts_func_info; +#endif /* !NO_PTP_SUPPORT */ + bool no_drop_policy_ena; +}; + +/* Device wide capabilities */ +struct ixgbe_hw_dev_caps { + struct ixgbe_hw_common_caps common_cap; + u32 num_vsi_allocd_to_host; /* Excluding EMP VSI */ + u32 num_flow_director_fltr; /* Number of FD filters available */ +#ifndef NO_PTP_SUPPORT + struct ixgbe_ts_dev_info ts_dev_info; +#endif /* !NO_PTP_SUPPORT */ + u32 num_funcs; +}; + +/* ACI event information */ +struct ixgbe_aci_event { + struct ixgbe_aci_desc desc; + u16 msg_len; + u16 buf_len; + u8 *msg_buf; +}; + +struct ixgbe_aci_info { + enum ixgbe_aci_err last_status; /* last status of sent admin command */ + struct ixgbe_lock lock; /* admin command interface lock */ +}; + +/* Minimum Security Revision information */ +struct ixgbe_minsrev_info { + u32 nvm; + u32 orom; + u8 nvm_valid : 1; + u8 orom_valid : 1; +}; + +/* Enumeration of which flash bank is desired to read from, either the active + * bank or the inactive bank. Used to abstract 1st and 2nd bank notion from + * code which just wants to read the active or inactive flash bank. + */ +enum ixgbe_bank_select { + IXGBE_ACTIVE_FLASH_BANK, + IXGBE_INACTIVE_FLASH_BANK, +}; + +/* Option ROM version information */ +struct ixgbe_orom_info { + u8 major; /* Major version of OROM */ + u8 patch; /* Patch version of OROM */ + u16 build; /* Build version of OROM */ + u32 srev; /* Security revision */ +}; + +/* NVM version information */ +struct ixgbe_nvm_info { + u32 eetrack; + u32 srev; + u8 major; + u8 minor; +}; + +/* netlist version information */ +struct ixgbe_netlist_info { + u32 major; /* major high/low */ + u32 minor; /* minor high/low */ + u32 type; /* type high/low */ + u32 rev; /* revision high/low */ + u32 hash; /* SHA-1 hash word */ + u16 cust_ver; /* customer version */ +}; + +/* Enumeration of possible flash banks for the NVM, OROM, and Netlist modules + * of the flash image. + */ +enum ixgbe_flash_bank { + IXGBE_INVALID_FLASH_BANK, + IXGBE_1ST_FLASH_BANK, + IXGBE_2ND_FLASH_BANK, +}; + +/* information for accessing NVM, OROM, and Netlist flash banks */ +struct ixgbe_bank_info { + u32 nvm_ptr; /* Pointer to 1st NVM bank */ + u32 nvm_size; /* Size of NVM bank */ + u32 orom_ptr; /* Pointer to 1st OROM bank */ + u32 orom_size; /* Size of OROM bank */ + u32 netlist_ptr; /* Pointer to 1st Netlist bank */ + u32 netlist_size; /* Size of Netlist bank */ + enum ixgbe_flash_bank nvm_bank; /* Active NVM bank */ + enum ixgbe_flash_bank orom_bank; /* Active OROM bank */ + enum ixgbe_flash_bank netlist_bank; /* Active Netlist bank */ +}; + +/* Flash Chip Information */ +struct ixgbe_flash_info { + struct ixgbe_orom_info orom; /* Option ROM version info */ + struct ixgbe_nvm_info nvm; /* NVM version information */ + struct ixgbe_netlist_info netlist; /* Netlist version info */ + struct ixgbe_bank_info banks; /* Flash Bank information */ + u32 sr_words; /* Shadow RAM size in words */ + u32 flash_size; /* Size of available flash in bytes */ + u8 blank_nvm_mode; /* is NVM empty (no FW present) */ +}; + +#define IXGBE_NVM_CMD_READ 0x0000000B +#define IXGBE_NVM_CMD_WRITE 0x0000000C + +/* NVM Access command */ +struct ixgbe_nvm_access_cmd { + u32 command; /* NVM command: READ or WRITE */ + u32 offset; /* Offset to read/write, in bytes */ + u32 data_size; /* Size of data field, in bytes */ +}; + +/* NVM Access data */ +struct ixgbe_nvm_access_data { + u32 regval; /* Storage for register value */ +}; + +#ifndef NO_PTP_SUPPORT +#define PROXY_TX_TS_LOW 0x00000100 +#define PROXY_TX_TS_HIGH 0x00000104 +#define PROXY_TX_STS 0x00000108 +#define PROXY_RX_TS_LOW 0x00002410 +#define PROXY_RX_TS_HIGH 0x00002414 +#define PROXY_RX_STS 0x00002418 +#define PROXY_STS_SEQ_ID GENMASK(15, 0) +#define PROXY_STS_ERR GENMASK(29, 16) +#define PROXY_STS_TS_RDY BIT(30) +#define PROXY_STS_TS_INT BIT(31) + +#endif /* !NO_PTP_SUPPORT */ + +/** + * ixgbe_is_mac_E6xx - check if MAC belongs to E600 series + * @mac_type: MAC type to be tested + * + * Return: true if mac_type belongs to E600 series, false otherwise. + */ +#define ixgbe_is_mac_E6xx(mac_type) ((mac_type) == ixgbe_mac_E610) + +#endif /* _IXGBE_TYPE_E610_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.c new file mode 100644 index 0000000000..4927935f78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.c @@ -0,0 +1,1032 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_x540.h" +#include "ixgbe_type.h" +#include "ixgbe_api.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" + +#define IXGBE_X540_MAX_TX_QUEUES 128 +#define IXGBE_X540_MAX_RX_QUEUES 128 +#define IXGBE_X540_RAR_ENTRIES 128 +#define IXGBE_X540_MC_TBL_SIZE 128 +#define IXGBE_X540_VFT_TBL_SIZE 128 +#define IXGBE_X540_RX_PB_SIZE 384 + +STATIC s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); +STATIC s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); +STATIC void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); + +/** + * ixgbe_init_ops_X540 - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type for X540. + * Does not touch the hardware. + **/ +s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + s32 ret_val; + u16 i; + + DEBUGFUNC("ixgbe_init_ops_X540"); + + ret_val = ixgbe_init_phy_ops_generic(hw); + ret_val = ixgbe_init_ops_generic(hw); + + /* EEPROM */ + eeprom->ops.init_params = ixgbe_init_eeprom_params_X540; + eeprom->ops.read = ixgbe_read_eerd_X540; + eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_X540; + eeprom->ops.write = ixgbe_write_eewr_X540; + eeprom->ops.write_buffer = ixgbe_write_eewr_buffer_X540; + eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X540; + eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X540; + eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X540; + + /* PHY */ + phy->ops.init = ixgbe_init_phy_ops_generic; + phy->ops.reset = NULL; + phy->ops.set_phy_power = ixgbe_set_copper_phy_power; + + /* MAC */ + mac->ops.reset_hw = ixgbe_reset_hw_X540; + mac->ops.get_media_type = ixgbe_get_media_type_X540; + mac->ops.get_supported_physical_layer = + ixgbe_get_supported_physical_layer_X540; + mac->ops.read_analog_reg8 = NULL; + mac->ops.write_analog_reg8 = NULL; + mac->ops.start_hw = ixgbe_start_hw_X540; + mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic; + mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic; + mac->ops.get_device_caps = ixgbe_get_device_caps_generic; + mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic; + mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic; + mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540; + mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540; + mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540; + mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic; + mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic; + + /* RAR, Multicast, VLAN */ + mac->ops.set_vmdq = ixgbe_set_vmdq_generic; + mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic; + mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic; + mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic; + mac->rar_highwater = 1; + mac->ops.set_vfta = ixgbe_set_vfta_generic; + mac->ops.set_vlvf = ixgbe_set_vlvf_generic; + mac->ops.clear_vfta = ixgbe_clear_vfta_generic; + mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic; + mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing; + mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing; + + /* Link */ + mac->ops.get_link_capabilities = + ixgbe_get_copper_link_capabilities_generic; + mac->ops.setup_link = ixgbe_setup_mac_link_X540; + mac->ops.setup_rxpba = ixgbe_set_rxpba_generic; + mac->ops.check_link = ixgbe_check_mac_link_generic; + + mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; + mac->vft_size = IXGBE_X540_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES; + mac->rx_pb_size = IXGBE_X540_RX_PB_SIZE; + mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); + + /* + * FWSM register + * ARC supported; valid only if manageability features are + * enabled. + */ + mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)) + & IXGBE_FWSM_MODE_MASK); + + for (i = 0; i < 64; i++) + hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf; + + /* LEDs */ + mac->ops.blink_led_start = ixgbe_blink_led_start_X540; + mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540; + + /* Manageability interface */ + mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic; + + mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic; + + return ret_val; +} + +/** + * ixgbe_get_link_capabilities_X540 - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: true when autoneg or autotry is enabled + * + * Determines the link capabilities by reading the AUTOC register. + **/ +s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_media_type_X540 - Get media type + * @hw: pointer to hardware structure + * + * Returns the media type (fiber, copper, backplane) + **/ +enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) +{ + UNREFERENCED_1PARAMETER(hw); + return ixgbe_media_type_copper; +} + +/** + * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + **/ +s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + DEBUGFUNC("ixgbe_setup_mac_link_X540"); + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); +} + +/** + * ixgbe_reset_hw_X540 - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks + * and clears all interrupts, and perform a reset. + **/ +s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) +{ + s32 status; + u32 ctrl, i; + u32 swfw_mask = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ixgbe_reset_hw_X540"); + + /* Call adapter stop to disable tx/rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); + if (status != IXGBE_SUCCESS) + goto reset_hw_out; + + /* flush pending Tx transactions */ + ixgbe_clear_tx_pending(hw); + +mac_reset_top: + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return IXGBE_ERR_SWFW_SYNC; + } + ctrl = IXGBE_CTRL_RST; + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + + /* Poll for reset bit to self-clear indicating reset is complete */ + for (i = 0; i < 10; i++) { + usec_delay(1); + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST_MASK)) + break; + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { + status = IXGBE_ERR_RESET_FAILED; + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "Reset polling failed to complete.\n"); + } + msec_delay(100); + + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + goto mac_reset_top; + } + + /* Set the Rx packet buffer size. */ + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. Also reset num_rar_entries to 128, + * since we modify this value when programming the SAN MAC address. + */ + hw->mac.num_rar_entries = 128; + hw->mac.ops.init_rx_addrs(hw); + + /* Store the permanent SAN mac address */ + hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); + + /* Add the SAN MAC address to the RAR only if it's a valid address */ + if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { + /* Save the SAN MAC RAR index */ + hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; + + hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index, + hw->mac.san_addr, 0, IXGBE_RAH_AV); + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index, + IXGBE_CLEAR_VMDQ_ALL); + + /* Reserve the last RAR for the SAN MAC address */ + hw->mac.num_rar_entries--; + } + + /* Store the alternative WWNN/WWPN prefix */ + hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, + &hw->mac.wwpn_prefix); + +reset_hw_out: + return status; +} + +/** + * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware using the generic start_hw function + * and the generation start_hw function. + * Then performs revision-specific operations, if any. + **/ +s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_start_hw_X540"); + + ret_val = ixgbe_start_hw_generic(hw); + if (ret_val != IXGBE_SUCCESS) + goto out; + + ixgbe_start_hw_gen2(hw); + +out: + return ret_val; +} + +/** + * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) +{ + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u16 ext_ability = 0; + + DEBUGFUNC("ixgbe_get_supported_physical_layer_X540"); + + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + + return physical_layer; +} + +/** + * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. + **/ +s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 eec; + u16 eeprom_size; + + DEBUGFUNC("ixgbe_init_eeprom_params_X540"); + + if (eeprom->type == ixgbe_eeprom_uninitialized) { + eeprom->semaphore_delay = 10; + eeprom->type = ixgbe_flash; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> + IXGBE_EEC_SIZE_SHIFT); + eeprom->word_size = 1 << (eeprom_size + + IXGBE_EEPROM_WORD_SIZE_SHIFT); + + hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", + eeprom->type, eeprom->word_size); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_eerd_X540- Read EEPROM word using EERD + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the EERD register. + **/ +s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_read_eerd_X540"); + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == + IXGBE_SUCCESS) { + status = ixgbe_read_eerd_generic(hw, offset, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @words: number of words + * @data: word(s) read from the EEPROM + * + * Reads a 16 bit word(s) from the EEPROM using the EERD register. + **/ +s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_read_eerd_buffer_X540"); + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == + IXGBE_SUCCESS) { + status = ixgbe_read_eerd_buffer_generic(hw, offset, + words, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the EEWR register. + **/ +s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_write_eewr_X540"); + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == + IXGBE_SUCCESS) { + status = ixgbe_write_eewr_generic(hw, offset, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @words: number of words + * @data: word(s) write to the EEPROM + * + * Write a 16 bit word(s) to the EEPROM using the EEWR register. + **/ +s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_write_eewr_buffer_X540"); + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == + IXGBE_SUCCESS) { + status = ixgbe_write_eewr_buffer_generic(hw, offset, + words, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum + * + * This function does not use synchronization for EERD and EEWR. It can + * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. + * + * @hw: pointer to hardware structure + * + * Returns a negative error code on error, or the 16-bit checksum + **/ +s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) +{ + u16 i, j; + u16 checksum = 0; + u16 length = 0; + u16 pointer = 0; + u16 word = 0; + u16 ptr_start = IXGBE_PCIE_ANALOG_PTR; + + /* Do not use hw->eeprom.ops.read because we do not want to take + * the synchronization semaphores here. Instead use + * ixgbe_read_eerd_generic + */ + + DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540"); + + /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the + * checksum itself + */ + for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { + if (ixgbe_read_eerd_generic(hw, i, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + checksum += word; + } + + /* Include all data from pointers 0x3, 0x6-0xE. This excludes the + * FW, PHY module, and PCIe Expansion/Option ROM pointers. + */ + for (i = ptr_start; i < IXGBE_FW_PTR; i++) { + if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) + continue; + + if (ixgbe_read_eerd_generic(hw, i, &pointer)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + + /* Skip pointer section if the pointer is invalid. */ + if (pointer == 0xFFFF || pointer == 0 || + pointer >= hw->eeprom.word_size) + continue; + + if (ixgbe_read_eerd_generic(hw, pointer, &length)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + + /* Skip pointer section if length is invalid. */ + if (length == 0xFFFF || length == 0 || + (u32)length > hw->eeprom.word_size - (u32)pointer) + continue; + + for (j = pointer + 1; j <= pointer + length; j++) { + if (ixgbe_read_eerd_generic(hw, j, &word)) { + hw_dbg(hw, "EEPROM read failed\n"); + return IXGBE_ERR_EEPROM; + } + checksum += word; + } + } + + checksum = (u16)IXGBE_EEPROM_SUM - checksum; + + return (s32)checksum; +} + +/** + * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If the + * caller does not need checksum_val, the value can be NULL. + **/ +s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, + u16 *checksum_val) +{ + s32 status; + u16 checksum; + u16 read_checksum = 0; + + DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) + goto out; + + checksum = (u16)(status & 0xffff); + + /* Do not use hw->eeprom.ops.read because we do not want to take + * the synchronization semaphores twice here. + */ + status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, + &read_checksum); + if (status) + goto out; + + /* Verify read checksum from EEPROM is the same as + * calculated checksum + */ + if (read_checksum != checksum) { + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "Invalid EEPROM checksum"); + status = IXGBE_ERR_EEPROM_CHECKSUM; + } + + /* If the user cares, return the calculated checksum */ + if (checksum_val) + *checksum_val = checksum; + +out: + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + + return status; +} + +/** + * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash + * @hw: pointer to hardware structure + * + * After writing EEPROM to shadow RAM using EEWR register, software calculates + * checksum and updates the EEPROM and instructs the hardware to update + * the flash. + **/ +s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) +{ + s32 status; + u16 checksum; + + DEBUGFUNC("ixgbe_update_eeprom_checksum_X540"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) + goto out; + + checksum = (u16)(status & 0xffff); + + /* Do not use hw->eeprom.ops.write because we do not want to + * take the synchronization semaphores twice here. + */ + status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum); + if (status) + goto out; + + status = ixgbe_update_flash_X540(hw); + +out: + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + + return status; +} + +/** + * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device + * @hw: pointer to hardware structure + * + * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy + * EEPROM from shadow RAM to the flash device. + **/ +s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) +{ + u32 flup; + s32 status; + + DEBUGFUNC("ixgbe_update_flash_X540"); + + status = ixgbe_poll_flash_update_done_X540(hw); + if (status == IXGBE_ERR_EEPROM) { + hw_dbg(hw, "Flash update time out\n"); + goto out; + } + + flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup); + + status = ixgbe_poll_flash_update_done_X540(hw); + if (status == IXGBE_SUCCESS) + hw_dbg(hw, "Flash update complete\n"); + else + hw_dbg(hw, "Flash update time out\n"); + + if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) { + flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + + if (flup & IXGBE_EEC_SEC1VAL) { + flup |= IXGBE_EEC_FLUP; + IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup); + } + + status = ixgbe_poll_flash_update_done_X540(hw); + if (status == IXGBE_SUCCESS) + hw_dbg(hw, "Flash update complete\n"); + else + hw_dbg(hw, "Flash update time out\n"); + } +out: + return status; +} + +/** + * ixgbe_poll_flash_update_done_X540 - Poll flash update status + * @hw: pointer to hardware structure + * + * Polls the FLUDONE (bit 26) of the EEC Register to determine when the + * flash update is done. + **/ +STATIC s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) +{ + u32 i; + u32 reg; + s32 status = IXGBE_ERR_EEPROM; + + DEBUGFUNC("ixgbe_poll_flash_update_done_X540"); + + for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { + reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); + if (reg & IXGBE_EEC_FLUDONE) { + status = IXGBE_SUCCESS; + break; + } + msec_delay(5); + } + + if (i == IXGBE_FLUDONE_ATTEMPTS) + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "Flash update status polling timed out"); + + return status; +} + +/** + * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore thought the SW_FW_SYNC register for + * the specified function (CSR, PHY0, PHY1, NVM, Flash) + **/ +s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) +{ + u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK; + u32 fwmask = swmask << 5; + u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK; + u32 timeout = 200; + u32 hwmask = 0; + u32 swfw_sync; + u32 i; + + DEBUGFUNC("ixgbe_acquire_swfw_sync_X540"); + + if (swmask & IXGBE_GSSR_EEP_SM) + hwmask |= IXGBE_GSSR_FLASH_SM; + + /* SW only mask doesn't have FW bit pair */ + if (mask & IXGBE_GSSR_SW_MNG_SM) + swmask |= IXGBE_GSSR_SW_MNG_SM; + + swmask |= swi2c_mask; + fwmask |= swi2c_mask << 2; + if (hw->mac.type >= ixgbe_mac_X550) + timeout = 1000; + + for (i = 0; i < timeout; i++) { + /* SW NVM semaphore bit is used for access to all + * SW_FW_SYNC bits (not just NVM) + */ + if (ixgbe_get_swfw_sync_semaphore(hw)) { + hw_dbg(hw, "Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n"); + return IXGBE_ERR_SWFW_SYNC; + } + + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); + if (!(swfw_sync & (fwmask | swmask | hwmask))) { + swfw_sync |= swmask; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), + swfw_sync); + ixgbe_release_swfw_sync_semaphore(hw); + return IXGBE_SUCCESS; + } + /* Firmware currently using resource (fwmask), hardware + * currently using resource (hwmask), or other software + * thread currently using resource (swmask) + */ + ixgbe_release_swfw_sync_semaphore(hw); + msec_delay(5); + } + + /* If the resource is not released by the FW/HW the SW can assume that + * the FW/HW malfunctions. In that case the SW should set the SW bit(s) + * of the requested resource(s) while ignoring the corresponding FW/HW + * bits in the SW_FW_SYNC register. + */ + if (ixgbe_get_swfw_sync_semaphore(hw)) { + hw_dbg(hw, "Failed to get NVM sempahore and register semaphore while forcefully ignoring FW sempahore bit(s) and setting SW semaphore bit(s), returning IXGBE_ERR_SWFW_SYNC\n"); + return IXGBE_ERR_SWFW_SYNC; + } + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); + if (swfw_sync & (fwmask | hwmask)) { + swfw_sync |= swmask; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); + ixgbe_release_swfw_sync_semaphore(hw); + msec_delay(5); + return IXGBE_SUCCESS; + } + /* If the resource is not released by other SW the SW can assume that + * the other SW malfunctions. In that case the SW should clear all SW + * flags that it does not own and then repeat the whole process once + * again. + */ + if (swfw_sync & swmask) { + u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | + IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM | + IXGBE_GSSR_SW_MNG_SM; + + if (swi2c_mask) + rmask |= IXGBE_GSSR_I2C_MASK; + ixgbe_release_swfw_sync_X540(hw, rmask); + ixgbe_release_swfw_sync_semaphore(hw); + hw_dbg(hw, "Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n"); + return IXGBE_ERR_SWFW_SYNC; + } + ixgbe_release_swfw_sync_semaphore(hw); + hw_dbg(hw, "Returning error IXGBE_ERR_SWFW_SYNC\n"); + + return IXGBE_ERR_SWFW_SYNC; +} + +/** + * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore through the SW_FW_SYNC register + * for the specified function (CSR, PHY0, PHY1, EVM, Flash) + **/ +void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) +{ + u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM); + u32 swfw_sync; + + DEBUGFUNC("ixgbe_release_swfw_sync_X540"); + + if (mask & IXGBE_GSSR_I2C_MASK) + swmask |= mask & IXGBE_GSSR_I2C_MASK; + ixgbe_get_swfw_sync_semaphore(hw); + + swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); + swfw_sync &= ~swmask; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); + + ixgbe_release_swfw_sync_semaphore(hw); + msec_delay(2); +} + +/** + * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore + * @hw: pointer to hardware structure + * + * Sets the hardware semaphores so SW/FW can gain control of shared resources + **/ +STATIC s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_EEPROM; + u32 timeout = 2000; + u32 i; + u32 swsm; + + DEBUGFUNC("ixgbe_get_swfw_sync_semaphore"); + + /* Get SMBI software semaphore between device drivers first */ + for (i = 0; i < timeout; i++) { + /* + * If the SMBI bit is 0 when we read it, then the bit will be + * set and we have the semaphore + */ + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); + if (!(swsm & IXGBE_SWSM_SMBI)) { + status = IXGBE_SUCCESS; + break; + } + usec_delay(50); + } + + /* Now get the semaphore between SW/FW through the REGSMP bit */ + if (status == IXGBE_SUCCESS) { + for (i = 0; i < timeout; i++) { + swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); + if (!(swsm & IXGBE_SWFW_REGSMP)) + break; + + usec_delay(50); + } + + /* + * Release semaphores and return error if SW NVM semaphore + * was not granted because we don't have access to the EEPROM + */ + if (i >= timeout) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "REGSMP Software NVM semaphore not granted.\n"); + ixgbe_release_swfw_sync_semaphore(hw); + status = IXGBE_ERR_EEPROM; + } + } else { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "Software semaphore SMBI between device drivers " + "not granted.\n"); + } + + return status; +} + +/** + * ixgbe_release_swfw_sync_semaphore - Release hardware semaphore + * @hw: pointer to hardware structure + * + * This function clears hardware semaphore bits. + **/ +STATIC void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) +{ + u32 swsm; + + DEBUGFUNC("ixgbe_release_swfw_sync_semaphore"); + + /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ + + swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); + swsm &= ~IXGBE_SWFW_REGSMP; + IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm); + + swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); + swsm &= ~IXGBE_SWSM_SMBI; + IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm); + + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_init_swfw_sync_X540 - Release hardware semaphore + * @hw: pointer to hardware structure + * + * This function reset hardware semaphore bits for a semaphore that may + * have be left locked due to a catastrophic failure. + **/ +void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw) +{ + u32 rmask; + + /* First try to grab the semaphore but we don't need to bother + * looking to see whether we got the lock or not since we do + * the same thing regardless of whether we got the lock or not. + * We got the lock - we release it. + * We timeout trying to get the lock - we force its release. + */ + ixgbe_get_swfw_sync_semaphore(hw); + ixgbe_release_swfw_sync_semaphore(hw); + + /* Acquire and release all software resources. */ + rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | + IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM | + IXGBE_GSSR_SW_MNG_SM; + + rmask |= IXGBE_GSSR_I2C_MASK; + ixgbe_acquire_swfw_sync_X540(hw, rmask); + ixgbe_release_swfw_sync_X540(hw, rmask); +} + +/** + * ixgbe_blink_led_start_X540 - Blink LED based on index. + * @hw: pointer to hardware structure + * @index: led number to blink + * + * Devices that implement the version 2 interface: + * X540 + **/ +s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) +{ + u32 macc_reg; + u32 ledctl_reg; + ixgbe_link_speed speed; + bool link_up; + + DEBUGFUNC("ixgbe_blink_led_start_X540"); + + if (index > 3) + return IXGBE_ERR_PARAM; + + /* + * Link should be up in order for the blink bit in the LED control + * register to work. Force link and speed in the MAC if link is down. + * This will be reversed when we stop the blinking. + */ + hw->mac.ops.check_link(hw, &speed, &link_up, false); + if (link_up == false) { + macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); + macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; + IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); + } + /* Set the LED to LINK_UP + BLINK. */ + ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); + ledctl_reg |= IXGBE_LED_BLINK(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index. + * @hw: pointer to hardware structure + * @index: led number to stop blinking + * + * Devices that implement the version 2 interface: + * X540 + **/ +s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) +{ + u32 macc_reg; + u32 ledctl_reg; + + if (index > 3) + return IXGBE_ERR_PARAM; + + DEBUGFUNC("ixgbe_blink_led_stop_X540"); + + /* Restore the LED to its default value. */ + ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); + ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); + ledctl_reg &= ~IXGBE_LED_BLINK(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); + + /* Unforce link and speed in the MAC. */ + macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); + macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS); + IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.h new file mode 100644 index 0000000000..f774f689c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x540.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_X540_H_ +#define _IXGBE_X540_H_ + +#include "ixgbe_type.h" + +s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *autoneg); +enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw); +s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool link_up_wait_to_complete); +s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw); +s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw); + +s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw); +s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, u16 offset, u16 words, + u16 *data); +s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data); +s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, u16 offset, u16 words, + u16 *data); +s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw); +s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, u16 *checksum_val); +s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw); +s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); + +s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); +void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw); + +s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index); +#endif /* _IXGBE_X540_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.c new file mode 100644 index 0000000000..fd57dc5761 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.c @@ -0,0 +1,4573 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe_x550.h" +#include "ixgbe_x540.h" +#include "ixgbe_type.h" +#include "ixgbe_api.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" + +STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed); +STATIC s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask); +STATIC void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask); +STATIC s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw); + +/** + * ixgbe_init_ops_X550 - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type for X550. + * Does not touch the hardware. + **/ +s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550"); + + ret_val = ixgbe_init_ops_X540(hw); + mac->ops.dmac_config = ixgbe_dmac_config_X550; + mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550; + mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550; + mac->ops.setup_eee = NULL; + mac->ops.set_source_address_pruning = + ixgbe_set_source_address_pruning_X550; + mac->ops.set_ethertype_anti_spoofing = + ixgbe_set_ethertype_anti_spoofing_X550; + + mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic; + eeprom->ops.init_params = ixgbe_init_eeprom_params_X550; + eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550; + eeprom->ops.read = ixgbe_read_ee_hostif_X550; + eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550; + eeprom->ops.write = ixgbe_write_ee_hostif_X550; + eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550; + eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550; + eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550; + + mac->ops.disable_mdd = ixgbe_disable_mdd_X550; + mac->ops.enable_mdd = ixgbe_enable_mdd_X550; + mac->ops.mdd_event = ixgbe_mdd_event_X550; + mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550; + mac->ops.fw_recovery_mode = ixgbe_fw_recovery_mode_X550; + mac->ops.disable_rx = ixgbe_disable_rx_x550; + /* Manageability interface */ + mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550; + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_1G_T: + hw->mac.ops.led_on = NULL; + hw->mac.ops.led_off = NULL; + break; + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: + hw->mac.ops.led_on = ixgbe_led_on_t_X550em; + hw->mac.ops.led_off = ixgbe_led_off_t_X550em; + break; + default: + break; + } + return ret_val; +} + +/** + * ixgbe_read_cs4227 - Read CS4227 register + * @hw: pointer to hardware structure + * @reg: register number to write + * @value: pointer to receive value read + * + * Returns status code + **/ +STATIC s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value) +{ + return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value); +} + +/** + * ixgbe_write_cs4227 - Write CS4227 register + * @hw: pointer to hardware structure + * @reg: register number to write + * @value: value to write to register + * + * Returns status code + **/ +STATIC s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value) +{ + return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value); +} + +/** + * ixgbe_read_pe - Read register from port expander + * @hw: pointer to hardware structure + * @reg: register number to read + * @value: pointer to receive read value + * + * Returns status code + **/ +STATIC s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value) +{ + s32 status; + + status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value); + if (status != IXGBE_SUCCESS) + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "port expander access failed with %d\n", status); + return status; +} + +/** + * ixgbe_write_pe - Write register to port expander + * @hw: pointer to hardware structure + * @reg: register number to write + * @value: value to write + * + * Returns status code + **/ +STATIC s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value) +{ + s32 status; + + status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value); + if (status != IXGBE_SUCCESS) + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "port expander access failed with %d\n", status); + return status; +} + +/** + * ixgbe_reset_cs4227 - Reset CS4227 using port expander + * @hw: pointer to hardware structure + * + * This function assumes that the caller has acquired the proper semaphore. + * Returns error code + **/ +STATIC s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw) +{ + s32 status; + u32 retry; + u16 value; + u8 reg; + + /* Trigger hard reset. */ + status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®); + if (status != IXGBE_SUCCESS) + return status; + reg |= IXGBE_PE_BIT1; + status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg); + if (status != IXGBE_SUCCESS) + return status; + + status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, ®); + if (status != IXGBE_SUCCESS) + return status; + reg &= ~IXGBE_PE_BIT1; + status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg); + if (status != IXGBE_SUCCESS) + return status; + + status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®); + if (status != IXGBE_SUCCESS) + return status; + reg &= ~IXGBE_PE_BIT1; + status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg); + if (status != IXGBE_SUCCESS) + return status; + + usec_delay(IXGBE_CS4227_RESET_HOLD); + + status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®); + if (status != IXGBE_SUCCESS) + return status; + reg |= IXGBE_PE_BIT1; + status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg); + if (status != IXGBE_SUCCESS) + return status; + + /* Wait for the reset to complete. */ + msec_delay(IXGBE_CS4227_RESET_DELAY); + for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) { + status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS, + &value); + if (status == IXGBE_SUCCESS && + value == IXGBE_CS4227_EEPROM_LOAD_OK) + break; + msec_delay(IXGBE_CS4227_CHECK_DELAY); + } + if (retry == IXGBE_CS4227_RETRIES) { + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "CS4227 reset did not complete."); + return IXGBE_ERR_PHY; + } + + status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value); + if (status != IXGBE_SUCCESS || + !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) { + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "CS4227 EEPROM did not load successfully."); + return IXGBE_ERR_PHY; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_check_cs4227 - Check CS4227 and reset as needed + * @hw: pointer to hardware structure + **/ +STATIC void ixgbe_check_cs4227(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u32 swfw_mask = hw->phy.phy_semaphore_mask; + u16 value = 0; + u8 retry; + + for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) { + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + msec_delay(IXGBE_CS4227_CHECK_DELAY); + continue; + } + + /* Get status of reset flow. */ + status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value); + + if (status == IXGBE_SUCCESS && + value == IXGBE_CS4227_RESET_COMPLETE) + goto out; + + if (status != IXGBE_SUCCESS || + value != IXGBE_CS4227_RESET_PENDING) + break; + + /* Reset is pending. Wait and check again. */ + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + msec_delay(IXGBE_CS4227_CHECK_DELAY); + } + + /* If still pending, assume other instance failed. */ + if (retry == IXGBE_CS4227_RETRIES) { + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return; + } + } + + /* Reset the CS4227. */ + status = ixgbe_reset_cs4227(hw); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, + "CS4227 reset failed: %d", status); + goto out; + } + + /* Reset takes so long, temporarily release semaphore in case the + * other driver instance is waiting for the reset indication. + */ + ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH, + IXGBE_CS4227_RESET_PENDING); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + msec_delay(10); + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return; + } + + /* Record completion for next time. */ + status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH, + IXGBE_CS4227_RESET_COMPLETE); + +out: + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + msec_delay(hw->eeprom.semaphore_delay); +} + +/** + * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control + * @hw: pointer to hardware structure + **/ +STATIC void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) +{ + u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + + if (hw->bus.lan_id) { + esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1); + esdp |= IXGBE_ESDP_SDP1_DIR; + } + esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR); + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_identify_phy_x550em - Get PHY type based on device id + * @hw: pointer to hardware structure + * + * Returns error code + */ +STATIC s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) +{ + hw->mac.ops.set_lan_id(hw); + + ixgbe_read_mng_if_sel_x550em(hw); + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_SFP: + return ixgbe_identify_sfp_module_X550em(hw); + case IXGBE_DEV_ID_X550EM_X_SFP: + /* set up for CS4227 usage */ + ixgbe_setup_mux_ctl(hw); + ixgbe_check_cs4227(hw); + fallthrough; + case IXGBE_DEV_ID_X550EM_A_SFP_N: + return ixgbe_identify_sfp_module_X550em(hw); + break; + case IXGBE_DEV_ID_X550EM_X_KX4: + hw->phy.type = ixgbe_phy_x550em_kx4; + break; + case IXGBE_DEV_ID_X550EM_X_XFI: + hw->phy.type = ixgbe_phy_x550em_xfi; + break; + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + hw->phy.type = ixgbe_phy_x550em_kr; + break; + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_X_10G_T: + return ixgbe_identify_phy_generic(hw); + case IXGBE_DEV_ID_X550EM_X_1G_T: + hw->phy.type = ixgbe_phy_ext_1g_t; + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + hw->phy.type = ixgbe_phy_fw; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; + break; + default: + break; + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fw_phy_activity - Perform an activity on a PHY + * @hw: pointer to hardware structure + * @activity: activity to perform + * @data: Pointer to 4 32-bit words of data + */ +s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity, + u32 (*data)[FW_PHY_ACT_DATA_COUNT]) +{ + union { + struct ixgbe_hic_phy_activity_req cmd; + struct ixgbe_hic_phy_activity_resp rsp; + } hic; + u16 retries = FW_PHY_ACT_RETRIES; + s32 rc; + u16 i; + + do { + memset(&hic, 0, sizeof(hic)); + hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD; + hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN; + hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + hic.cmd.port_number = hw->bus.lan_id; + hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity); + for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) + hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]); + + rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd, + sizeof(hic.cmd), + IXGBE_HI_COMMAND_TIMEOUT, + true); + if (rc != IXGBE_SUCCESS) + return rc; + if (hic.rsp.hdr.cmd_or_resp.ret_status == + FW_CEM_RESP_STATUS_SUCCESS) { + for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i) + (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]); + return IXGBE_SUCCESS; + } + usec_delay(20); + --retries; + } while (retries > 0); + + return IXGBE_ERR_HOST_INTERFACE_COMMAND; +} + +static const struct { + u16 fw_speed; + ixgbe_link_speed phy_speed; +} ixgbe_fw_map[] = { + { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL }, + { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL }, + { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL }, + { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL }, + { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL }, + { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL }, +}; + +/** + * ixgbe_get_phy_id_fw - Get the phy ID via firmware command + * @hw: pointer to hardware structure + * + * Returns error code + */ +static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw) +{ + u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; + u16 phy_speeds; + u16 phy_id_lo; + s32 rc; + u16 i; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info); + if (rc) + return rc; + + hw->phy.speeds_supported = 0; + phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK; + for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) { + if (phy_speeds & ixgbe_fw_map[i].fw_speed) + hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed; + } + if (!hw->phy.autoneg_advertised) + hw->phy.autoneg_advertised = hw->phy.speeds_supported; + + hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK; + phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK; + hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; + hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; + if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) + return IXGBE_ERR_PHY_ADDR_INVALID; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_identify_phy_fw - Get PHY type based on firmware command + * @hw: pointer to hardware structure + * + * Returns error code + */ +static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw) +{ + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; + + hw->phy.type = ixgbe_phy_fw; + hw->phy.ops.read_reg = NULL; + hw->phy.ops.write_reg = NULL; + return ixgbe_get_phy_id_fw(hw); +} + +/** + * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY + * @hw: pointer to hardware structure + * + * Returns error code + */ +s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw) +{ + u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; + + setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF; + return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup); +} + +STATIC s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) +{ + UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data); + return IXGBE_NOT_IMPLEMENTED; +} + +STATIC s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data); + return IXGBE_NOT_IMPLEMENTED; +} + +/** + * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to read from + * @reg: I2C device register to read from + * @val: pointer to location to receive read value + * + * Returns an error code on error. + **/ +STATIC s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr, + u16 reg, u16 *val) +{ + return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true); +} + +/** + * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to read from + * @reg: I2C device register to read from + * @val: pointer to location to receive read value + * + * Returns an error code on error. + **/ +STATIC s32 +ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr, + u16 reg, u16 *val) +{ + return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false); +} + +/** + * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to write to + * @reg: I2C device register to write to + * @val: value to write + * + * Returns an error code on error. + **/ +STATIC s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, + u8 addr, u16 reg, u16 val) +{ + return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true); +} + +/** + * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation + * @hw: pointer to the hardware structure + * @addr: I2C bus address to write to + * @reg: I2C device register to write to + * @val: value to write + * + * Returns an error code on error. + **/ +STATIC s32 +ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, + u8 addr, u16 reg, u16 val) +{ + return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false); +} + +/** +* ixgbe_init_ops_X550EM - Inits func ptrs and MAC type +* @hw: pointer to hardware structure +* +* Initialize the function pointers and for MAC type X550EM. +* Does not touch the hardware. +**/ +s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550EM"); + + /* Similar to X550 so start there. */ + ret_val = ixgbe_init_ops_X550(hw); + + /* Since this function eventually calls + * ixgbe_init_ops_540 by design, we are setting + * the pointers to NULL explicitly here to overwrite + * the values being set in the x540 function. + */ + /* Thermal sensor not supported in x550EM */ + mac->ops.get_thermal_sensor_data = NULL; + mac->ops.init_thermal_sensor_thresh = NULL; + mac->thermal_sensor_enabled = false; + + /* FCOE not supported in x550EM */ + mac->ops.get_san_mac_addr = NULL; + mac->ops.set_san_mac_addr = NULL; + mac->ops.get_wwn_prefix = NULL; + mac->ops.get_fcoe_boot_status = NULL; + + /* IPsec not supported in x550EM */ + mac->ops.disable_sec_rx_path = NULL; + mac->ops.enable_sec_rx_path = NULL; + + /* AUTOC register is not present in x550EM. */ + mac->ops.prot_autoc_read = NULL; + mac->ops.prot_autoc_write = NULL; + + /* X550EM bus type is internal*/ + hw->bus.type = ixgbe_bus_type_internal; + mac->ops.get_bus_info = ixgbe_get_bus_info_X550em; + + + mac->ops.get_media_type = ixgbe_get_media_type_X550em; + mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em; + mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em; + mac->ops.reset_hw = ixgbe_reset_hw_X550em; + mac->ops.get_supported_physical_layer = + ixgbe_get_supported_physical_layer_X550em; + + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) + mac->ops.setup_fc = ixgbe_setup_fc_generic; + else + mac->ops.setup_fc = ixgbe_setup_fc_X550em; + + /* PHY */ + phy->ops.init = ixgbe_init_phy_ops_X550em; + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + mac->ops.setup_fc = NULL; + phy->ops.identify = ixgbe_identify_phy_fw; + phy->ops.set_phy_power = NULL; + phy->ops.get_firmware_version = NULL; + break; + case IXGBE_DEV_ID_X550EM_X_1G_T: + mac->ops.setup_fc = NULL; + phy->ops.identify = ixgbe_identify_phy_x550em; + phy->ops.set_phy_power = NULL; + break; + default: + phy->ops.identify = ixgbe_identify_phy_x550em; + } + + if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper) + phy->ops.set_phy_power = NULL; + + /* EEPROM */ + eeprom->ops.init_params = ixgbe_init_eeprom_params_X540; + eeprom->ops.read = ixgbe_read_ee_hostif_X550; + eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550; + eeprom->ops.write = ixgbe_write_ee_hostif_X550; + eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550; + eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550; + eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550; + eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550; + + return ret_val; +} + +/** + * ixgbe_setup_fw_link - Setup firmware-controlled PHYs + * @hw: pointer to hardware structure + */ +static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw) +{ + u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + u16 i; + + if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) + return 0; + + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + switch (hw->fc.requested_mode) { + case ixgbe_fc_full: + setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX << + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; + break; + case ixgbe_fc_rx_pause: + setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX << + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; + break; + case ixgbe_fc_tx_pause: + setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX << + FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT; + break; + default: + break; + } + + for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) { + if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed) + setup[0] |= (u32)(ixgbe_fw_map[i].fw_speed); + } + setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN; + + if (hw->phy.eee_speeds_advertised) + setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); + if (rc) + return rc; + if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) + return IXGBE_ERR_OVERTEMP; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_fc_autoneg_fw - Set up flow control for FW-controlled PHYs + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + */ +static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw) +{ + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + return ixgbe_setup_fw_link(hw); +} + +/** + * ixgbe_setup_eee_fw - Enable/disable EEE support + * @hw: pointer to the HW structure + * @enable_eee: boolean flag to enable EEE + * + * Enable/disable EEE based on enable_eee flag. + * This function controls EEE for firmware-based PHY implementations. + */ +static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee) +{ + if (!!hw->phy.eee_speeds_advertised == enable_eee) + return IXGBE_SUCCESS; + if (enable_eee) + hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; + else + hw->phy.eee_speeds_advertised = 0; + return hw->phy.ops.setup_link(hw); +} + +/** +* ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type +* @hw: pointer to hardware structure +* +* Initialize the function pointers and for MAC type X550EM_a. +* Does not touch the hardware. +**/ +s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550EM_a"); + + /* Start with generic X550EM init */ + ret_val = ixgbe_init_ops_X550EM(hw); + + mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; + mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; + mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a; + mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a; + + switch (mac->ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + mac->ops.setup_fc = NULL; + mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a; + break; + case ixgbe_media_type_backplane: + mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a; + mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a; + break; + default: + break; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a; + mac->ops.setup_fc = ixgbe_fc_autoneg_fw; + mac->ops.setup_eee = ixgbe_setup_eee_fw; + hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported; + break; + default: + break; + } + + return ret_val; +} + +/** +* ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type +* @hw: pointer to hardware structure +* +* Initialize the function pointers and for MAC type X550EM_x. +* Does not touch the hardware. +**/ +s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_link_info *link = &hw->link; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550EM_x"); + + /* Start with generic X550EM init */ + ret_val = ixgbe_init_ops_X550EM(hw); + + mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550; + mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550; + mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em; + mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em; + link->ops.read_link = ixgbe_read_i2c_combined_generic; + link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked; + link->ops.write_link = ixgbe_write_i2c_combined_generic; + link->ops.write_link_unlocked = + ixgbe_write_i2c_combined_generic_unlocked; + link->addr = IXGBE_CS4227; + + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) { + mac->ops.setup_fc = NULL; + mac->ops.setup_eee = NULL; + mac->ops.init_led_link_act = NULL; + } + + return ret_val; +} + +/** + * ixgbe_dmac_config_X550 + * @hw: pointer to hardware structure + * + * Configure DMA coalescing. If enabling dmac, dmac is activated. + * When disabling dmac, dmac enable dmac bit is cleared. + **/ +s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw) +{ + u32 reg, high_pri_tc; + + DEBUGFUNC("ixgbe_dmac_config_X550"); + + /* Disable DMA coalescing before configuring */ + reg = IXGBE_READ_REG(hw, IXGBE_DMACR); + reg &= ~IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + + /* Disable DMA Coalescing if the watchdog timer is 0 */ + if (!hw->mac.dmac_config.watchdog_timer) + goto out; + + ixgbe_dmac_config_tcs_X550(hw); + + /* Configure DMA Coalescing Control Register */ + reg = IXGBE_READ_REG(hw, IXGBE_DMACR); + + /* Set the watchdog timer in units of 40.96 usec */ + reg &= ~IXGBE_DMACR_DMACWT_MASK; + reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096; + + reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK; + /* If fcoe is enabled, set high priority traffic class */ + if (hw->mac.dmac_config.fcoe_en) { + high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc; + reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) & + IXGBE_DMACR_HIGH_PRI_TC_MASK); + } + reg |= IXGBE_DMACR_EN_MNG_IND; + + /* Enable DMA coalescing after configuration */ + reg |= IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + +out: + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dmac_config_tcs_X550 + * @hw: pointer to hardware structure + * + * Configure DMA coalescing threshold per TC. The dmac enable bit must + * be cleared before configuring. + **/ +s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw) +{ + u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb; + + DEBUGFUNC("ixgbe_dmac_config_tcs_X550"); + + /* Configure DMA coalescing enabled */ + switch (hw->mac.dmac_config.link_speed) { + case IXGBE_LINK_SPEED_10_FULL: + case IXGBE_LINK_SPEED_100_FULL: + pb_headroom = IXGBE_DMACRXT_100M; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + pb_headroom = IXGBE_DMACRXT_1G; + break; + default: + pb_headroom = IXGBE_DMACRXT_10G; + break; + } + + maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >> + IXGBE_MHADD_MFS_SHIFT) / 1024); + + /* Set the per Rx packet buffer receive threshold */ + for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) { + reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc)); + reg &= ~IXGBE_DMCTH_DMACRXT_MASK; + + if (tc < hw->mac.dmac_config.num_tcs) { + /* Get Rx PB size */ + rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc)); + rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >> + IXGBE_RXPBSIZE_SHIFT; + + /* Calculate receive buffer threshold in kilobytes */ + if (rx_pb_size > pb_headroom) + rx_pb_size = rx_pb_size - pb_headroom; + else + rx_pb_size = 0; + + /* Minimum of MFS shall be set for DMCTH */ + reg |= (rx_pb_size > maxframe_size_kb) ? + rx_pb_size : maxframe_size_kb; + } + IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg); + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dmac_update_tcs_X550 + * @hw: pointer to hardware structure + * + * Disables dmac, updates per TC settings, and then enables dmac. + **/ +s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw) +{ + u32 reg; + + DEBUGFUNC("ixgbe_dmac_update_tcs_X550"); + + /* Disable DMA coalescing before configuring */ + reg = IXGBE_READ_REG(hw, IXGBE_DMACR); + reg &= ~IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + + ixgbe_dmac_config_tcs_X550(hw); + + /* Enable DMA coalescing after configuration */ + reg = IXGBE_READ_REG(hw, IXGBE_DMACR); + reg |= IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. + **/ +s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom = &hw->eeprom; + u32 eec; + u16 eeprom_size; + + DEBUGFUNC("ixgbe_init_eeprom_params_X550"); + + if (eeprom->type == ixgbe_eeprom_uninitialized) { + eeprom->semaphore_delay = 10; + eeprom->type = ixgbe_flash; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> + IXGBE_EEC_SIZE_SHIFT); + eeprom->word_size = 1 << (eeprom_size + + IXGBE_EEPROM_WORD_SIZE_SHIFT); + + hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", + eeprom->type, eeprom->word_size); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning + * @hw: pointer to hardware structure + * @enable: enable or disable source address pruning + * @pool: Rx pool to set source address pruning for + **/ +void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable, + unsigned int pool) +{ + u64 pfflp; + + /* max rx pool is 63 */ + if (pool > 63) + return; + + pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL); + pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32; + + if (enable) + pfflp |= (1ULL << pool); + else + pfflp &= ~(1ULL << pool); + + IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp); + IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32)); +} + +/** + * ixgbe_set_ethertype_anti_spoofing_X550 - Configure Ethertype anti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for Ethertype anti-spoofing + * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing + * + **/ +void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, + bool enable, int vf) +{ + int vf_target_reg = vf >> 3; + int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT; + u32 pfvfspoof; + + DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550"); + + pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); + if (enable) + pfvfspoof |= (1 << vf_target_shift); + else + pfvfspoof &= ~(1 << vf_target_shift); + + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); +} + +/** + * ixgbe_iosf_wait - Wait for IOSF command completion + * @hw: pointer to hardware structure + * @ctrl: pointer to location to receive final IOSF control value + * + * Returns failing status on timeout + * + * Note: ctrl can be NULL if the IOSF control register value is not needed + **/ +STATIC s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl) +{ + u32 i, command = 0; + + /* Check every 10 usec to see if the address cycle completed. + * The SB IOSF BUSY bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL); + if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0) + break; + usec_delay(10); + } + if (ctrl) + *ctrl = command; + if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n"); + return IXGBE_ERR_PHY; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register + * of the IOSF device + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 3 bit device type + * @data: Data to write to the register + **/ +s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 data) +{ + u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM; + u32 command, error; + s32 ret; + + ret = ixgbe_acquire_swfw_semaphore(hw, gssr); + if (ret != IXGBE_SUCCESS) + return ret; + + ret = ixgbe_iosf_wait(hw, NULL); + if (ret != IXGBE_SUCCESS) + goto out; + + command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | + (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); + + /* Write IOSF control register */ + IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); + + /* Write IOSF data register */ + IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data); + + ret = ixgbe_iosf_wait(hw, &command); + + if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { + error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> + IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Failed to write, error %x\n", error); + ret = IXGBE_ERR_PHY; + } + +out: + ixgbe_release_swfw_semaphore(hw, gssr); + return ret; +} + +/** + * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 3 bit device type + * @data: Pointer to read data from the register + **/ +s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *data) +{ + u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM; + u32 command, error; + s32 ret; + + ret = ixgbe_acquire_swfw_semaphore(hw, gssr); + if (ret != IXGBE_SUCCESS) + return ret; + + ret = ixgbe_iosf_wait(hw, NULL); + if (ret != IXGBE_SUCCESS) + goto out; + + command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | + (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); + + /* Write IOSF control register */ + IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); + + ret = ixgbe_iosf_wait(hw, &command); + + if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { + error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> + IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Failed to read, error %x\n", error); + ret = IXGBE_ERR_PHY; + } + + if (ret == IXGBE_SUCCESS) + *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA); + +out: + ixgbe_release_swfw_semaphore(hw, gssr); + return ret; +} + +/** + * ixgbe_get_phy_token - Get the token for shared phy access + * @hw: Pointer to hardware structure + */ + +s32 ixgbe_get_phy_token(struct ixgbe_hw *hw) +{ + struct ixgbe_hic_phy_token_req token_cmd; + s32 status; + + token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD; + token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN; + token_cmd.hdr.cmd_or_resp.cmd_resv = 0; + token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + token_cmd.port_number = hw->bus.lan_id; + token_cmd.command_type = FW_PHY_TOKEN_REQ; + token_cmd.pad = 0; + status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd, + sizeof(token_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + true); + if (status) { + hw_dbg(hw, "Issuing host interface command failed with Status = %d\n", + status); + return status; + } + if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) + return IXGBE_SUCCESS; + if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) { + hw_dbg(hw, "Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n", + token_cmd.hdr.cmd_or_resp.ret_status); + return IXGBE_ERR_FW_RESP_INVALID; + } + + hw_dbg(hw, "Returning IXGBE_ERR_TOKEN_RETRY\n"); + return IXGBE_ERR_TOKEN_RETRY; +} + +/** + * ixgbe_put_phy_token - Put the token for shared phy access + * @hw: Pointer to hardware structure + */ + +s32 ixgbe_put_phy_token(struct ixgbe_hw *hw) +{ + struct ixgbe_hic_phy_token_req token_cmd; + s32 status; + + token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD; + token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN; + token_cmd.hdr.cmd_or_resp.cmd_resv = 0; + token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + token_cmd.port_number = hw->bus.lan_id; + token_cmd.command_type = FW_PHY_TOKEN_REL; + token_cmd.pad = 0; + status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd, + sizeof(token_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + true); + if (status) + return status; + if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) + return IXGBE_SUCCESS; + + hw_dbg(hw, "Put PHY Token host interface command failed"); + return IXGBE_ERR_FW_RESP_INVALID; +} + +/** + * ixgbe_disable_mdd_X550 + * @hw: pointer to hardware structure + * + * Disable malicious driver detection + **/ +void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw) +{ + u32 reg; + + DEBUGFUNC("ixgbe_disable_mdd_X550"); + + /* Disable MDD for TX DMA and interrupt */ + reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg); + + /* Disable MDD for RX and interrupt */ + reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); +} + +/** + * ixgbe_enable_mdd_X550 + * @hw: pointer to hardware structure + * + * Enable malicious driver detection + **/ +void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw) +{ + u32 reg; + + DEBUGFUNC("ixgbe_enable_mdd_X550"); + + /* Enable MDD for TX DMA and interrupt */ + reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg); + + /* Enable MDD for RX and interrupt */ + reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); +} + +/** + * ixgbe_restore_mdd_vf_X550 + * @hw: pointer to hardware structure + * @vf: vf index + * + * Restore VF that was disabled during malicious driver detection event + **/ +void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf) +{ + u32 idx, reg, num_qs, start_q, bitmask; + + DEBUGFUNC("ixgbe_restore_mdd_vf_X550"); + + /* Map VF to queues */ + reg = IXGBE_READ_REG(hw, IXGBE_MRQC); + switch (reg & IXGBE_MRQC_MRQE_MASK) { + case IXGBE_MRQC_VMDQRT8TCEN: + num_qs = 8; /* 16 VFs / pools */ + bitmask = 0x000000FF; + break; + case IXGBE_MRQC_VMDQRSS32EN: + case IXGBE_MRQC_VMDQRT4TCEN: + num_qs = 4; /* 32 VFs / pools */ + bitmask = 0x0000000F; + break; + default: /* 64 VFs / pools */ + num_qs = 2; + bitmask = 0x00000003; + break; + } + start_q = vf * num_qs; + + /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */ + idx = start_q / 32; + reg = 0; + reg |= (bitmask << (start_q % 32)); + IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg); + IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg); +} + +/** + * ixgbe_mdd_event_X550 + * @hw: pointer to hardware structure + * @vf_bitmap: vf bitmap of malicious vfs + * + * Handle malicious driver detection event. + **/ +void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap) +{ + u32 wqbr; + u32 i, j, reg, q, shift, vf, idx; + + DEBUGFUNC("ixgbe_mdd_event_X550"); + + /* figure out pool size for mapping to vf's */ + reg = IXGBE_READ_REG(hw, IXGBE_MRQC); + switch (reg & IXGBE_MRQC_MRQE_MASK) { + case IXGBE_MRQC_VMDQRT8TCEN: + shift = 3; /* 16 VFs / pools */ + break; + case IXGBE_MRQC_VMDQRSS32EN: + case IXGBE_MRQC_VMDQRT4TCEN: + shift = 2; /* 32 VFs / pools */ + break; + default: + shift = 1; /* 64 VFs / pools */ + break; + } + + /* Read WQBR_TX and WQBR_RX and check for malicious queues */ + for (i = 0; i < 4; i++) { + wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i)); + wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i)); + + if (!wqbr) + continue; + + /* Get malicious queue */ + for (j = 0; j < 32 && wqbr; j++) { + + if (!(wqbr & (1 << j))) + continue; + + /* Get queue from bitmask */ + q = j + (i * 32); + + /* Map queue to vf */ + vf = (q >> shift); + + /* Set vf bit in vf_bitmap */ + idx = vf / 32; + vf_bitmap[idx] |= (1 << (vf % 32)); + wqbr &= ~(1 << j); + } + } +} + +/** + * ixgbe_get_media_type_X550em - Get media type + * @hw: pointer to hardware structure + * + * Returns the media type (fiber, copper, backplane) + */ +enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) +{ + enum ixgbe_media_type media_type; + + DEBUGFUNC("ixgbe_get_media_type_X550em"); + + /* Detect if there is a copper PHY attached. */ + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_KX4: + case IXGBE_DEV_ID_X550EM_X_XFI: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + media_type = ixgbe_media_type_backplane; + break; + case IXGBE_DEV_ID_X550EM_X_SFP: + case IXGBE_DEV_ID_X550EM_A_SFP: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_QSFP: + case IXGBE_DEV_ID_X550EM_A_QSFP_N: + media_type = ixgbe_media_type_fiber; + break; + case IXGBE_DEV_ID_X550EM_X_1G_T: + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_10G_T: + media_type = ixgbe_media_type_copper; + break; + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + media_type = ixgbe_media_type_backplane; + hw->phy.type = ixgbe_phy_sgmii; + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + media_type = ixgbe_media_type_copper; + break; + default: + media_type = ixgbe_media_type_unknown; + break; + } + return media_type; +} + +/** + * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported + * @hw: pointer to hardware structure + * @linear: true if SFP module is linear + */ +STATIC s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear) +{ + DEBUGFUNC("ixgbe_supported_sfp_modules_X550em"); + + switch (hw->phy.sfp_type) { + case ixgbe_sfp_type_not_present: + return IXGBE_ERR_SFP_NOT_PRESENT; + case ixgbe_sfp_type_da_cu_core0: + case ixgbe_sfp_type_da_cu_core1: + *linear = true; + break; + case ixgbe_sfp_type_srlr_core0: + case ixgbe_sfp_type_srlr_core1: + case ixgbe_sfp_type_da_act_lmt_core0: + case ixgbe_sfp_type_da_act_lmt_core1: + case ixgbe_sfp_type_1g_sx_core0: + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: + *linear = false; + break; + case ixgbe_sfp_type_unknown: + case ixgbe_sfp_type_1g_cu_core0: + case ixgbe_sfp_type_1g_cu_core1: + default: + return IXGBE_ERR_SFP_NOT_SUPPORTED; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_identify_sfp_module_X550em - Identifies SFP modules + * @hw: pointer to hardware structure + * + * Searches for and identifies the SFP module and assigns appropriate PHY type. + **/ +s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw) +{ + s32 status; + bool linear; + + DEBUGFUNC("ixgbe_identify_sfp_module_X550em"); + + status = ixgbe_identify_module_generic(hw); + + if (status != IXGBE_SUCCESS) + return status; + + /* Check if SFP module is supported */ + status = ixgbe_supported_sfp_modules_X550em(hw, &linear); + + return status; +} + +/** + * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops + * @hw: pointer to hardware structure + */ +s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw) +{ + s32 status; + bool linear; + + DEBUGFUNC("ixgbe_setup_sfp_modules_X550em"); + + /* Check if SFP module is supported */ + status = ixgbe_supported_sfp_modules_X550em(hw, &linear); + + if (status != IXGBE_SUCCESS) + return status; + + ixgbe_init_mac_link_ops_X550em(hw); + hw->phy.ops.reset = NULL; + + return IXGBE_SUCCESS; +} + +/** +* ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the +* internal PHY +* @hw: pointer to hardware structure +**/ +STATIC s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u32 link_ctrl; + + /* Restart auto-negotiation. */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl); + + if (status) { + hw_dbg(hw, "Auto-negotiation did not complete\n"); + return status; + } + + link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl); + + if (hw->mac.type == ixgbe_mac_X550EM_a) { + u32 flx_mask_st20; + + /* Indicate to FW that AN restart has been asserted */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20); + + if (status) { + hw_dbg(hw, "Auto-negotiation did not complete\n"); + return status; + } + + flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20); + } + + return status; +} + +/** + * ixgbe_setup_sgmii - Set up link for sgmii + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait: true when waiting for completion is needed + */ +STATIC s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait) +{ + struct ixgbe_mac_info *mac = &hw->mac; + u32 lval, sval, flx_val; + s32 rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); + if (rc) + return rc; + + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); + if (rc) + return rc; + + sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; + sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, sval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); + if (rc) + return rc; + + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); + if (rc) + return rc; + + rc = ixgbe_restart_an_internal_phy_x550em(hw); + if (rc) + return rc; + + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); +} + +/** + * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait: true when waiting for completion is needed + */ +STATIC s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed, + bool autoneg_wait) +{ + struct ixgbe_mac_info *mac = &hw->mac; + u32 lval, sval, flx_val; + s32 rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &lval); + if (rc) + return rc; + + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN; + lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN; + lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &sval); + if (rc) + return rc; + + sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D; + sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D; + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, sval); + if (rc) + return rc; + + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, lval); + if (rc) + return rc; + + rc = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val); + if (rc) + return rc; + + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; + flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + + rc = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val); + if (rc) + return rc; + + rc = ixgbe_restart_an_internal_phy_x550em(hw); + + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait); +} + +/** + * ixgbe_init_mac_link_ops_X550em - init mac link function pointers + * @hw: pointer to hardware structure + */ +void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + + DEBUGFUNC("ixgbe_init_mac_link_ops_X550em"); + + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + /* CS4227 does not support autoneg, so disable the laser control + * functions for SFP+ fiber + */ + mac->ops.disable_tx_laser = NULL; + mac->ops.enable_tx_laser = NULL; + mac->ops.flap_tx_laser = NULL; + mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber; + mac->ops.set_rate_select_speed = + ixgbe_set_soft_rate_select_speed; + + if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) || + (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP)) + mac->ops.setup_mac_link = + ixgbe_setup_mac_link_sfp_x550a; + else + mac->ops.setup_mac_link = + ixgbe_setup_mac_link_sfp_x550em; + break; + case ixgbe_media_type_copper: + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) + break; + if (hw->mac.type == ixgbe_mac_X550EM_a) { + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || + hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) { + mac->ops.setup_link = ixgbe_setup_sgmii_fw; + mac->ops.check_link = + ixgbe_check_mac_link_generic; + } else { + mac->ops.setup_link = + ixgbe_setup_mac_link_t_X550em; + } + } else { + mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; + mac->ops.check_link = ixgbe_check_link_t_X550em; + } + break; + case ixgbe_media_type_backplane: + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII || + hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) + mac->ops.setup_link = ixgbe_setup_sgmii; + break; + default: + break; + } +} + +/** + * ixgbe_get_link_capabilities_X550em - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: true when autoneg or autotry is enabled + */ +s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + DEBUGFUNC("ixgbe_get_link_capabilities_X550em"); + + if (hw->phy.type == ixgbe_phy_fw) { + *autoneg = true; + *speed = hw->phy.speeds_supported; + return 0; + } + + /* SFP */ + if (hw->phy.media_type == ixgbe_media_type_fiber) { + + /* CS4227 SFP must not enable auto-negotiation */ + *autoneg = false; + + /* Check if 1G SFP module. */ + if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 + || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + return IXGBE_SUCCESS; + } + + /* Link capabilities are based on SFP */ + if (hw->phy.multispeed_fiber) + *speed = IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + else + *speed = IXGBE_LINK_SPEED_10GB_FULL; + } else { + *autoneg = true; + + switch (hw->phy.type) { + case ixgbe_phy_x550em_xfi: + *speed = IXGBE_LINK_SPEED_1GB_FULL | + IXGBE_LINK_SPEED_10GB_FULL; + *autoneg = false; + break; + case ixgbe_phy_ext_1g_t: + case ixgbe_phy_sgmii: + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + case ixgbe_phy_x550em_kr: + if (hw->mac.type == ixgbe_mac_X550EM_a) { + /* check different backplane modes */ + if (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { + *speed = IXGBE_LINK_SPEED_2_5GB_FULL; + break; + } else if (hw->device_id == + IXGBE_DEV_ID_X550EM_A_KR_L) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + } + } + fallthrough; + default: + *speed = IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + break; + } + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause + * @hw: pointer to hardware structure + * @lsc: pointer to boolean flag which indicates whether external Base T + * PHY interrupt is lsc + * + * Determime if external Base T PHY interrupt cause is high temperature + * failure alarm or link status change. + * + * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature + * failure alarm, else return PHY access status. + */ +STATIC s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) +{ + s32 status; + u16 reg; + + *lsc = false; + + /* Vendor alarm triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS || + !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN)) + return status; + + /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS || + !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN | + IXGBE_MDIO_GLOBAL_ALARM_1_INT))) + return status; + + /* Global alarm triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + /* If high temperature failure, then return over temp error and exit */ + if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) { + /* power down the PHY in case the PHY FW didn't already */ + ixgbe_set_copper_phy_power(hw, false); + return IXGBE_ERR_OVERTEMP; + } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) { + /* device fault alarm triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + /* if device fault was due to high temp alarm handle and exit */ + if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) { + /* power down the PHY in case the PHY FW didn't */ + ixgbe_set_copper_phy_power(hw, false); + return IXGBE_ERR_OVERTEMP; + } + } + + /* Vendor alarm 2 triggered */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); + + if (status != IXGBE_SUCCESS || + !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT)) + return status; + + /* link connect/disconnect event occurred */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); + + if (status != IXGBE_SUCCESS) + return status; + + /* Indicate LSC */ + if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC) + *lsc = true; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts + * @hw: pointer to hardware structure + * + * Enable link status change and temperature failure alarm for the external + * Base T PHY + * + * Returns PHY access status + */ +STATIC s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u16 reg; + bool lsc; + + /* Clear interrupt flags */ + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + + /* Enable link status change alarm */ + + /* Enable the LASI interrupts on X552 devices to receive notifications + * of the link configurations of the external PHY and correspondingly + * support the configuration of the internal iXFI link, since iXFI does + * not support auto-negotiation. This is not required for X553 devices + * having KR support, which performs auto-negotiations and which is used + * as the internal link to the external PHY. Hence adding a check here + * to avoid enabling LASI interrupts for X553 devices. + */ + if (hw->mac.type != ixgbe_mac_X550EM_a) { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®); + + if (status != IXGBE_SUCCESS) + return status; + + reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN; + + status = hw->phy.ops.write_reg(hw, + IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg); + + if (status != IXGBE_SUCCESS) + return status; + } + + /* Enable high temperature failure and global fault alarms */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN | + IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN); + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + reg); + + if (status != IXGBE_SUCCESS) + return status; + + /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN | + IXGBE_MDIO_GLOBAL_ALARM_1_INT); + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + reg); + + if (status != IXGBE_SUCCESS) + return status; + + /* Enable chip-wide vendor alarm */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN; + + status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + reg); + + return status; +} + +/** + * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed. + * @hw: pointer to hardware structure + * @speed: link speed + * + * Configures the integrated KR PHY. + **/ +STATIC s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, + ixgbe_link_speed speed) +{ + s32 status; + u32 reg_val; + + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status) + return status; + + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR | + IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX); + + /* Advertise 10G support. */ + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR; + + /* Advertise 1G support. */ + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX; + + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + if (hw->mac.type == ixgbe_mac_X550EM_a) { + /* Set lane mode to KR auto negotiation */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + + if (status) + return status; + + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN; + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + } + + return ixgbe_restart_an_internal_phy_x550em(hw); +} + +/** + * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs + * @hw: pointer to hardware structure + */ +static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw) +{ + u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + + if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) + return IXGBE_SUCCESS; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store); + if (rc) + return rc; + memset(store, 0, sizeof(store)); + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store); + if (rc) + return rc; + + return ixgbe_setup_fw_link(hw); +} + +/** + * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp + * @hw: pointer to hardware structure + */ +static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) +{ + u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; + s32 rc; + + rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); + if (rc) + return rc; + + if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { + ixgbe_shutdown_fw_phy(hw); + return IXGBE_ERR_OVERTEMP; + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register + * @hw: pointer to hardware structure + * + * Read NW_MNG_IF_SEL register and save field values, and check for valid field + * values. + **/ +STATIC s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw) +{ + /* Save NW management interface connected on board. This is used + * to determine internal PHY mode. + */ + hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL); + + /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set + * PHY address. This register field was has only been used for X552. + */ + if (hw->mac.type == ixgbe_mac_X550EM_a && + hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) { + hw->phy.addr = (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >> + IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_phy_ops_X550em - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + */ +s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) +{ + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_phy_ops_X550em"); + + hw->mac.ops.set_lan_id(hw); + ixgbe_read_mng_if_sel_x550em(hw); + + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) { + phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; + ixgbe_setup_mux_ctl(hw); + phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + phy->ops.read_reg_mdi = NULL; + phy->ops.write_reg_mdi = NULL; + hw->phy.ops.read_reg = NULL; + hw->phy.ops.write_reg = NULL; + phy->ops.check_overtemp = ixgbe_check_overtemp_fw; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; + + break; + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_SFP: + hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a; + hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; + break; + case IXGBE_DEV_ID_X550EM_X_SFP: + /* set up for CS4227 usage */ + hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; + break; + case IXGBE_DEV_ID_X550EM_X_1G_T: + phy->ops.read_reg_mdi = NULL; + phy->ops.write_reg_mdi = NULL; + default: + break; + } + + /* Identify the PHY or SFP module */ + ret_val = phy->ops.identify(hw); + if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED || + ret_val == IXGBE_ERR_PHY_ADDR_INVALID) + return ret_val; + + /* Setup function pointers based on detected hardware */ + ixgbe_init_mac_link_ops_X550em(hw); + if (phy->sfp_type != ixgbe_sfp_type_unknown) + phy->ops.reset = NULL; + + /* Set functions pointers based on phy type */ + switch (hw->phy.type) { + case ixgbe_phy_x550em_kx4: + phy->ops.setup_link = NULL; + phy->ops.read_reg = ixgbe_read_phy_reg_x550em; + phy->ops.write_reg = ixgbe_write_phy_reg_x550em; + break; + case ixgbe_phy_x550em_kr: + phy->ops.setup_link = ixgbe_setup_kr_x550em; + phy->ops.read_reg = ixgbe_read_phy_reg_x550em; + phy->ops.write_reg = ixgbe_write_phy_reg_x550em; + break; + case ixgbe_phy_ext_1g_t: + /* link is managed by FW */ + phy->ops.setup_link = NULL; + phy->ops.reset = NULL; + break; + case ixgbe_phy_x550em_xfi: + /* link is managed by HW */ + phy->ops.setup_link = NULL; + phy->ops.read_reg = ixgbe_read_phy_reg_x550em; + phy->ops.write_reg = ixgbe_write_phy_reg_x550em; + break; + case ixgbe_phy_x550em_ext_t: + /* If internal link mode is XFI, then setup iXFI internal link, + * else setup KR now. + */ + phy->ops.setup_internal_link = + ixgbe_setup_internal_phy_t_x550em; + + /* setup SW LPLU only for first revision of X550EM_x */ + if ((hw->mac.type == ixgbe_mac_X550EM_x) && + !(IXGBE_FUSES0_REV_MASK & + IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))) + phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em; + + phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em; + phy->ops.reset = ixgbe_reset_phy_t_X550em; + break; + case ixgbe_phy_sgmii: + phy->ops.setup_link = NULL; + break; + case ixgbe_phy_fw: + phy->ops.setup_link = ixgbe_setup_fw_link; + phy->ops.reset = ixgbe_reset_phy_fw; + break; + default: + break; + } + return ret_val; +} + +/** + * ixgbe_set_mdio_speed - Set MDIO clock speed + * @hw: pointer to hardware structure + */ +STATIC void ixgbe_set_mdio_speed(struct ixgbe_hw *hw) +{ + u32 hlreg0; + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + case IXGBE_DEV_ID_X550EM_A_10G_T: + case IXGBE_DEV_ID_X550EM_A_SFP: + case IXGBE_DEV_ID_X550EM_A_QSFP: + /* Config MDIO clock speed before the first MDIO PHY access */ + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + hlreg0 &= ~IXGBE_HLREG0_MDCSPD; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + break; + case IXGBE_DEV_ID_X550EM_A_1G_T: + case IXGBE_DEV_ID_X550EM_A_1G_T_L: + /* Select fast MDIO clock speed for these devices */ + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + hlreg0 |= IXGBE_HLREG0_MDCSPD; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + break; + default: + break; + } +} + +/** + * ixgbe_reset_hw_X550em - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, masks + * and clears all interrupts, perform a PHY reset, and perform a link (MAC) + * reset. + */ +s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) +{ + ixgbe_link_speed link_speed; + s32 status; + u32 ctrl = 0; + u32 i; + bool link_up = false; + u32 swfw_mask = hw->phy.phy_semaphore_mask; + + DEBUGFUNC("ixgbe_reset_hw_X550em"); + + /* Call adapter stop to disable Tx/Rx and clear interrupts */ + status = hw->mac.ops.stop_adapter(hw); + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Failed to stop adapter, STATUS = %d\n", status); + return status; + } + /* flush pending Tx transactions */ + ixgbe_clear_tx_pending(hw); + + ixgbe_set_mdio_speed(hw); + + /* PHY ops must be identified and initialized prior to reset */ + status = hw->phy.ops.init(hw); + + if (status) + hw_dbg(hw, "Failed to initialize PHY ops, STATUS = %d\n", + status); + + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED || + status == IXGBE_ERR_PHY_ADDR_INVALID) { + hw_dbg(hw, "Returning from reset HW due to PHY init failure\n"); + return status; + } + + /* start the external PHY */ + if (hw->phy.type == ixgbe_phy_x550em_ext_t) { + status = ixgbe_init_ext_t_x550em(hw); + if (status) { + hw_dbg(hw, "Failed to start the external PHY, STATUS = %d\n", + status); + return status; + } + } + + /* Setup SFP module if there is one present. */ + if (hw->phy.sfp_setup_needed) { + status = hw->mac.ops.setup_sfp(hw); + hw->phy.sfp_setup_needed = false; + } + + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + return status; + + /* Reset PHY */ + if (!hw->phy.reset_disable && hw->phy.ops.reset) { + if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP) + return IXGBE_ERR_OVERTEMP; + } + +mac_reset_top: + /* Issue global reset to the MAC. Needs to be SW reset if link is up. + * If link reset is used when link is up, it might reset the PHY when + * mng is using it. If link is down or the flag to force full link + * reset is set, then perform link reset. + */ + ctrl = IXGBE_CTRL_LNK_RST; + if (!hw->force_full_reset) { + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + if (link_up) + ctrl = IXGBE_CTRL_RST; + } + + status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (status != IXGBE_SUCCESS) { + ERROR_REPORT2(IXGBE_ERROR_CAUTION, + "semaphore failed with %d", status); + return IXGBE_ERR_SWFW_SYNC; + } + ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + + /* Poll for reset bit to self-clear meaning reset is complete */ + for (i = 0; i < 10; i++) { + usec_delay(1); + ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST_MASK)) + break; + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { + status = IXGBE_ERR_RESET_FAILED; + hw_dbg(hw, "Reset polling failed to complete.\n"); + } + + msec_delay(50); + + /* Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to + * allow time for any pending HW events to complete. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + goto mac_reset_top; + } + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. Also reset num_rar_entries to 128, + * since we modify this value when programming the SAN MAC address. + */ + hw->mac.num_rar_entries = 128; + hw->mac.ops.init_rx_addrs(hw); + + ixgbe_set_mdio_speed(hw); + + if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) + ixgbe_setup_mux_ctl(hw); + + if (status != IXGBE_SUCCESS) + hw_dbg(hw, "Reset HW failed, STATUS = %d\n", status); + + return status; +} + +/** + * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY. + * @hw: pointer to hardware structure + */ +s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u16 reg; + + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_TX_VENDOR_ALARMS_3, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + /* If PHY FW reset completed bit is set then this is the first + * SW instance after a power on so the PHY FW must be un-stalled. + */ + if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) { + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_GLOBAL_RES_PR_10, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + ®); + + if (status != IXGBE_SUCCESS) + return status; + + reg &= ~IXGBE_MDIO_POWER_UP_STALL; + + status = hw->phy.ops.write_reg(hw, + IXGBE_MDIO_GLOBAL_RES_PR_10, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + reg); + + if (status != IXGBE_SUCCESS) + return status; + } + + return status; +} + +/** + * ixgbe_setup_kr_x550em - Configure the KR PHY. + * @hw: pointer to hardware structure + **/ +s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw) +{ + /* leave link alone for 2.5G */ + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) + return IXGBE_SUCCESS; + + if (ixgbe_check_reset_blocked(hw)) + return 0; + + return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised); +} + +/** + * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: unused + * + * Configure the external PHY and the integrated KR PHY for SFP support. + **/ +s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 ret_val; + u16 reg_slice, reg_val; + bool setup_linear = false; + UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); + + /* Check if SFP module is supported and linear */ + ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); + + /* If no SFP module present, then return success. Return success since + * there is no reason to configure CS4227 and SFP not present error is + * not excepted in the setup MAC link flow. + */ + if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + return IXGBE_SUCCESS; + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* Configure internal PHY for KR/KX. */ + ixgbe_setup_kr_speed_x550em(hw, speed); + + /* Configure CS4227 LINE side to proper mode. */ + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + + (hw->bus.lan_id << 12); + if (setup_linear) + reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + else + reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice, + reg_val); + return ret_val; +} + +/** + * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode + * @hw: pointer to hardware structure + * @speed: the link speed to force + * + * Configures the integrated PHY for native SFI mode. Used to connect the + * internal PHY directly to an SFP cage, without autonegotiation. + **/ +STATIC s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 status; + u32 reg_val; + + /* Disable all AN and force speed to 10G Serial. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN; + reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK; + + /* Select forced link speed for internal PHY. */ + switch (*speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G; + break; + default: + /* Other link speeds are not supported by internal PHY. */ + return IXGBE_ERR_LINK_SETUP; + } + + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + /* Toggle port SW reset by AN reset. */ + status = ixgbe_restart_an_internal_phy_x550em(hw); + + return status; +} + +/** + * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: unused + * + * Configure the the integrated PHY for SFP support. + **/ +s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 ret_val; + u16 reg_phy_ext; + bool setup_linear = false; + u32 reg_slice, reg_phy_int, slice_offset; + + UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); + + /* Check if SFP module is supported and linear */ + ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); + + /* If no SFP module present, then return success. Return success since + * SFP not present error is not excepted in the setup MAC link flow. + */ + if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + return IXGBE_SUCCESS; + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) { + /* Configure internal PHY for native SFI based on module type */ + ret_val = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA; + if (!setup_linear) + reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR; + + ret_val = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* Setup SFI internal link. */ + ret_val = ixgbe_setup_sfi_x550a(hw, &speed); + } else { + /* Configure internal PHY for KR/KX. */ + ixgbe_setup_kr_speed_x550em(hw, speed); + + if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) { + /* Find Address */ + hw_dbg(hw, "Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n"); + return IXGBE_ERR_PHY_ADDR_INVALID; + } + + /* Get external PHY SKU id */ + ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, + IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* When configuring quad port CS4223, the MAC instance is part + * of the slice offset. + */ + if (reg_phy_ext == IXGBE_CS4223_SKU_ID) + slice_offset = (hw->bus.lan_id + + (hw->bus.instance_id << 1)) << 12; + else + slice_offset = hw->bus.lan_id << 12; + + /* Configure CS4227/CS4223 LINE side to proper mode. */ + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset; + + ret_val = hw->phy.ops.read_reg(hw, reg_slice, + IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) | + (IXGBE_CS4227_EDC_MODE_SR << 1)); + + if (setup_linear) + reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + else + reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + ret_val = hw->phy.ops.write_reg(hw, reg_slice, + IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext); + + /* Flush previous write with a read */ + ret_val = hw->phy.ops.read_reg(hw, reg_slice, + IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext); + } + return ret_val; +} + +/** + * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration + * @hw: pointer to hardware structure + * + * iXfI configuration needed for ixgbe_mac_X550EM_x devices. + **/ +STATIC s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 status; + u32 reg_val; + + /* Disable training protocol FSM. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Disable Flex from training TXFFE. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; + reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Enable override for coefficients. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN; + reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN; + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + return status; +} + +/** + * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. + * @hw: pointer to hardware structure + * @speed: the link speed to force + * + * Configures the integrated KR PHY to use iXFI mode. Used to connect an + * internal and external PHY at a specific speed, without autonegotiation. + **/ +STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) +{ + struct ixgbe_mac_info *mac = &hw->mac; + s32 status; + u32 reg_val; + + /* iXFI is only supported with X552 */ + if (mac->type != ixgbe_mac_X550EM_x) + return IXGBE_ERR_LINK_SETUP; + + /* Disable AN and force speed to 10G Serial. */ + status = mac->ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + + reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + + /* Select forced link speed for internal PHY. */ + switch (*speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G; + break; + default: + /* Other link speeds are not supported by internal KR PHY. */ + return IXGBE_ERR_LINK_SETUP; + } + + status = mac->ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Additional configuration needed for x550em_x */ + if (hw->mac.type == ixgbe_mac_X550EM_x) { + status = ixgbe_setup_ixfi_x550em_x(hw); + if (status != IXGBE_SUCCESS) + return status; + } + + /* Toggle port SW reset by AN reset. */ + status = ixgbe_restart_an_internal_phy_x550em(hw); + + return status; +} + +/** + * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status + * @hw: address of hardware structure + * @link_up: address of boolean to indicate link status + * + * Returns error code if unable to get link status. + */ +STATIC s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up) +{ + s32 ret; + u16 autoneg_status; + + *link_up = false; + + /* read this twice back to back to indicate current status */ + ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_status); + if (ret != IXGBE_SUCCESS) + return ret; + + ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_status); + if (ret != IXGBE_SUCCESS) + return ret; + + *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link + * @hw: point to hardware structure + * + * Configures the link between the integrated KR PHY and the external X557 PHY + * The driver will call this function when it gets a link status change + * interrupt from the X557 PHY. This function configures the link speed + * between the PHYs to match the link speed of the BASE-T link. + * + * A return of a non-zero value indicates an error, and the base driver should + * not report link up. + */ +s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) +{ + ixgbe_link_speed force_speed; + bool link_up; + s32 status; + u16 speed; + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) + return IXGBE_ERR_CONFIG; + + if (hw->mac.type == ixgbe_mac_X550EM_x && + !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { + /* If link is down, there is no setup necessary so return */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return status; + + if (!link_up) + return IXGBE_SUCCESS; + + status = hw->phy.ops.read_reg(hw, + IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &speed); + if (status != IXGBE_SUCCESS) + return status; + + /* If link is still down - no setup is required so return */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return status; + if (!link_up) + return IXGBE_SUCCESS; + + /* clear everything but the speed and duplex bits */ + speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK; + + switch (speed) { + case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL: + force_speed = IXGBE_LINK_SPEED_10GB_FULL; + break; + case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL: + force_speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + default: + /* Internal PHY does not support anything else */ + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + return ixgbe_setup_ixfi_x550em(hw, &force_speed); + } else { + speed = IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + return ixgbe_setup_kr_speed_x550em(hw, speed); + } +} + +/** + * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback. + * @hw: pointer to hardware structure + * + * Configures the integrated KR PHY to use internal loopback mode. + **/ +s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u32 reg_val; + + /* Disable AN and force speed to 10G Serial. */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Set near-end loopback clocks. */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B; + reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Set loopback enable. */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status != IXGBE_SUCCESS) + return status; + + /* Training bypass. */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status != IXGBE_SUCCESS) + return status; + reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS; + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + return status; +} + +/** + * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command + * assuming that the semaphore is already obtained. + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the hostif. + **/ +s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data) +{ + const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; + struct ixgbe_hic_read_shadow_ram buffer; + s32 status; + + DEBUGFUNC("ixgbe_read_ee_hostif_X550"); + buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + + /* convert offset from words to bytes */ + buffer.address = IXGBE_CPU_TO_BE32(offset * 2); + /* one word */ + buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16)); + buffer.pad2 = 0; + buffer.data = 0; + buffer.pad3 = 0; + + status = hw->mac.ops.acquire_swfw_sync(hw, mask); + if (status) + return status; + + status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer), + IXGBE_HI_COMMAND_TIMEOUT); + if (!status) { + *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, + FW_NVM_DATA_OFFSET); + } + + hw->mac.ops.release_swfw_sync(hw, mask); + return status; +} + +/** + * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @words: number of words + * @data: word(s) read from the EEPROM + * + * Reads a 16 bit word(s) from the EEPROM using the hostif. + **/ +s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) +{ + const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM; + struct ixgbe_hic_read_shadow_ram buffer; + u32 current_word = 0; + u16 words_to_read; + s32 status; + u32 i; + + DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550"); + + /* Take semaphore for the entire operation. */ + status = hw->mac.ops.acquire_swfw_sync(hw, mask); + if (status) { + hw_dbg(hw, "EEPROM read buffer - semaphore failed\n"); + return status; + } + + while (words) { + if (words > FW_MAX_READ_BUFFER_SIZE / 2) + words_to_read = FW_MAX_READ_BUFFER_SIZE / 2; + else + words_to_read = words; + + buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + + /* convert offset from words to bytes */ + buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2); + buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2); + buffer.pad2 = 0; + buffer.data = 0; + buffer.pad3 = 0; + + status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer), + IXGBE_HI_COMMAND_TIMEOUT); + + if (status) { + hw_dbg(hw, "Host interface command failed\n"); + goto out; + } + + for (i = 0; i < words_to_read; i++) { + u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) + + 2 * i; + u32 value = IXGBE_READ_REG(hw, reg); + + data[current_word] = (u16)(value & 0xffff); + current_word++; + i++; + if (i < words_to_read) { + value >>= 16; + data[current_word] = (u16)(value & 0xffff); + current_word++; + } + } + words -= words_to_read; + } + +out: + hw->mac.ops.release_swfw_sync(hw, mask); + return status; +} + +/** + * ixgbe_write_ee_hostif_data_X550 - Write EEPROM word using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the hostif. + **/ +s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + u16 data) +{ + s32 status; + struct ixgbe_hic_write_shadow_ram buffer; + + DEBUGFUNC("ixgbe_write_ee_hostif_data_X550"); + + buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN; + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + + /* one word */ + buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16)); + buffer.data = data; + buffer.address = IXGBE_CPU_TO_BE32(offset * 2); + + status = ixgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), + IXGBE_HI_COMMAND_TIMEOUT, true); + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "for offset %04x failed with status %d\n", + offset, status); + return status; + } + if (buffer.hdr.rsp.buf_lenh_status != FW_CEM_RESP_STATUS_SUCCESS) { + hw_dbg(hw, "for offset %04x host interface return status %02x\n", + offset, buffer.hdr.rsp.buf_lenh_status); + return IXGBE_ERR_HOST_INTERFACE_COMMAND; + } + + return status; +} + +/** + * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the hostif. + **/ +s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, + u16 data) +{ + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_write_ee_hostif_X550"); + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == + IXGBE_SUCCESS) { + status = ixgbe_write_ee_hostif_data_X550(hw, offset, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + hw_dbg(hw, "write ee hostif failed to get semaphore"); + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @words: number of words + * @data: word(s) write to the EEPROM + * + * Write a 16 bit word(s) to the EEPROM using the hostif. + **/ +s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) +{ + s32 status = IXGBE_SUCCESS; + u32 i = 0; + + DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550"); + + /* Take semaphore for the entire operation. */ + status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "EEPROM write buffer - semaphore failed\n"); + goto out; + } + + for (i = 0; i < words; i++) { + status = ixgbe_write_ee_hostif_data_X550(hw, offset + i, + data[i]); + + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Eeprom buffered write failed\n"); + break; + } + } + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); +out: + + return status; +} + +/** + * ixgbe_checksum_ptr_x550 - Checksum one pointer region + * @hw: pointer to hardware structure + * @ptr: pointer offset in eeprom + * @size: size of section pointed by ptr, if 0 first word will be used as size + * @csum: address of checksum to update + * @buffer: pointer to buffer containing calculated checksum + * @buffer_size: size of buffer + * + * Returns error status for any failure + */ +STATIC s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr, + u16 size, u16 *csum, u16 *buffer, + u32 buffer_size) +{ + u16 buf[256]; + s32 status; + u16 length, bufsz, i, start; + u16 *local_buffer; + + bufsz = sizeof(buf) / sizeof(buf[0]); + + /* Read a chunk at the pointer location */ + if (!buffer) { + status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf); + if (status) { + hw_dbg(hw, "Failed to read EEPROM image\n"); + return status; + } + local_buffer = buf; + } else { + if (buffer_size < ptr) + return IXGBE_ERR_PARAM; + local_buffer = &buffer[ptr]; + } + + if (size) { + start = 0; + length = size; + } else { + start = 1; + length = local_buffer[0]; + + /* Skip pointer section if length is invalid. */ + if (length == 0xFFFF || length == 0 || + (u32)length > hw->eeprom.word_size - (u32)ptr) + return IXGBE_SUCCESS; + } + + if (buffer && ((u32)start + (u32)length > buffer_size)) + return IXGBE_ERR_PARAM; + + for (i = start; length; i++, length--) { + if (i == bufsz && !buffer) { + ptr += bufsz; + i = 0; + if (length < bufsz) + bufsz = length; + + /* Read a chunk at the pointer location */ + status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, + bufsz, buf); + if (status) { + hw_dbg(hw, "Failed to read EEPROM image\n"); + return status; + } + } + *csum += local_buffer[i]; + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_calc_checksum_X550 - Calculates and returns the checksum + * @hw: pointer to hardware structure + * @buffer: pointer to buffer containing calculated checksum + * @buffer_size: size of buffer + * + * Returns a negative error code on error, or the 16-bit checksum + **/ +s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size) +{ + u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1]; + u16 *local_buffer; + s32 status; + u16 checksum = 0; + u16 pointer, i, size; + + DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550"); + + hw->eeprom.ops.init_params(hw); + + if (!buffer) { + /* Read pointer area */ + status = ixgbe_read_ee_hostif_buffer_X550(hw, 0, + IXGBE_EEPROM_LAST_WORD + 1, + eeprom_ptrs); + if (status) { + hw_dbg(hw, "Failed to read EEPROM image\n"); + return status; + } + local_buffer = eeprom_ptrs; + } else { + if (buffer_size < IXGBE_EEPROM_LAST_WORD) + return IXGBE_ERR_PARAM; + local_buffer = buffer; + } + + /* + * For X550 hardware include 0x0-0x41 in the checksum, skip the + * checksum word itself + */ + for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++) + if (i != IXGBE_EEPROM_CHECKSUM) + checksum += local_buffer[i]; + + /* + * Include all data from pointers 0x3, 0x6-0xE. This excludes the + * FW, PHY module, and PCIe Expansion/Option ROM pointers. + */ + for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) { + if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) + continue; + + pointer = local_buffer[i]; + + /* Skip pointer section if the pointer is invalid. */ + if (pointer == 0xFFFF || pointer == 0 || + pointer >= hw->eeprom.word_size) + continue; + + switch (i) { + case IXGBE_PCIE_GENERAL_PTR: + size = IXGBE_IXGBE_PCIE_GENERAL_SIZE; + break; + case IXGBE_PCIE_CONFIG0_PTR: + case IXGBE_PCIE_CONFIG1_PTR: + size = IXGBE_PCIE_CONFIG_SIZE; + break; + default: + size = 0; + break; + } + + status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum, + buffer, buffer_size); + if (status) + return status; + } + + checksum = (u16)IXGBE_EEPROM_SUM - checksum; + + return (s32)checksum; +} + +/** + * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum + * @hw: pointer to hardware structure + * + * Returns a negative error code on error, or the 16-bit checksum + **/ +s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw) +{ + return ixgbe_calc_checksum_X550(hw, NULL, 0); +} + +/** + * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If the + * caller does not need checksum_val, the value can be NULL. + **/ +s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val) +{ + s32 status; + u16 checksum; + u16 read_checksum = 0; + + DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + status = hw->eeprom.ops.calc_checksum(hw); + if (status < 0) + return status; + + checksum = (u16)(status & 0xffff); + + status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, + &read_checksum); + if (status) + return status; + + /* Verify read checksum from EEPROM is the same as + * calculated checksum + */ + if (read_checksum != checksum) { + status = IXGBE_ERR_EEPROM_CHECKSUM; + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "Invalid EEPROM checksum"); + } + + /* If the user cares, return the calculated checksum */ + if (checksum_val) + *checksum_val = checksum; + + return status; +} + +/** + * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash + * @hw: pointer to hardware structure + * + * After writing EEPROM to shadow RAM using EEWR register, software calculates + * checksum and updates the EEPROM and instructs the hardware to update + * the flash. + **/ +s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw) +{ + s32 status; + u16 checksum = 0; + + DEBUGFUNC("ixgbe_update_eeprom_checksum_X550"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum); + if (status) { + hw_dbg(hw, "EEPROM read failed\n"); + return status; + } + + status = ixgbe_calc_eeprom_checksum_X550(hw); + if (status < 0) + return status; + + checksum = (u16)(status & 0xffff); + + status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, + checksum); + if (status) + return status; + + status = ixgbe_update_flash_X550(hw); + + return status; +} + +/** + * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device + * @hw: pointer to hardware structure + * + * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash. + **/ +s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + union ixgbe_hic_hdr2 buffer; + + DEBUGFUNC("ixgbe_update_flash_X550"); + + buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD; + buffer.req.buf_lenh = 0; + buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN; + buffer.req.checksum = FW_DEFAULT_CHECKSUM; + + status = ixgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), + IXGBE_HI_COMMAND_TIMEOUT, false); + + return status; +} + +/** + * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) +{ + u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u16 ext_ability = 0; + + DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em"); + + hw->phy.ops.identify(hw); + + switch (hw->phy.type) { + case ixgbe_phy_x550em_kr: + if (hw->mac.type == ixgbe_mac_X550EM_a) { + if (hw->phy.nw_mng_if_sel & + IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) { + physical_layer = + IXGBE_PHYSICAL_LAYER_2500BASE_KX; + break; + } else if (hw->device_id == + IXGBE_DEV_ID_X550EM_A_KR_L) { + physical_layer = + IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + } + } + fallthrough; + case ixgbe_phy_x550em_xfi: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR | + IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + case ixgbe_phy_x550em_kx4: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | + IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + case ixgbe_phy_x550em_ext_t: + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + break; + case ixgbe_phy_fw: + if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL) + physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T; + break; + case ixgbe_phy_sgmii: + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + case ixgbe_phy_ext_1g_t: + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + break; + default: + break; + } + + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) + physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw); + + return physical_layer; +} + +/** + * ixgbe_get_bus_info_X550em - Set PCI bus info + * @hw: pointer to hardware structure + * + * Sets bus link width and speed to unknown because X550em is + * not a PCI device. + **/ +s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw) +{ + + DEBUGFUNC("ixgbe_get_bus_info_x550em"); + + hw->bus.width = ixgbe_bus_width_unknown; + hw->bus.speed = ixgbe_bus_speed_unknown; + + hw->mac.ops.set_lan_id(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_disable_rx_x550 - Disable RX unit + * @hw: pointer to hardware structure + * + * Enables the Rx DMA unit for x550 + **/ +void ixgbe_disable_rx_x550(struct ixgbe_hw *hw) +{ + u32 rxctrl, pfdtxgswc; + s32 status; + struct ixgbe_hic_disable_rxen fw_cmd; + + DEBUGFUNC("ixgbe_enable_rx_dma_x550"); + + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) { + pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben = true; + } else { + hw->mac.set_lben = false; + } + + fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD; + fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN; + fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM; + fw_cmd.port_number = (u8)hw->bus.lan_id; + + status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, + sizeof(struct ixgbe_hic_disable_rxen), + IXGBE_HI_COMMAND_TIMEOUT, true); + + /* If we fail - disable RX using register write */ + if (status) { + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + rxctrl &= ~IXGBE_RXCTRL_RXEN; + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); + } + } + } +} + +/** + * ixgbe_enter_lplu_t_x550em - Transition to low power states + * @hw: pointer to hardware structure + * + * Configures Low Power Link Up on transition to low power states + * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the + * X557 PHY immediately prior to entering LPLU. + **/ +s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) +{ + u16 an_10g_cntl_reg, autoneg_reg, speed; + s32 status; + ixgbe_link_speed lcd_speed; + u32 save_autoneg; + bool link_up; + + /* SW LPLU not required on later HW revisions. */ + if ((hw->mac.type == ixgbe_mac_X550EM_x) && + (IXGBE_FUSES0_REV_MASK & + IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)))) + return IXGBE_SUCCESS; + + /* If blocked by MNG FW, then don't restart AN */ + if (ixgbe_check_reset_blocked(hw)) + return IXGBE_SUCCESS; + + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return status; + + status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3); + + if (status != IXGBE_SUCCESS) + return status; + + /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability + * disabled, then force link down by entering low power mode. + */ + if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) || + !(hw->wol_enabled || ixgbe_mng_present(hw))) + return ixgbe_set_copper_phy_power(hw, FALSE); + + /* Determine LCD */ + status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed); + + if (status != IXGBE_SUCCESS) + return status; + + /* If no valid LCD link speed, then force link down and exit. */ + if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN) + return ixgbe_set_copper_phy_power(hw, FALSE); + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &speed); + + if (status != IXGBE_SUCCESS) + return status; + + /* If no link now, speed is invalid so take link down */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return ixgbe_set_copper_phy_power(hw, false); + + /* clear everything but the speed bits */ + speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK; + + /* If current speed is already LCD, then exit. */ + if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) && + (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) || + ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) && + (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL))) + return status; + + /* Clear AN completed indication */ + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + if (status != IXGBE_SUCCESS) + return status; + + status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &an_10g_cntl_reg); + + if (status != IXGBE_SUCCESS) + return status; + + status = hw->phy.ops.read_reg(hw, + IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); + + if (status != IXGBE_SUCCESS) + return status; + + save_autoneg = hw->phy.autoneg_advertised; + + /* Setup link at least common link speed */ + status = hw->mac.ops.setup_link(hw, lcd_speed, false); + + /* restore autoneg from before setting lplu speed */ + hw->phy.autoneg_advertised = save_autoneg; + + return status; +} + +/** + * ixgbe_get_lcd_t_x550em - Determine lowest common denominator + * @hw: pointer to hardware structure + * @lcd_speed: pointer to lowest common link speed + * + * Determine lowest common link speed with link partner. + **/ +s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed) +{ + u16 an_lp_status; + s32 status; + u16 word = hw->eeprom.ctrl_word_3; + + *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN; + + status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &an_lp_status); + + if (status != IXGBE_SUCCESS) + return status; + + /* If link partner advertised 1G, return 1G */ + if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) { + *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL; + return status; + } + + /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */ + if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) || + (word & NVM_INIT_CTRL_3_D10GMP_PORT0)) + return status; + + /* Link partner not capable of lower speeds, return 10G */ + *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL; + return status; +} + +/** + * ixgbe_setup_fc_X550em - Set up flow control + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + **/ +s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + u32 pause, asm_dir, reg_val; + + DEBUGFUNC("ixgbe_setup_fc_X550em"); + + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* 10gig parts do not have a word in the EEPROM to determine the + * default flow control setting, so we explicitly set it to full. + */ + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + /* Determine PAUSE and ASM_DIR bits. */ + switch (hw->fc.requested_mode) { + case ixgbe_fc_none: + pause = 0; + asm_dir = 0; + break; + case ixgbe_fc_tx_pause: + pause = 0; + asm_dir = 1; + break; + case ixgbe_fc_rx_pause: + /* Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE, as such we fall + * through to the fc_full statement. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + case ixgbe_fc_full: + pause = 1; + asm_dir = 1; + break; + default: + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, + "Flow control param set incorrectly\n"); + ret_val = IXGBE_ERR_CONFIG; + goto out; + } + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + ret_val = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (ret_val != IXGBE_SUCCESS) + goto out; + reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); + if (pause) + reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; + if (asm_dir) + reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; + ret_val = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + /* This device does not fully support AN. */ + hw->fc.disable_fc_autoneg = true; + break; + case IXGBE_DEV_ID_X550EM_X_XFI: + hw->fc.disable_fc_autoneg = true; + break; + default: + break; + } + +out: + return ret_val; +} + +/** + * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) +{ + u32 link_s1, lp_an_page_low, an_cntl_1; + s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; + ixgbe_link_speed speed; + bool link_up; + + /* AN should have completed when the cable was plugged in. + * Look for reasons to bail out. Bail out if: + * - FC autoneg is disabled, or if + * - link is not up. + */ + if (hw->fc.disable_fc_autoneg) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "Flow control autoneg is disabled"); + goto out; + } + + hw->mac.ops.check_link(hw, &speed, &link_up, false); + if (!link_up) { + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); + goto out; + } + + /* Check at auto-negotiation has completed */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LINK_S1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1); + + if (status != IXGBE_SUCCESS || + (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); + status = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + /* Read the 10g AN autoc and LP ability registers and resolve + * local flow control settings accordingly + */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1); + + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); + goto out; + } + + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low); + + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); + goto out; + } + + status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low, + IXGBE_KRM_AN_CNTL_1_SYM_PAUSE, + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE, + IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE, + IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE); + +out: + if (status == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = true; + } else { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + } +} + +/** + * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings + * @hw: pointer to hardware structure + * + **/ +void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw) +{ + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; +} + +/** + * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; + u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; + ixgbe_link_speed speed; + bool link_up; + + /* AN should have completed when the cable was plugged in. + * Look for reasons to bail out. Bail out if: + * - FC autoneg is disabled, or if + * - link is not up. + */ + if (hw->fc.disable_fc_autoneg) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "Flow control autoneg is disabled"); + goto out; + } + + hw->mac.ops.check_link(hw, &speed, &link_up, false); + if (!link_up) { + ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); + goto out; + } + + /* Check if auto-negotiation has completed */ + status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); + if (status != IXGBE_SUCCESS || + !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); + status = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + + /* Negotiate the flow control */ + status = ixgbe_negotiate_fc(hw, info[0], info[0], + FW_PHY_ACT_GET_LINK_INFO_FC_RX, + FW_PHY_ACT_GET_LINK_INFO_FC_TX, + FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX, + FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX); + +out: + if (status == IXGBE_SUCCESS) { + hw->fc.fc_was_autonegged = true; + } else { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + } +} + +/** + * ixgbe_setup_fc_backplane_x550em_a - Set up flow control + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + **/ +s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw) +{ + s32 status = IXGBE_SUCCESS; + u32 an_cntl = 0; + + DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a"); + + /* Validate the requested mode */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED, + "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + /* Set up the 1G and 10G flow control advertisement registers so the + * HW will be able to do FC autoneg once the cable is plugged in. If + * we link at 10G, the 1G advertisement is harmless and vice versa. + */ + status = hw->mac.ops.read_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl); + + if (status != IXGBE_SUCCESS) { + hw_dbg(hw, "Auto-Negotiation did not complete\n"); + return status; + } + + /* The possible values of fc.requested_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.requested_mode) { + case ixgbe_fc_none: + /* Flow control completely disabled by software override. */ + an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE); + break; + case ixgbe_fc_tx_pause: + /* Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; + an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE; + break; + case ixgbe_fc_rx_pause: + /* Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE, as such we fall + * through to the fc_full statement. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE | + IXGBE_KRM_AN_CNTL_1_ASM_PAUSE; + break; + default: + ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, + "Flow control param set incorrectly\n"); + return IXGBE_ERR_CONFIG; + } + + status = hw->mac.ops.write_iosf_sb_reg(hw, + IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl); + + /* Restart auto-negotiation. */ + status = ixgbe_restart_an_internal_phy_x550em(hw); + + return status; +} + +/** + * ixgbe_set_mux - Set mux for port 1 access with CS4227 + * @hw: pointer to hardware structure + * @state: set mux if 1, clear if 0 + */ +STATIC void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state) +{ + u32 esdp; + + if (!hw->bus.lan_id) + return; + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (state) + esdp |= IXGBE_ESDP_SDP1; + else + esdp &= ~IXGBE_ESDP_SDP1; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore and sets the I2C MUX + **/ +s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask) +{ + s32 status; + + DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em"); + + status = ixgbe_acquire_swfw_sync_X540(hw, mask); + if (status) + return status; + + if (mask & IXGBE_GSSR_I2C_MASK) + ixgbe_set_mux(hw, 1); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore and sets the I2C MUX + **/ +void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask) +{ + DEBUGFUNC("ixgbe_release_swfw_sync_X550em"); + + if (mask & IXGBE_GSSR_I2C_MASK) + ixgbe_set_mux(hw, 0); + + ixgbe_release_swfw_sync_X540(hw, mask); +} + +/** + * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore and get the shared phy token as needed + */ +STATIC s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask) +{ + u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM; + int retries = FW_PHY_TOKEN_RETRIES; + s32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a"); + + status = IXGBE_SUCCESS; + if (hmask) + status = ixgbe_acquire_swfw_sync_X540(hw, hmask); + + if (status) { + hw_dbg(hw, "Could not acquire SWFW semaphore, Status = %d\n", status); + return status; + } + + if (!(mask & IXGBE_GSSR_TOKEN_SM)) + return IXGBE_SUCCESS; + + while (--retries) { + status = ixgbe_get_phy_token(hw); + + if (status == IXGBE_SUCCESS) + return IXGBE_SUCCESS; + + if (status != IXGBE_ERR_TOKEN_RETRY) { + hw_dbg(hw, "Retry acquiring the PHY token failed, Status = %d\n", status); + if (hmask) + ixgbe_release_swfw_sync_X540(hw, hmask); + return status; + } + + if (status == IXGBE_ERR_TOKEN_RETRY) + hw_dbg(hw, "Could not acquire PHY token, Status = %d\n", + status); + } + + if (hmask) + ixgbe_release_swfw_sync_X540(hw, hmask); + + hw_dbg(hw, "Semaphore acquisition retries failed!: PHY ID = 0x%08X\n", + hw->phy.id); + return status; +} + +/** + * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore and puts the shared phy token as needed + */ +STATIC void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask) +{ + u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM; + + DEBUGFUNC("ixgbe_release_swfw_sync_X550a"); + + if (mask & IXGBE_GSSR_TOKEN_SM) + ixgbe_put_phy_token(hw); + + if (hmask) + ixgbe_release_swfw_sync_X540(hw, hmask); +} + +/** + * ixgbe_read_phy_reg_x550a - Reads specified PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @device_type: 5 bit device type + * @phy_data: Pointer to read data from PHY register + * + * Reads a value from a specified PHY register using the SWFW lock and PHY + * Token. The PHY Token is needed since the MDIO is shared between to MAC + * instances. + **/ +s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) +{ + s32 status; + u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM; + + DEBUGFUNC("ixgbe_read_phy_reg_x550a"); + + if (hw->mac.ops.acquire_swfw_sync(hw, mask)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); + + hw->mac.ops.release_swfw_sync(hw, mask); + + return status; +} + +/** + * ixgbe_write_phy_reg_x550a - Writes specified PHY register + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 5 bit device type + * @phy_data: Data to write to the PHY register + * + * Writes a value to specified PHY register using the SWFW lock and PHY Token. + * The PHY Token is needed since the MDIO is shared between to MAC instances. + **/ +s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + s32 status; + u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM; + + DEBUGFUNC("ixgbe_write_phy_reg_x550a"); + + if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) { + status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type, + phy_data); + hw->mac.ops.release_swfw_sync(hw, mask); + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt + * @hw: pointer to hardware structure + * + * Handle external Base T PHY interrupt. If high temperature + * failure alarm then return error, else if link status change + * then setup internal/external PHY link + * + * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature + * failure alarm, else return PHY access status. + */ +s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw) +{ + bool lsc; + s32 status; + + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + + if (status != IXGBE_SUCCESS) + return status; + + if (lsc) + return ixgbe_setup_internal_phy(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * Setup internal/external PHY link speed based on link speed, then set + * external PHY auto advertised link speed. + * + * Returns error status for any failure + **/ +s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 status; + ixgbe_link_speed force_speed; + + DEBUGFUNC("ixgbe_setup_mac_link_t_X550em"); + + /* Setup internal/external PHY link speed to iXFI (10G), unless + * only 1G is auto advertised then setup KX link. + */ + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + force_speed = IXGBE_LINK_SPEED_10GB_FULL; + else + force_speed = IXGBE_LINK_SPEED_1GB_FULL; + + /* If X552 and internal link mode is XFI, then setup XFI internal link. + */ + if (hw->mac.type == ixgbe_mac_X550EM_x && + !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) { + status = ixgbe_setup_ixfi_x550em(hw, &force_speed); + + if (status != IXGBE_SUCCESS) + return status; + } + + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); +} + +/** + * ixgbe_check_link_t_X550em - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Check that both the MAC and X557 external PHY have link. + **/ +s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + s32 status; + u16 i, autoneg_status = 0; + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) + return IXGBE_ERR_CONFIG; + + status = ixgbe_check_mac_link_generic(hw, speed, link_up, + link_up_wait_to_complete); + + /* If check link fails or MAC link is not up, then return */ + if (status != IXGBE_SUCCESS || !(*link_up)) + return status; + + /* MAC link is up, so check external PHY link. + * X557 PHY. Link status is latching low, and can only be used to detect + * link drop, and not the current status of the link without performing + * back-to-back reads. + */ + for (i = 0; i < 2; i++) { + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_status); + + if (status != IXGBE_SUCCESS) + return status; + } + + /* If external PHY link is not up, then indicate link not up */ + if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) + *link_up = false; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI + * @hw: pointer to hardware structure + **/ +s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw) +{ + s32 status; + + status = ixgbe_reset_phy_generic(hw); + + if (status != IXGBE_SUCCESS) + return status; + + /* Configure Link Status Alarm and Temperature Threshold interrupts */ + return ixgbe_enable_lasi_ext_t_x550em(hw); +} + +/** + * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs. + * @hw: pointer to hardware structure + * @led_idx: led number to turn on + **/ +s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx) +{ + u16 phy_data; + + DEBUGFUNC("ixgbe_led_on_t_X550em"); + + if (led_idx >= IXGBE_X557_MAX_LED_INDEX) + return IXGBE_ERR_PARAM; + + /* To turn on the LED, set mode to ON. */ + ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data); + phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK; + ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); + + /* Some designs have the LEDs wired to the MAC */ + return ixgbe_led_on_generic(hw, led_idx); +} + +/** + * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs. + * @hw: pointer to hardware structure + * @led_idx: led number to turn off + **/ +s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx) +{ + u16 phy_data; + + DEBUGFUNC("ixgbe_led_off_t_X550em"); + + if (led_idx >= IXGBE_X557_MAX_LED_INDEX) + return IXGBE_ERR_PARAM; + + /* To turn on the LED, set mode to ON. */ + ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data); + phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK; + ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data); + + /* Some designs have the LEDs wired to the MAC */ + return ixgbe_led_off_generic(hw, led_idx); +} + +/** + * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware + * @hw: pointer to the HW structure + * @maj: driver version major number + * @min: driver version minor number + * @build: driver version build number + * @sub: driver version sub build number + * @len: length of driver_ver string + * @driver_ver: driver string + * + * Sends driver version number to firmware through the manageability + * block. On success return IXGBE_SUCCESS + * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 sub, u16 len, const char *driver_ver) +{ + struct ixgbe_hic_drv_info2 fw_cmd; + s32 ret_val = IXGBE_SUCCESS; + int i; + + DEBUGFUNC("ixgbe_set_fw_drv_ver_x550"); + + if ((len == 0) || (driver_ver == NULL) || + (len > sizeof(fw_cmd.driver_string))) + return IXGBE_ERR_INVALID_ARGUMENT; + + fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; + fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len; + fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; + fw_cmd.port_num = (u8)hw->bus.func; + fw_cmd.ver_maj = maj; + fw_cmd.ver_min = min; + fw_cmd.ver_build = build; + fw_cmd.ver_sub = sub; + fw_cmd.hdr.checksum = 0; + memcpy(fw_cmd.driver_string, driver_ver, len); + fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd, + (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); + + for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { + ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, + sizeof(fw_cmd), + IXGBE_HI_COMMAND_TIMEOUT, + true); + if (ret_val != IXGBE_SUCCESS) + continue; + + if (fw_cmd.hdr.cmd_or_resp.ret_status == + FW_CEM_RESP_STATUS_SUCCESS) + ret_val = IXGBE_SUCCESS; + else + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + + break; + } + + return ret_val; +} + +/** + * ixgbe_fw_recovery_mode_X550 - Check FW NVM recovery mode + * @hw: pointer t hardware structure + * + * Returns true if in FW NVM recovery mode. + **/ +bool ixgbe_fw_recovery_mode_X550(struct ixgbe_hw *hw) +{ + u32 fwsm; + + fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)); + + return !!(fwsm & IXGBE_FWSM_FW_NVM_RECOVERY_MODE); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.h new file mode 100644 index 0000000000..d1c7e15f51 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_x550.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _IXGBE_X550_H_ +#define _IXGBE_X550_H_ + +#include "ixgbe_type.h" + +s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw); +s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw); +s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw); + +s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw); +s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw); +s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw); +s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw); +s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size); +s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val); +s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw); +s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data); +s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, + u16 data); +s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data); +s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, +u16 *data); +s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + u16 data); +void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable, + unsigned int pool); +void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, + bool enable, int vf); +s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 data); +s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *data); +s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 ver, u16 len, const char *str); +s32 ixgbe_get_phy_token(struct ixgbe_hw *); +s32 ixgbe_put_phy_token(struct ixgbe_hw *); +void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw); +void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw); +void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap); +void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf); +enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw); +s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *autoneg); +void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw); +s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw); +s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw); +s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw); +u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw); +void ixgbe_disable_rx_x550(struct ixgbe_hw *hw); +s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed); +s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw); +s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask); +s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); +s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); +s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw); +void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw); +s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete); +s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); +s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw); +s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw); +s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx); +s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx); +bool ixgbe_fw_recovery_mode_X550(struct ixgbe_hw *hw); +#endif /* _IXGBE_X550_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_xsk.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_xsk.c new file mode 100644 index 0000000000..ae6f85e8e0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/ixgbe_xsk.c @@ -0,0 +1,1097 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" + +#ifdef HAVE_XDP_SUPPORT +#include +#endif +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +#include +#else +#include +#endif +#endif +#ifdef HAVE_XDP_BUFF_RXQ +#include +#endif + +#include "ixgbe_txrx_common.h" + +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#ifndef HAVE_NETDEV_BPF_XSK_POOL +struct xdp_umem *ixgbe_xsk_umem(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +#else +struct xsk_buff_pool *ixgbe_xsk_umem(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ +{ + bool xdp_on = READ_ONCE(adapter->xdp_prog); + int qid = ring->ring_idx; + +#ifndef HAVE_NETDEV_BPF_XSK_POOL + if (!adapter->xsk_pools || !adapter->xsk_pools[qid] || + qid >= adapter->num_xsk_pools || !xdp_on || + !test_bit(qid, adapter->af_xdp_zc_qps)) + return NULL; + + return adapter->xsk_pools[qid]; +#else + if (!xdp_on || !test_bit(qid, adapter->af_xdp_zc_qps)) + return NULL; + + return xsk_get_pool_from_qid(adapter->netdev, qid); +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ +} + +#ifndef HAVE_NETDEV_BPF_XSK_POOL +static int ixgbe_alloc_xsk_umems(struct ixgbe_adapter *adapter) +{ + if (adapter->xsk_pools) + return 0; + + adapter->num_xsk_pools_used = 0; + adapter->num_xsk_pools = adapter->num_rx_queues; + adapter->xsk_pools = kcalloc(adapter->num_xsk_pools, + sizeof(*adapter->xsk_pools), + GFP_KERNEL); + if (!adapter->xsk_pools) { + adapter->num_xsk_pools = 0; + return -ENOMEM; + } + + return 0; +} +static int ixgbe_add_xsk_umem(struct ixgbe_adapter *adapter, + struct xdp_umem *pool, + u16 qid) +{ + int err; + + err = ixgbe_alloc_xsk_umems(adapter); + if (err) + return err; + + adapter->xsk_pools[qid] = pool; + adapter->num_xsk_pools_used++; + + return 0; +} + +static void ixgbe_remove_xsk_umem(struct ixgbe_adapter *adapter, u16 qid) +{ + adapter->xsk_pools[qid] = NULL; + adapter->num_xsk_pools_used--; + + if (adapter->num_xsk_pools == 0) { + kfree(adapter->xsk_pools); + adapter->xsk_pools = NULL; + adapter->num_xsk_pools = 0; + } +} +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + +/** + * ixgbe_xsk_any_rx_ring_enabled - Checks if Rx rings have AF_XDP UMEM attached + * @adapter: adapter + * + * Returns true if any of the Rx rings has an AF_XDP UMEM attached + */ +bool ixgbe_xsk_any_rx_ring_enabled(struct ixgbe_adapter *adapter) +{ + int i; + +#ifndef HAVE_NETDEV_BPF_XSK_POOL + if (!adapter->xsk_pools) + return false; + + for (i = 0; i < adapter->num_xsk_pools; i++) { + if (adapter->xsk_pools[i]) +#else + for (i = 0; i < adapter->num_rx_queues; i++) { + if (xsk_get_pool_from_qid(adapter->netdev, i)) +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + return true; + } + + return false; +} + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +static int ixgbe_xsk_umem_dma_map(struct ixgbe_adapter *adapter, + struct xdp_umem *pool) +{ + struct device *dev = &adapter->pdev->dev; + unsigned int i, j; + dma_addr_t dma; + + for (i = 0; i < pool->npgs; i++) { + dma = dma_map_page_attrs(dev, pool->pgs[i], 0, PAGE_SIZE, + DMA_BIDIRECTIONAL, IXGBE_RX_DMA_ATTR); + if (dma_mapping_error(dev, dma)) + goto out_unmap; + + pool->pages[i].dma = dma; + } + + return 0; + +out_unmap: + for (j = 0; j < i; j++) { + dma_unmap_page_attrs(dev, pool->pages[i].dma, PAGE_SIZE, + DMA_BIDIRECTIONAL, IXGBE_RX_DMA_ATTR); + pool->pages[i].dma = 0; + } + + return -1; +} + +static void ixgbe_xsk_umem_dma_unmap(struct ixgbe_adapter *adapter, + struct xdp_umem *pool) +{ + struct device *dev = &adapter->pdev->dev; + unsigned int i; + + for (i = 0; i < pool->npgs; i++) { + dma_unmap_page_attrs(dev, pool->pages[i].dma, PAGE_SIZE, + DMA_BIDIRECTIONAL, IXGBE_RX_DMA_ATTR); + + pool->pages[i].dma = 0; + } +} +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + +#ifndef HAVE_NETDEV_BPF_XSK_POOL +static int ixgbe_xsk_umem_enable(struct ixgbe_adapter *adapter, + struct xdp_umem *pool, + u16 qid) +#else +static int ixgbe_xsk_umem_enable(struct ixgbe_adapter *adapter, + struct xsk_buff_pool *pool, + u16 qid) +#endif +{ +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct xdp_umem_fq_reuse *reuseq; +#endif + bool if_running; + int err; + + if (qid >= adapter->num_rx_queues) + return -EINVAL; + +#ifndef HAVE_NETDEV_BPF_XSK_POOL + if (adapter->xsk_pools) { + if (qid >= adapter->num_xsk_pools) + return -EINVAL; + if (adapter->xsk_pools[qid]) + return -EBUSY; + } +#else + if (qid >= adapter->netdev->real_num_rx_queues || + qid >= adapter->netdev->real_num_tx_queues) + return -EINVAL; +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + reuseq = xsk_reuseq_prepare(adapter->rx_ring[0]->count); + if (!reuseq) + return -ENOMEM; + + xsk_reuseq_free(xsk_reuseq_swap(pool, reuseq)); + + err = ixgbe_xsk_umem_dma_map(adapter, pool); +#else + err = xsk_pool_dma_map(pool, &adapter->pdev->dev, IXGBE_RX_DMA_ATTR); +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + if (err) + return err; + + if_running = netif_running(adapter->netdev) && + READ_ONCE(adapter->xdp_prog); + + if (if_running) + ixgbe_txrx_ring_disable(adapter, qid); + + set_bit(qid, adapter->af_xdp_zc_qps); +#ifndef HAVE_NETDEV_BPF_XSK_POOL + err = ixgbe_add_xsk_umem(adapter, pool, qid); + if (err) + return err; +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + + if (if_running) { + ixgbe_txrx_ring_enable(adapter, qid); + + /* Kick start the NAPI context so that receiving will start */ +#ifdef HAVE_NDO_XSK_WAKEUP + err = ixgbe_xsk_wakeup(adapter->netdev, qid, XDP_WAKEUP_RX); +#else + err = ixgbe_xsk_async_xmit(adapter->netdev, qid); +#endif + if (err) { + clear_bit(qid, adapter->af_xdp_zc_qps); +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + ixgbe_xsk_umem_dma_unmap(adapter, adapter->xsk_pools[qid]); +#else + xsk_pool_dma_unmap(pool, IXGBE_RX_DMA_ATTR); +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + return err; + } + } + + return 0; +} + +static int ixgbe_xsk_umem_disable(struct ixgbe_adapter *adapter, u16 qid) +{ + bool if_running; + +#ifndef HAVE_NETDEV_BPF_XSK_POOL + if (!adapter->xsk_pools || qid >= adapter->num_xsk_pools || + !adapter->xsk_pools[qid]) +#else + if (!xsk_get_pool_from_qid(adapter->netdev, qid)) + return -EINVAL; +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + + if_running = netif_running(adapter->netdev) && + READ_ONCE(adapter->xdp_prog); + + if (if_running) + ixgbe_txrx_ring_disable(adapter, qid); + + clear_bit(qid, adapter->af_xdp_zc_qps); + +#ifdef HAVE_NETDEV_BPF_XSK_POOL + xsk_pool_dma_unmap(xsk_get_pool_from_qid(adapter->netdev, qid), + IXGBE_RX_DMA_ATTR); +#else +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + ixgbe_xsk_umem_dma_unmap(adapter, adapter->xsk_pools[qid]); +#else + xsk_pool_dma_unmap(adapter->xsk_pools[qid], IXGBE_RX_DMA_ATTR); +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + ixgbe_remove_xsk_umem(adapter, qid); +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + + if (if_running) + ixgbe_txrx_ring_enable(adapter, qid); + + return 0; +} + +#ifndef HAVE_NETDEV_BPF_XSK_POOL +int ixgbe_xsk_umem_setup(struct ixgbe_adapter *adapter, struct xdp_umem *pool, + u16 qid) +#else +int ixgbe_xsk_umem_setup(struct ixgbe_adapter *adapter, struct xsk_buff_pool *pool, + u16 qid) +#endif +{ + return pool ? ixgbe_xsk_umem_enable(adapter, pool, qid) : + ixgbe_xsk_umem_disable(adapter, qid); +} + +static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + struct xdp_buff *xdp) +{ + int err, result = IXGBE_XDP_PASS; + struct bpf_prog *xdp_prog; + struct ixgbe_ring *ring; + struct xdp_frame *xdpf; + u32 act; + + rcu_read_lock(); + xdp_prog = READ_ONCE(rx_ring->xdp_prog); + act = bpf_prog_run_xdp(xdp_prog, xdp); +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + xdp->handle += xdp->data - xdp->data_hard_start; +#endif + switch (act) { + case XDP_PASS: + break; + case XDP_TX: + xdpf = xdp_convert_buff_to_frame(xdp); + if (unlikely(!xdpf)) { + result = IXGBE_XDP_CONSUMED; + break; + } + ring = ixgbe_determine_xdp_ring(adapter); + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_lock(&ring->tx_lock); +#ifdef HAVE_XDP_FRAME_STRUCT + result = ixgbe_xmit_xdp_ring(ring, xdpf); +#else + result = ixgbe_xmit_xdp_ring(ring, xdp); +#endif /* HAVE_XDP_FRAME_STRUCT */ + if (static_branch_unlikely(&ixgbe_xdp_locking_key)) + spin_unlock(&ring->tx_lock); + break; + case XDP_REDIRECT: + err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); + result = !err ? IXGBE_XDP_REDIR : IXGBE_XDP_CONSUMED; + break; + default: + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); + fallthrough; + case XDP_ABORTED: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + /* fallthrough -- handle aborts by dropping packet */ + fallthrough; + case XDP_DROP: + result = IXGBE_XDP_CONSUMED; + break; + } + rcu_read_unlock(); + return result; +} + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +static struct +ixgbe_rx_buffer *ixgbe_get_rx_buffer_zc(struct ixgbe_ring *rx_ring, + unsigned int size) +{ + struct ixgbe_rx_buffer *bi; + + bi = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; + + /* we are reusing so sync this buffer for CPU use */ + dma_sync_single_range_for_cpu(rx_ring->dev, + bi->dma, 0, + size, + DMA_BIDIRECTIONAL); + + return bi; +} + +static void ixgbe_reuse_rx_buffer_zc(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *obi) +{ + unsigned long mask = (unsigned long)rx_ring->xsk_pool->chunk_mask; + u64 hr = rx_ring->xsk_pool->headroom + XDP_PACKET_HEADROOM; + u16 nta = rx_ring->next_to_alloc; + struct ixgbe_rx_buffer *nbi; + + nbi = &rx_ring->rx_buffer_info[rx_ring->next_to_alloc]; + /* update, and store next to alloc */ + nta++; + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; + + /* transfer page from old buffer to new buffer */ + nbi->dma = obi->dma & mask; + nbi->dma += hr; + + nbi->addr = (void *)((unsigned long)obi->addr & mask); + nbi->addr += hr; + + nbi->handle = obi->handle & mask; + nbi->handle += rx_ring->xsk_pool->headroom; + + obi->addr = NULL; + obi->skb = NULL; +} + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +void ixgbe_zca_free(struct zero_copy_allocator *alloc, unsigned long handle) +{ + struct ixgbe_rx_buffer *bi; + struct ixgbe_ring *rx_ring; + u64 hr, mask; + u16 nta; + + rx_ring = container_of(alloc, struct ixgbe_ring, zca); + hr = rx_ring->xsk_pool->headroom + XDP_PACKET_HEADROOM; + mask = rx_ring->xsk_pool->chunk_mask; + + nta = rx_ring->next_to_alloc; + bi = rx_ring->rx_buffer_info; + + nta++; + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; + + handle &= mask; + + bi->dma = xdp_umem_get_dma(rx_ring->xsk_pool, handle); + bi->dma += hr; + + bi->addr = xdp_umem_get_data(rx_ring->xsk_pool, handle); + bi->addr += hr; + + bi->handle = (u64)handle + rx_ring->xsk_pool->headroom; +} +#endif + +static bool ixgbe_alloc_buffer_zc(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi) +{ +#ifndef HAVE_NETDEV_BPF_XSK_POOL + struct xdp_umem *umem = rx_ring->xsk_pool; +#endif + void *addr = bi->addr; + u64 handle, hr; + + if (addr) + return true; + + if (!xsk_umem_peek_addr(umem, &handle)) { + rx_ring->rx_stats.alloc_rx_page_failed++; + return false; + } + + hr = umem->headroom + XDP_PACKET_HEADROOM; + + bi->dma = xdp_umem_get_dma(umem, handle); + bi->dma += hr; + + bi->addr = xdp_umem_get_data(umem, handle); + bi->addr += hr; + + bi->handle = handle + umem->headroom; + + xsk_umem_release_addr(umem); + return true; +} + +static bool ixgbe_alloc_buffer_slow_zc(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi) +{ +#ifndef HAVE_NETDEV_BPF_XSK_POOL + struct xdp_umem *pool = rx_ring->xsk_pool; +#else + struct xsk_buff_pool *pool = rx_ring->xsk_pool; +#endif + u64 handle, hr; + + if (!xsk_umem_peek_addr_rq(pool, &handle)) { + rx_ring->rx_stats.alloc_rx_page_failed++; + return false; + } + + handle &= rx_ring->xsk_pool->chunk_mask; + + hr = pool->headroom + XDP_PACKET_HEADROOM; + + bi->dma = xdp_umem_get_dma(pool, handle); + bi->dma += hr; + + bi->addr = xdp_umem_get_data(pool, handle); + bi->addr += hr; + + bi->handle = handle + pool->headroom; + + xsk_umem_release_addr_rq(pool); + return true; +} + +static __always_inline bool +__ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 count, + bool alloc(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi)) +#else +bool ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 count) +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ +{ + union ixgbe_adv_rx_desc *rx_desc; + struct ixgbe_rx_buffer *bi; + u16 i = rx_ring->next_to_use; +#ifdef HAVE_MEM_TYPE_XSK_BUFF_POOL + dma_addr_t dma; +#endif + bool ok = true; + + /* nothing to do */ + if (!count) + return true; + + rx_desc = IXGBE_RX_DESC(rx_ring, i); + bi = &rx_ring->rx_buffer_info[i]; + i -= rx_ring->count; + + do { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + if (!alloc(rx_ring, bi)) { +#else + bi->xdp = xsk_buff_alloc(rx_ring->xsk_pool); + if (!bi->xdp) { +#endif + ok = false; + break; + } + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + /* sync the buffer for use by the device */ + dma_sync_single_range_for_device(rx_ring->dev, bi->dma, + bi->page_offset, + rx_ring->rx_buf_len, + DMA_BIDIRECTIONAL); +#else + dma = xsk_buff_xdp_get_dma(bi->xdp); +#endif + + /* Refresh the desc even if buffer_addrs didn't change + * because each write-back erases this info. + */ +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); +#else + rx_desc->read.pkt_addr = cpu_to_le64(dma); +#endif + + rx_desc++; + bi++; + i++; + if (unlikely(!i)) { + rx_desc = IXGBE_RX_DESC(rx_ring, 0); + bi = rx_ring->rx_buffer_info; + i -= rx_ring->count; + } + + /* clear the length for the next_to_use descriptor */ + rx_desc->wb.upper.length = 0; + + count--; + } while (count); + + i += rx_ring->count; + + if (rx_ring->next_to_use != i) { + rx_ring->next_to_use = i; + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + /* update next to alloc since we have filled the ring */ + rx_ring->next_to_alloc = i; +#endif + + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). + */ + wmb(); + writel(i, rx_ring->tail); + } + + return ok; +} + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +void ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 count) +{ + __ixgbe_alloc_rx_buffers_zc(rx_ring, count, + ixgbe_alloc_buffer_slow_zc); +} + +static bool ixgbe_alloc_rx_buffers_fast_zc(struct ixgbe_ring *rx_ring, + u16 count) +{ + return __ixgbe_alloc_rx_buffers_zc(rx_ring, count, + ixgbe_alloc_buffer_zc); +} +#endif /* HAVE_MEM_TYPE_XSK_BUFF_POOL */ + +static struct sk_buff *ixgbe_construct_skb_zc(struct ixgbe_ring *rx_ring, +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct ixgbe_rx_buffer *bi, + struct xdp_buff *xdp) +#else + struct ixgbe_rx_buffer *bi) +#endif +{ +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct xdp_buff *xdp_buffer = xdp; +#else + struct xdp_buff *xdp_buffer = bi->xdp; +#endif + unsigned int metasize = xdp_buffer->data - xdp_buffer->data_meta; + unsigned int datasize = xdp_buffer->data_end - xdp_buffer->data; + struct sk_buff *skb; + + /* allocate a skb to store the frags */ + skb = napi_alloc_skb(&rx_ring->q_vector->napi, + xdp_buffer->data_end - xdp_buffer->data_hard_start); + if (unlikely(!skb)) + return NULL; + + skb_reserve(skb, xdp_buffer->data - xdp_buffer->data_hard_start); + memcpy(__skb_put(skb, datasize), xdp_buffer->data, datasize); + if (metasize) + skb_metadata_set(skb, metasize); +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + ixgbe_reuse_rx_buffer_zc(rx_ring, bi); +#else + xsk_buff_free(xdp_buffer); + bi->xdp = NULL; +#endif + return skb; +} + +static void ixgbe_inc_ntc(struct ixgbe_ring *rx_ring) +{ + u32 ntc = rx_ring->next_to_clean + 1; + + ntc = (ntc < rx_ring->count) ? ntc : 0; + rx_ring->next_to_clean = ntc; + prefetch(IXGBE_RX_DESC(rx_ring, ntc)); +} + +int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *rx_ring, + const int budget) +{ + unsigned int total_rx_bytes = 0, total_rx_packets = 0; + struct ixgbe_adapter *adapter = q_vector->adapter; + u16 cleaned_count = ixgbe_desc_unused(rx_ring); + unsigned int xdp_res, xdp_xmit = 0; + bool failure = false; + struct sk_buff *skb; +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + struct xdp_buff xdp; + + xdp.rxq = &rx_ring->xdp_rxq; +#endif + + while (likely(total_rx_packets < budget)) { + union ixgbe_adv_rx_desc *rx_desc; + struct ixgbe_rx_buffer *bi; + unsigned int size; + + /* return some buffers to hardware, one at a time is too slow */ + if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { + failure = failure || +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + !ixgbe_alloc_rx_buffers_fast_zc(rx_ring, + cleaned_count); +#else + !ixgbe_alloc_rx_buffers_zc(rx_ring, + cleaned_count); +#endif + cleaned_count = 0; + } + + rx_desc = IXGBE_RX_DESC(rx_ring, rx_ring->next_to_clean); + size = le16_to_cpu(rx_desc->wb.upper.length); + if (!size) + break; + + /* This memory barrier is needed to keep us from reading + * any other fields out of the rx_desc until we know the + * descriptor has been written back + */ + dma_rmb(); + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + bi = ixgbe_get_rx_buffer_zc(rx_ring, size); +#else + bi = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; +#endif + + if (unlikely(!ixgbe_test_staterr(rx_desc, + IXGBE_RXD_STAT_EOP))) { + struct ixgbe_rx_buffer *next_bi; + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + ixgbe_reuse_rx_buffer_zc(rx_ring, bi); +#else + xsk_buff_free(bi->xdp); + bi->xdp = NULL; +#endif + ixgbe_inc_ntc(rx_ring); + next_bi = + &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + next_bi->skb = ERR_PTR(-EINVAL); +#else + next_bi->discard = true; +#endif + continue; + } + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + if (unlikely(bi->skb)) { + ixgbe_reuse_rx_buffer_zc(rx_ring, bi); +#else + if (unlikely(bi->discard)) { + xsk_buff_free(bi->xdp); + bi->xdp = NULL; + bi->discard = false; +#endif + ixgbe_inc_ntc(rx_ring); + continue; + } + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + xdp.data = bi->addr; + xdp.data_meta = xdp.data; + xdp.data_hard_start = xdp.data - XDP_PACKET_HEADROOM; + xdp.data_end = xdp.data + size; + xdp.handle = bi->handle; + + xdp_res = ixgbe_run_xdp_zc(adapter, rx_ring, &xdp); +#else + bi->xdp->data_end = bi->xdp->data + size; + xsk_buff_dma_sync_for_cpu(bi->xdp); + xdp_res = ixgbe_run_xdp_zc(adapter, rx_ring, bi->xdp); +#endif + + if (xdp_res) { + if (xdp_res & (IXGBE_XDP_TX | IXGBE_XDP_REDIR)) { + xdp_xmit |= xdp_res; +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + bi->addr = NULL; + bi->skb = NULL; +#endif + } else { +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + ixgbe_reuse_rx_buffer_zc(rx_ring, bi); +#else + xsk_buff_free(bi->xdp); +#endif + } +#ifdef HAVE_MEM_TYPE_XSK_BUFF_POOL + bi->xdp = NULL; +#endif + total_rx_packets++; + total_rx_bytes += size; + + cleaned_count++; + ixgbe_inc_ntc(rx_ring); + continue; + } + + /* XDP_PASS path */ +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + skb = ixgbe_construct_skb_zc(rx_ring, bi, &xdp); +#else + skb = ixgbe_construct_skb_zc(rx_ring, bi); +#endif + if (!skb) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + break; + } + + cleaned_count++; + ixgbe_inc_ntc(rx_ring); + + if (eth_skb_pad(skb)) + continue; + + total_rx_bytes += skb->len; + total_rx_packets++; + + ixgbe_process_skb_fields(rx_ring, rx_desc, skb); + ixgbe_rx_skb(q_vector, rx_ring, rx_desc, skb); + } + + if (xdp_xmit & IXGBE_XDP_REDIR) + xdp_do_flush(); + + if (xdp_xmit & IXGBE_XDP_TX) { + struct ixgbe_ring *ring = ixgbe_determine_xdp_ring(adapter); + + ixgbe_xdp_ring_update_tail_locked(ring); + } + + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->stats.packets += total_rx_packets; + rx_ring->stats.bytes += total_rx_bytes; + u64_stats_update_end(&rx_ring->syncp); + q_vector->rx.total_packets += total_rx_packets; + q_vector->rx.total_bytes += total_rx_bytes; + + return failure ? budget : (int)total_rx_packets; +} + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL +void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring) +{ + u16 i = rx_ring->next_to_clean; + struct ixgbe_rx_buffer *bi = &rx_ring->rx_buffer_info[i]; + + while (i != rx_ring->next_to_alloc) { + xsk_umem_fq_reuse(rx_ring->xsk_pool, bi->handle); + i++; + bi++; + if (i == rx_ring->count) { + i = 0; + bi = rx_ring->rx_buffer_info; + } + } +} +#else +void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring) +{ + struct ixgbe_rx_buffer *bi; + u16 i; + + for (i = 0; i < rx_ring->count; i++) { + bi = &rx_ring->rx_buffer_info[i]; + + if (!bi->xdp) + continue; + + xsk_buff_free(bi->xdp); + bi->xdp = NULL; + } +} +#endif + +static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget) +{ + unsigned int sent_frames = 0, total_bytes = 0; + union ixgbe_adv_tx_desc *tx_desc = NULL; + u16 ntu = xdp_ring->next_to_use; + struct ixgbe_tx_buffer *tx_bi; + bool work_done = true; +#ifdef XSK_UMEM_RETURNS_XDP_DESC + struct xdp_desc desc; +#endif + dma_addr_t dma; + u32 cmd_type; +#ifndef XSK_UMEM_RETURNS_XDP_DESC + u32 len; +#endif + + while (budget-- > 0) { + if (unlikely(!ixgbe_desc_unused(xdp_ring) || + !netif_carrier_ok(xdp_ring->netdev))) { + work_done = false; + break; + } + +#ifdef XSK_UMEM_RETURNS_XDP_DESC + if (!xsk_tx_peek_desc(xdp_ring->xsk_pool, &desc)) + break; + +#ifndef HAVE_MEM_TYPE_XSK_BUFF_POOL + dma = xdp_umem_get_dma(xdp_ring->xsk_pool, desc.addr); + + dma_sync_single_for_device(xdp_ring->dev, dma, desc.len, + DMA_BIDIRECTIONAL); +#else + dma = xsk_buff_raw_get_dma(xdp_ring->xsk_pool, desc.addr); + xsk_buff_raw_dma_sync_for_device(xdp_ring->xsk_pool, dma, + desc.len); +#endif + + tx_bi = &xdp_ring->tx_buffer_info[ntu]; + tx_bi->bytecount = desc.len; + tx_bi->xdpf = NULL; +#else + if (!xsk_umem_consume_tx(xdp_ring->xsk_pool, &dma, &len)) + break; + + dma_sync_single_for_device(xdp_ring->dev, dma, len, + DMA_BIDIRECTIONAL); + + tx_bi = &xdp_ring->tx_buffer_info[ntu]; + tx_bi->bytecount = len; + tx_bi->xdpf = NULL; +#endif + + tx_desc = IXGBE_TX_DESC(xdp_ring, ntu); + tx_desc->read.buffer_addr = cpu_to_le64(dma); + + /* put descriptor type bits */ + cmd_type = IXGBE_ADVTXD_DTYP_DATA | + IXGBE_ADVTXD_DCMD_DEXT | + IXGBE_ADVTXD_DCMD_IFCS; +#ifdef XSK_UMEM_RETURNS_XDP_DESC + cmd_type |= desc.len | IXGBE_TXD_CMD_EOP; + tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); + tx_desc->read.olinfo_status = + cpu_to_le32(desc.len << IXGBE_ADVTXD_PAYLEN_SHIFT); +#else + cmd_type |= len | IXGBE_TXD_CMD_EOP; + tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); + tx_desc->read.olinfo_status = + cpu_to_le32(len << IXGBE_ADVTXD_PAYLEN_SHIFT); +#endif + + xdp_ring->next_rs_idx = ntu; + ntu++; + if (ntu == xdp_ring->count) + ntu = 0; + xdp_ring->next_to_use = ntu; + + sent_frames++; + total_bytes += tx_bi->bytecount; + } + + if (tx_desc) { + /* set RS bit for the last frame and bump tail ptr */ + cmd_type |= IXGBE_TXD_CMD_RS; + tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); + + ixgbe_xdp_ring_update_tail(xdp_ring); + xsk_tx_release(xdp_ring->xsk_pool); + + u64_stats_update_begin(&xdp_ring->syncp); + xdp_ring->stats.bytes += total_bytes; + xdp_ring->stats.packets += sent_frames; + u64_stats_update_end(&xdp_ring->syncp); + xdp_ring->q_vector->tx.total_bytes += total_bytes; + xdp_ring->q_vector->tx.total_packets += sent_frames; + + } + + return (budget > 0) && work_done; +} + +static void ixgbe_clean_xdp_tx_buffer(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *tx_bi) +{ + xdp_return_frame(tx_bi->xdpf); + tx_ring->xdp_tx_active--; + dma_unmap_single(tx_ring->dev, + dma_unmap_addr(tx_bi, dma), + dma_unmap_len(tx_bi, len), DMA_TO_DEVICE); + dma_unmap_len_set(tx_bi, len, 0); +} + +bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring *tx_ring) +{ + u32 next_rs_idx = tx_ring->next_rs_idx; + union ixgbe_adv_tx_desc *next_rs_desc; + u32 ntc = tx_ring->next_to_clean; + struct ixgbe_tx_buffer *tx_bi; + u16 frames_ready = 0; + u32 xsk_frames = 0; + u16 i; + + next_rs_desc = IXGBE_TX_DESC(tx_ring, next_rs_idx); + if (next_rs_desc->wb.status & + cpu_to_le32(IXGBE_TXD_STAT_DD)) { + if (next_rs_idx >= ntc) + frames_ready = next_rs_idx - ntc; + else + frames_ready = next_rs_idx + tx_ring->count - ntc; + } + + if (!frames_ready) + goto out_xmit; + + if (likely(!tx_ring->xdp_tx_active)) { + xsk_frames = frames_ready; + } else { + for (i = 0; i < frames_ready; i++) { + tx_bi = &tx_ring->tx_buffer_info[ntc]; + + if (tx_bi->xdpf) + ixgbe_clean_xdp_tx_buffer(tx_ring, tx_bi); + else + xsk_frames++; + + tx_bi->xdpf = NULL; + + ++ntc; + if (ntc >= tx_ring->count) + ntc = 0; + } + } + + tx_ring->next_to_clean += frames_ready; + if (unlikely(tx_ring->next_to_clean >= tx_ring->count)) + tx_ring->next_to_clean -= tx_ring->count; + + if (xsk_frames) + xsk_tx_completed(tx_ring->xsk_pool, xsk_frames); + +out_xmit: + return ixgbe_xmit_zc(tx_ring, q_vector->tx.work_limit); +} + +#ifdef HAVE_NDO_XSK_WAKEUP +/** + * ixgbe_xsk_wakeup - Wake up an XDP socket queue for transmission + * @dev: Network device structure pointer + * @qid: Queue ID for the XDP socket + * @flags: Flags for the wakeup operation (unused) + * + * This function wakes up a specified XDP (eXpress Data Path) socket queue + * on the ixgbe network adapter to enable transmission. It checks the device + * state, the presence of an XDP program, and the validity of the queue ID. + * If the queue is valid and not scheduled, it rearms the interrupt for the + * queue to ensure it is ready for transmission. + * + * Return: 0 on success, or a negative error code on failure, such as + * -ENETDOWN if the device is down or -ENXIO if the queue is invalid. + */ +int ixgbe_xsk_wakeup(struct net_device *dev, u32 qid, u32 __maybe_unused flags) +#else +/** + * ixgbe_xsk_async_xmit - Transmit XDP frames asynchronously on a queue + * @dev: Network device structure pointer + * @qid: Queue ID for the XDP transmission + * + * This function handles the asynchronous transmission of XDP (eXpress Data + * Path) frames on a specified queue of the ixgbe network adapter. It checks + * the device state, the presence of an XDP program, and the validity of the + * queue ID. If the queue is valid and not scheduled, it rearms the interrupt + * for the queue to ensure transmission. + * + * Return: 0 on success, or a negative error code on failure, such as + * -ENETDOWN if the device is down or -ENXIO if the queue is invalid. + */ +int ixgbe_xsk_async_xmit(struct net_device *dev, u32 qid) +#endif +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_ring *ring; + + if (test_bit(__IXGBE_DOWN, adapter->state)) + return -ENETDOWN; + + if (!READ_ONCE(adapter->xdp_prog)) + return -ENXIO; + + if (qid >= adapter->num_xdp_queues) + return -ENXIO; + +#ifndef HAVE_NETDEV_BPF_XSK_POOL + if (!adapter->xsk_pools || !adapter->xsk_pools[qid]) +#else + if (!xsk_get_pool_from_qid(adapter->netdev, qid)) +#endif /* HAVE_NETDEV_BPF_XSK_POOL */ + return -ENXIO; + + ring = adapter->xdp_ring[qid]; + if (!napi_if_scheduled_mark_missed(&ring->q_vector->napi)) { + u64 eics = BIT_ULL(ring->q_vector->v_idx); + + ixgbe_irq_rearm_queues(adapter, eics); + } + + return 0; +} + +void ixgbe_xsk_clean_tx_ring(struct ixgbe_ring *tx_ring) +{ + u16 ntc = tx_ring->next_to_clean, ntu = tx_ring->next_to_use; + struct ixgbe_tx_buffer *tx_bi; + u32 xsk_frames = 0; + + while (ntc != ntu) { + tx_bi = &tx_ring->tx_buffer_info[ntc]; + + if (tx_bi->xdpf) + ixgbe_clean_xdp_tx_buffer(tx_ring, tx_bi); + else + xsk_frames++; + + tx_bi->xdpf = NULL; + + ntc++; + if (ntc == tx_ring->count) + ntc = 0; + } + + if (xsk_frames) + xsk_tx_completed(tx_ring->xsk_pool, xsk_frames); +} +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-generator.sh b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-generator.sh new file mode 100644 index 0000000000..cb53529b87 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-generator.sh @@ -0,0 +1,715 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 1999 - 2026 Intel Corporation + +set -Eeuo pipefail + +# This file generates HAVE_ and NEED_ defines for current kernel +# (or KSRC if provided). +# +# It does so by 'gen' function calls (see body of 'gen-devlink' for examples). +# 'gen' could look for various kinds of declarations in provided kernel headers, +# eg look for an enum in one of files specified and check if given enumeration +# (single value) is present. See 'Documentation' or comment above the 'gen' fun +# in the kcompat-lib.sh. + +# Why using bash/awk instead of an old/legacy approach? +# +# The aim is to replicate all the defines provided by human developers +# in the past. Additional bonus is the fact, that we no longer need to care +# about backports done by OS vendors (RHEL, SLES, ORACLE, UBUNTU, more to come). +# We will even work (compile) with only part of backports provided. +# +# To enable smooth transition, especially in time of late fixes, "old" method +# of providing flags should still work as usual. + +# End of intro. +# Find info about coding style/rules at the end of file. +# Most of the implementation is in kcompat-lib.sh, here are actual 'gen' calls. + +export LC_ALL=C +SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" +ORIG_CWD="$(pwd)" +trap 'rc=$?; echo >&2 "$(realpath "$ORIG_CWD/${BASH_SOURCE[0]}"):$LINENO: failed with rc: $rc"' ERR + +# shellcheck source=kcompat-lib.sh +source "$SCRIPT_DIR"/kcompat-lib.sh + +ARCH=$(uname -m) +IS_ARM= +if [ "$ARCH" == aarch64 ]; then + IS_ARM=1 +fi + +# DO NOT break gen calls below (via \), to make our compat code more grep-able, +# keep them also grouped, first by feature (like DEVLINK), then by .h filename +# finally, keep them sorted within a group (sort by flag name) + +# handy line of DOC copy-pasted form kcompat-lib.sh: +# gen DEFINE if (KIND [METHOD of]) NAME [(matches|lacks) PATTERN|absent] in + +function gen-aux() { + ah='include/linux/auxiliary_bus.h' + mh='include/linux/mod_devicetable.h' + HAVE_AUX_INT_REMOVE=0 + if config_has CONFIG_AUXILIARY_BUS && + check method remove of auxiliary_driver matches 'int' in "$ah" ; then + HAVE_AUX_INT_REMOVE=1 + fi + gen HAVE_AUXILIARY_DRIVER_INT_REMOVE if string "$HAVE_AUX_INT_REMOVE" equals 1 + + # generate HAVE_AUXILIARY_DEVICE_ID only for cases when it's disabled in .config + HAVE_AUX_DEV_ID=0 + if ! config_has CONFIG_AUXILIARY_BUS && check struct auxiliary_device_id in "$mh" ; then + HAVE_AUX_DEV_ID=1 + fi + gen HAVE_AUXILIARY_DEVICE_ID if string "$HAVE_AUX_DEV_ID" equals 1 +} + +function gen-bitfield() { + bf='include/linux/bitfield.h' + gen HAVE_INCLUDE_BITFIELD if macro FIELD_PREP in "$bf" + gen NEED_BITFIELD_FIELD_FIT if macro FIELD_FIT absent in "$bf" + gen NEED_BITFIELD_FIELD_MASK if fun field_mask absent in "$bf" + gen NEED_BITFIELD_FIELD_MAX if macro FIELD_MAX absent in "$bf" +} + +function gen-cleanup() { + ch='include/linux/cleanup.h' + dh='include/net/devlink.h' + mh='include/linux/mutex.h' + sh='include/linux/spinlock.h' + slabh='include/linux/slab.h' + rcuh='include/linux/rcupdate.h' + gen NEED_DEFINE_FREE if macro DEFINE_FREE absent in "$ch" + gen NEED___DEFINE_CLASS_IS_CONDITIONAL if macro __DEFINE_CLASS_IS_CONDITIONAL absent in "$ch" + gen NEED_DEFINE_GUARD_MUTEX if invocation of macro DEFINE_GUARD absent or lacks mutex_lock in "$mh" + gen NEED_LOCK_GUARD_FOR_RCU if invocation of macro DEFINE_LOCK_GUARD_0 absent or lacks rcu in "$rcuh" + gen NEED_DEFINE_FREE_KFREE if invocation of macro DEFINE_FREE absent or lacks kfree in "$slabh" + gen NEED_DEFINE_FREE_KVFREE if invocation of macro DEFINE_FREE absent or lacks kvfree in "$slabh" + gen NEED_LOCK_GUARD_FOR_SPINLOCK if invocation of macro DEFINE_LOCK_GUARD_1 absent or lacks spinlock in "$sh" + gen NEED_LOCK_GUARD_FOR_SPINLOCK_BH if invocation of macro DEFINE_LOCK_GUARD_1 absent or lacks spinlock_bh in "$sh" + gen NEED_DEFINE_GUARD_DEVLINK if invocation of macro DEFINE_GUARD absent or lacks devl_lock in "$dh" +} + +function gen-device() { + dh='include/linux/device.h' + dph='include/linux/dev_printk.h' + gen NEED_BUS_FIND_DEVICE_CONST_DATA if fun bus_find_device lacks 'const void \\*data' in "$dh" + gen NEED_DEV_LEVEL_ONCE if macro dev_level_once absent in "$dh" "$dph" +} + +function gen-devlink() { + dh='include/net/devlink.h' + gen HAVE_DEVLINK_ESWITCH_OPS_EXTACK if fun eswitch_mode_set matches extack in "$dh" + gen HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY if fun devlink_flash_update_begin_notify in "$dh" + gen HAVE_DEVLINK_FLASH_UPDATE_PARAMS if struct devlink_flash_update_params in "$dh" + gen HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FW if struct devlink_flash_update_params matches 'struct firmware \\*fw' in "$dh" + gen HAVE_DEVLINK_FLASH_UPDATE_PARAMS_OVERWRITE_MASK if struct devlink_flash_update_params matches 'overwrite_mask' in "$dh" + gen HAVE_DEVLINK_HEALTH if enum devlink_health_reporter_state in "$dh" + gen HAVE_DEVLINK_HEALTH_OPS_EXTACK if method dump of devlink_health_reporter_ops matches extack in "$dh" + gen HAVE_DEVLINK_INFO_DRIVER_NAME_PUT if fun devlink_info_driver_name_put in "$dh" + gen HAVE_DEVLINK_PARAMS if method validate of devlink_param matches extack in "$dh" + gen HAVE_DEVLINK_PARAMS_PUBLISH if fun devlink_params_publish in "$dh" + gen HAVE_DEVLINK_PARAMS_SET_EXTACK if method set of devlink_param matches extack in "$dh" + gen HAVE_DEVLINK_PORT_NEW if method port_new of devlink_ops in "$dh" + gen HAVE_DEVLINK_PORT_OPS if struct devlink_port_ops in "$dh" + gen HAVE_DEVLINK_PORT_REGISTERED if struct devlink_port matches 'registered' in "$dh" + gen HAVE_DEVLINK_PORT_SPLIT if method port_split of '(devlink_ops|devlink_port_ops)' in "$dh" + gen HAVE_DEVLINK_PORT_SPLIT_EXTACK if method port_split of '(devlink_ops|devlink_port_ops)' matches extack in "$dh" + gen HAVE_DEVLINK_PORT_SPLIT_IN_OPS if method port_split of devlink_ops in "$dh" + gen HAVE_DEVLINK_PORT_SPLIT_IN_PORT_OPS if method port_split of devlink_port_ops in "$dh" + gen HAVE_DEVLINK_PORT_SPLIT_PORT_STRUCT if method port_split of '(devlink_ops|devlink_port_ops)' matches devlink_port in "$dh" + gen HAVE_DEVLINK_PORT_TYPE_ETH_HAS_NETDEV if fun devlink_port_type_eth_set matches 'struct net_device' in "$dh" + gen HAVE_DEVLINK_RATE_NODE_CREATE if fun devl_rate_node_create in "$dh" + # keep devlink_region_ops body in variable, to not look 4 times for + # exactly the same thing in big file + # please consider it as an example of "how to speed up if needed" + REGION_OPS="$(find-struct-decl devlink_region_ops "$dh")" + gen HAVE_DEVLINK_REGIONS if struct devlink_region_ops in - <<< "$REGION_OPS" + gen HAVE_DEVLINK_REGION_OPS_SNAPSHOT if fun snapshot in - <<< "$REGION_OPS" + gen HAVE_DEVLINK_REGION_OPS_SNAPSHOT_OPS if fun snapshot matches devlink_region_ops in - <<< "$REGION_OPS" + gen HAVE_DEVLINK_REGISTER_SETS_DEV if fun devlink_register matches 'struct device' in "$dh" + gen HAVE_DEVLINK_RELOAD_ENABLE_DISABLE if fun devlink_reload_enable in "$dh" + gen HAVE_DEVLINK_SET_FEATURES if fun devlink_set_features in "$dh" + gen HAVE_DEVL_HEALTH_REPORTER_DESTROY if fun devl_health_reporter_destroy in "$dh" + gen HAVE_DEVL_PORT_REGISTER if fun devl_port_register in "$dh" + gen HAVE_DEVL_PORT_REG_WITH_OPS_AND_UNREG if fun devl_port_register_with_ops in "$dh" + gen NEED_DEVLINK_FLASH_UPDATE_STATUS_NOTIFY if fun devlink_flash_update_status_notify absent in "$dh" + gen NEED_DEVLINK_FLASH_UPDATE_TIMEOUT_NOTIFY if fun devlink_flash_update_timeout_notify absent in "$dh" + gen NEED_DEVLINK_FMSG_DUMP_SKB if fun devlink_fmsg_dump_skb absent in "$dh" + gen NEED_DEVLINK_FMSG_PUT if macro devlink_fmsg_put absent in "$dh" + gen NEED_DEVLINK_HEALTH_DEFAULT_AUTO_RECOVER if fun devlink_health_reporter_create matches auto_recover in "$dh" + gen NEED_DEVLINK_REGION_CREATE_OPS if fun devlink_region_create lacks 'struct devlink_region_ops \\*ops' in "$dh" + gen NEED_DEVLINK_RESOURCES_UNREGISTER_NO_RESOURCE if fun devlink_resources_unregister matches 'struct devlink_resource \\*' in "$dh" + gen NEED_DEVLINK_TO_DEV if fun devlink_to_dev absent in "$dh" + gen NEED_DEVLINK_UNLOCKED_RESOURCE if fun devl_resource_size_get absent in "$dh" + gen NEED_DEVL_HEALTH_REPORTER_CREATE if fun devl_health_reporter_create absent in "$dh" + gen NEED_DEVL_HEALTH_REPORTER_CREATE_REMOVE_GRACEFUL_PERIOD if fun devl_health_reporter_create matches graceful_period in "$dh" + gen NEED_DEVL_LOCK if fun devl_lock absent in "$dh" + gen NEED_DEVL_PARAMS_REGISTER if fun devl_params_register absent in "$dh" + gen NEED_DEVL_PORT_REGISTER if fun devl_port_register absent in "$dh" + gen NEED_DEVL_REGION_CREATE if fun devl_region_create absent in "$dh" + gen NEED_DEVL_REGISTER if fun devl_register absent in "$dh" + gen NEED_DEVL_RESOURCE_REGISTER if fun devl_resource_register absent in "$dh" + + gen HAVE_DEVLINK_PORT_FLAVOUR_PCI_SF if enum devlink_port_flavour matches DEVLINK_PORT_FLAVOUR_PCI_SF in include/uapi/linux/devlink.h + gen HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT if enum devlink_reload_action matches DEVLINK_RELOAD_ACTION_FW_ACTIVATE in include/uapi/linux/devlink.h +} + +function gen-devres() { + dh='include/linux/device.h' + ddrh='include/linux/device/devres.h' + gen NEED_DEVM_KASPRINTF if fun devm_kasprintf absent in "$dh" "$ddrh" + gen NEED_DEVM_KCALLOC if fun devm_kcalloc absent in "$dh" "$ddrh" + gen NEED_DEVM_KFREE if fun devm_kfree absent in "$dh" "$ddrh" + gen NEED_DEVM_KMEMDUP if fun devm_kmemdup absent in "$dh" "$ddrh" + gen NEED_DEVM_KSTRDUP if fun devm_kstrdup absent in "$dh" "$ddrh" + gen NEED_DEVM_KVASPRINTF if fun devm_kvasprintf absent in "$dh" "$ddrh" + gen NEED_DEVM_KZALLOC if fun devm_kzalloc absent in "$dh" "$ddrh" +} + +function gen-dma() { + dma='include/linux/dma-mapping.h' + gen NEED_DMA_ATTRS_PTR if struct dma_attrs in include/linux/dma-attrs.h + gen NEED_DMA_ATTRS if fun dma_map_page_attrs absent in "$dma" +} + +function gen-dpll() { + dh='include/linux/dpll.h' + gen HAVE_DPLL_ESYNC if method esync_get of dpll_pin_ops in "$dh" + gen HAVE_DPLL_LOCK_STATUS_ERROR if method lock_status_get of dpll_device_ops matches status_error in "$dh" + gen HAVE_DPLL_PHASE_OFFSET if method phase_offset_get of dpll_pin_ops in "$dh" + gen HAVE_DPLL_PHASE_OFFSET_MONITOR if method phase_offset_monitor_set of dpll_device_ops in "$dh" + gen NEED_DPLL_NETDEV_PIN_SET if fun dpll_netdev_pin_set absent in "$dh" +} + +function gen-ethtool() { + eth='include/linux/ethtool.h' + nleth='include/linux/ethtool_netlink.h' + ueth='include/uapi/linux/ethtool.h' + unleth='include/uapi/linux/ethtool_netlink.h' + unlgeth='include/uapi/linux/ethtool_netlink_generated.h' + gen HAVE_ETHTOOL_COALESCE_EXTACK if method get_coalesce of ethtool_ops matches 'struct kernel_ethtool_coalesce \\*' in "$eth" + gen HAVE_ETHTOOL_EXTENDED_RINGPARAMS if method get_ringparam of ethtool_ops matches 'struct kernel_ethtool_ringparam \\*' in "$eth" + gen HAVE_ETHTOOL_FEC_HIST if method get_fec_stats of ethtool_ops matches 'struct ethtool_fec_hist \\*' in "$eth" + gen HAVE_ETHTOOL_GET_FEC_STATS_OPS if struct ethtool_ops matches '\\*get_fec_stats' in "$eth" + gen HAVE_ETHTOOL_KEEE if struct ethtool_keee in "$eth" + gen HAVE_ETHTOOL_KERNEL_TS_INFO if struct kernel_ethtool_ts_info in "$eth" + gen HAVE_ETHTOOL_LINK_EXT_STATS if struct ethtool_ops matches '\\*get_link_ext_stats' in "$eth" + gen HAVE_ETHTOOL_PUTS if fun ethtool_puts in "$eth" + gen HAVE_ETHTOOL_RXFH_PARAM if struct ethtool_rxfh_param in "$eth" + gen HAVE_ETHTOOL_SUPPORTED_RING_PARAMS if struct ethtool_ops matches 'supported_ring_params' in "$eth" + gen NEED_ETHTOOL_RING_USE_TCP_DATA_SPLIT if enum ethtool_supported_ring_param matches ETHTOOL_RING_USE_TCP_DATA_SPLIT in "$eth" + gen NEED_ETHTOOL_SPRINTF if fun ethtool_sprintf absent in "$eth" + gen HAVE_ETHTOOL_FLOW_RSS if macro FLOW_RSS in "$ueth" + gen HAVE_ETHTOOL_LINK_MODE_FEC_NONE_BIT if enum ethtool_link_mode_bit_indices matches ETHTOOL_LINK_MODE_FEC_NONE_BIT in "$ueth" + gen NEED_ETHTOOL_LINK_MODE_BIT_INDICES if enum ethtool_link_mode_bit_indices absent in "$ueth" + + ETHTOOL_TCP_DATA_SPLIT=0 + if check anonymous enum matches ETHTOOL_TCP_DATA_SPLIT_UNKNOWN in "$unleth" || + check enum ethtool_tcp_data_split matches ETHTOOL_TCP_DATA_SPLIT_UNKNOWN in "$unlgeth"; then + ETHTOOL_TCP_DATA_SPLIT=1 + fi + gen HAVE_ETHTOOL_SUPPORT_TCP_DATA_SPLIT if string "$ETHTOOL_TCP_DATA_SPLIT" equals 1 +} + +function gen-exported-symbols() { + # The Module.symvers is a generated file that is found in the object + # directory, not the source directory. + symvers="${KOBJ}/Module.symvers" + gen HAVE_EXPORTED_IRQ_SET_AFFINITY if symbol irq_set_affinity matches vmlinux in "$symvers" +} + +function gen-filter() { + fh='include/linux/filter.h' + gen NEED_NO_NETDEV_PROG_XDP_WARN_ACTION if fun bpf_warn_invalid_xdp_action lacks 'struct net_device \\*' in "$fh" + gen NEED_XDP_DO_FLUSH if fun xdp_do_flush absent in "$fh" +} + +function gen-flow-dissector() { + aah='include/net/act_api.h' + fdh='include/net/flow_dissector.h' + fkh='include/net/flow_keys.h' + foh='include/net/flow_offload.h' + pch='include/net/pkt_cls.h' + sgh='include/net/sch_generic.h' + tmh='include/net/tc_act/tc_mirred.h' + + gen HAVE_FLOW_DISSECTOR_KEY_PPPOE if enum flow_dissector_key_id matches FLOW_DISSECTOR_KEY_PPPOE in "$fdh" "$fkh" + gen HAVE_FLOW_DISSECTOR_ICMP_ID if enum flow_dissector_key_icmp matches id in "$fdh" + + gen HAVE_FLOW_BLOCK_API if fun flow_block_cb_priv in "$foh" + + # following HAVE ... CVLAN flag is mistakenly named after an enum key, + # but guards code around function call that was introduced later + gen HAVE_FLOW_DISSECTOR_KEY_CVLAN if fun flow_rule_match_cvlan in "$foh" + gen HAVE_FLOW_MATCH_ICMP if struct flow_match_icmp in "$foh" + gen HAVE_TC_FLOW_INDIR_BLOCK_CLEANUP if fun flow_indr_dev_unregister matches 'void \\(\\*release\\)\\(void \\*cb_priv\\)' in "$foh" + gen HAVE_TC_FLOW_INDIR_DEV if fun flow_indr_dev_register in "$foh" + gen HAVE_TC_FLOW_RULE_INFRASTRUCTURE if struct flow_action in "$foh" + gen NEED_FLOW_BLOCK_BIND if enum '(flow_block_command|tc_block_command)' lacks FLOW_BLOCK_BIND in "$foh" "$pch" + gen NEED_FLOW_BLOCK_BINDER_TYPE if enum '(flow_block_binder_type|tcf_block_binder_type)' lacks FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS in "$foh" "$pch" + gen NEED_FLOW_BLOCK_CB_SETUP_SIMPLE if fun flow_block_cb_setup_simple absent in "$foh" + gen NEED_FLOW_CLS_OFFLOAD if struct flow_cls_offload absent in "$foh" + gen NEED_FLOW_MATCH if struct flow_match absent in "$foh" + + gen HAVE_TCF_BLOCK_CB_REGISTER_EXTACK if fun tcf_block_cb_register matches 'struct netlink_ext_ack \\*extack' in "$pch" + gen HAVE_TCF_EXTS_FOR_EACH_ACTION if macro tcf_exts_for_each_action in "$pch" + gen HAVE_TCF_EXTS_HAS_ACTION if fun tcf_exts_has_actions in "$pch" + gen HAVE_TCF_EXTS_TO_LIST if fun tcf_exts_to_list in "$pch" + + gen HAVE_TCF_BLOCK if fun '(tcf_block_cb_register|flow_block_cb_setup_simple)' in "$foh" "$pch" + gen HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO if typedef '(tc_setup_cb_t|flow_setup_cb_t)' in "$aah" "$foh" "$sgh" + gen HAVE_TC_INDIR_BLOCK if fun '(flow_indr_dev_register|tc_indr_block_cb_register|flow_indr_block_cb_register)' in "$foh" "$pch" + gen HAVE_TC_SETUP_CLSFLOWER if struct '(tc_cls_flower_offload|flow_cls_offload)' in "$foh" "$pch" + + # Some drivers check HAVE_TCF_MIRRED_DEV and + # HAVE_TCF_MIRRED_EGRESS_REDIRECT directly, so we need to keep both + # the NEED_ and HAVE_ variants. + # + # Additionally, drivers check HAVE_TCF_MIRRED_REDIRECT and expect it + # to be true even after the rename to is_tcf_mirred_egress_redirect. + gen HAVE_TCF_MIRRED_DEV if fun tcf_mirred_dev in "$tmh" + gen HAVE_TCF_MIRRED_EGRESS_REDIRECT if fun is_tcf_mirred_egress_redirect in "$tmh" + gen HAVE_TCF_MIRRED_REDIRECT if fun '(is_tcf_mirred_egress_redirect|is_tcf_mirred_redirect)' in "$tmh" + gen NEED_TCF_MIRRED_DEV if fun tcf_mirred_dev absent in "$tmh" + gen NEED_TCF_MIRRED_EGRESS_REDIRECT if fun is_tcf_mirred_egress_redirect absent in "$tmh" +} + +function gen-gnss() { + cdh='include/linux/cdev.h' + clh='include/linux/device/class.h' + dh='include/linux/device.h' + gh='include/linux/gnss.h' + th='include/uapi/linux/types.h' + fh='include/linux/fs.h' + + gen HAVE_CDEV_DEVICE if fun cdev_device_add in "$cdh" + gen HAVE_DEV_UEVENT_CONST if method dev_uevent of class matches '(const|RH_KABI_CONST) struct device' in "$clh" "$dh" + gen HAVE_NO_LLSEEK if fun no_llseek in "$fh" + gen HAVE_STREAM_OPEN if fun stream_open in "$fh" + + NEED_CLASS_CREATE=0 + if check fun class_create matches 'owner' in "$clh" "$dh" || + check macro class_create matches 'owner' in "$clh" "$dh" ; then + NEED_CLASS_CREATE=1 + fi + gen NEED_CLASS_CREATE_WITHOUT_OWNER if string "$NEED_CLASS_CREATE" equals 1 + + HAVE_GNSS_MODULE=0 + if ! config_has CONFIG_SUSE_KERNEL && check struct gnss_device in "$gh" ; then + HAVE_GNSS_MODULE=1 + fi + gen HAVE_GNSS_MODULE if string "$HAVE_GNSS_MODULE" equals 1 + + gen HAVE_POLL_T if typedef __poll_t in "$th" +} + +function gen-mdev() { + mdevh='include/linux/mdev.h' + + gen HAVE_DEV_IN_MDEV_API if method probe of mdev_driver matches 'struct device \\*' in "$mdevh" + gen HAVE_KOBJ_IN_MDEV_PARENT_OPS_CREATE if method create of mdev_parent_ops matches 'struct kobject \\*' in "$mdevh" +} + +function gen-mdio() { + mdioh='include/linux/mdio.h' + + gen HAVE_MII_EEE_CAP1_MOD_LINKMODE if fun mii_eee_cap1_mod_linkmode_t in "$mdioh" +} + +function gen-mm() { + slabh='include/linux/slab.h' + + gen NEED_KREALLOC_ARRAY if fun krealloc_array absent in "$slabh" + + HAVE_KMEM_CACHE_ALLOC_LRU=0 + check macro kmem_cache_alloc_lru in "$slabh" && HAVE_KMEM_CACHE_ALLOC_LRU=1 + check fun kmem_cache_alloc_lru in "$slabh" && HAVE_KMEM_CACHE_ALLOC_LRU=1 + gen NEED_KMEM_CACHE_ALLOC_LRU if string "$HAVE_KMEM_CACHE_ALLOC_LRU" equals 0 +} + +function gen-netdevice() { + ndh='include/linux/netdevice.h' + gen HAVE_NDO_BRIDGE_SETLINK_EXTACK if method ndo_bridge_setlink of net_device_ops matches 'struct netlink_ext_ack \\*extack' in "$ndh" + gen HAVE_NDO_ETH_IOCTL if fun ndo_eth_ioctl in "$ndh" + gen HAVE_NDO_EXTENDED_SET_TX_MAXRATE if method ndo_set_tx_maxrate of net_device_ops_extended in "$ndh" + gen HAVE_NDO_FDB_ADD_EXTACK if method ndo_fdb_add of net_device_ops matches 'struct netlink_ext_ack \\*extack' in "$ndh" + gen HAVE_NDO_FDB_ADD_NOTIFIED if method ndo_fdb_add of net_device_ops matches 'bool \\*notified' in "$ndh" + gen HAVE_NDO_FDB_ADD_VID if method ndo_fdb_add of net_device_ops matches 'u16 vid' in "$ndh" + gen HAVE_NDO_FDB_DEL_EXTACK if method ndo_fdb_del of net_device_ops matches 'struct netlink_ext_ack \\*extack' in "$ndh" + gen HAVE_NDO_FDB_DEL_NOTIFIED if method ndo_fdb_del of net_device_ops matches 'bool \\*notified' in "$ndh" + gen HAVE_NDO_GET_DEVLINK_PORT if method ndo_get_devlink_port of net_device_ops in "$ndh" + gen HAVE_NDO_SETUP_TC_CHAIN_INDEX if method ndo_setup_tc of net_device_ops matches 'u32 chain_index' in "$ndh" + gen HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV if method '(ndo_setup_tc|ndo_setup_tc_rh)' of '(net_device_ops|netdevice_ops_extended)' matches 'void \\*type_data' in "$ndh" + gen HAVE_NDO_UDP_TUNNEL_CALLBACK if method ndo_udp_tunnel_add of net_device_ops in "$ndh" + gen HAVE_NETDEV_EXTENDED_MIN_MAX_MTU if struct net_device_extended matches min_mtu in "$ndh" + gen HAVE_NETDEV_FCOE_MTU if struct net_device matches fcoe_mtu in "$ndh" + gen HAVE_NETDEV_IRQ_AFFINITY_AND_ARFS if struct net_device matches irq_affinity_auto in "$ndh" + gen HAVE_NETDEV_MIN_MAX_MTU if struct net_device matches min_mtu in "$ndh" + gen HAVE_NETIF_SET_TSO_MAX if fun netif_set_tso_max_size in "$ndh" + gen HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SETUP_TC if method ndo_setup_tc_rh of net_device_ops_extended in "$ndh" + gen HAVE_SET_NETDEV_DEVLINK_PORT if macro SET_NETDEV_DEVLINK_PORT in "$ndh" + gen NEED_NETDEV_TX_SENT_QUEUE if fun __netdev_tx_sent_queue absent in "$ndh" + gen NEED_NETIF_NAPI_ADD_NO_WEIGHT if fun netif_napi_add matches 'int weight' in "$ndh" + gen NEED_NET_PREFETCH if fun net_prefetch absent in "$ndh" + gen NEED_XDP_FEATURES if enum netdev_xdp_act absent in include/uapi/linux/netdev.h +} + +function gen-netif() { + gen HAVE_GENEVE_TYPE if fun netif_is_geneve in include/net/geneve.h + gen HAVE_GRETAP_TYPE if fun netif_is_gretap in include/net/gre.h + gen HAVE_GTP_SUPPORT if fun netif_is_gtp in include/net/gtp.h + gen HAVE_NETIF_SUBQUEUE_MAYBE_STOP if macro netif_subqueue_maybe_stop in include/net/netdev_queues.h + gen HAVE_VXLAN_TYPE if fun netif_is_vxlan in include/net/vxlan.h +} + +function gen-packing() { + lph='include/linux/packing.h' + HAVE_PACK_FIELDS=0 + if config_has CONFIG_PACKING && check macro pack_fields in "$lph" ; then + HAVE_PACK_FIELDS=1 + fi + gen HAVE_PACK_FIELDS if string "$HAVE_PACK_FIELDS" equals 1 +} + +function gen-pci() { + pcih='include/linux/pci.h' + gen HAVE_PCI_MSIX_ALLOC_IRQ_AT if fun pci_msix_alloc_irq_at in "$pcih" + gen HAVE_PCI_MSIX_CAN_ALLOC_DYN if fun pci_msix_can_alloc_dyn in "$pcih" + gen HAVE_PCI_MSIX_FREE_IRQ if fun pci_msix_free_irq in "$pcih" + gen HAVE_PER_VF_MSIX_SYSFS if method sriov_set_msix_vec_count of pci_driver in "$pcih" + gen HAVE_STRUCT_PCI_DEV_PTM_CAP if struct pci_dev matches ptm_cap in "$pcih" + gen HAVE_STRUCT_PCI_DEV_PTM_ENABLED if struct pci_dev matches ptm_enabled in "$pcih" + gen NEED_PCIE_FLR if fun pcie_flr absent in "$pcih" + gen NEED_PCIE_FLR_RETVAL if fun pcie_flr lacks 'int pcie_flr' in "$pcih" + gen NEED_PCIE_PTM_ENABLED if fun pcie_ptm_enabled absent in "$pcih" + gen NEED_PCI_DISABLE_PTM if fun pci_disable_ptm absent in "$pcih" + gen NEED_PCI_ENABLE_PTM if fun pci_enable_ptm absent in "$pcih" +} + +function gen-ptp() { + classifyh='include/linux/ptp_classify.h' + clockh='include/linux/ptp_clock_kernel.h' + timekeepingh='include/linux/timekeeping.h' + uapih='include/uapi/linux/ptp_clock.h' + gen HAVE_PTP_CSID_X86_ART if enum clocksource_ids matches CSID_X86_ART in include/linux/clocksource_ids.h + gen NEED_PTP_CLASSIFY_RAW if fun ptp_classify_raw absent in "$classifyh" + gen NEED_PTP_PARSE_HEADER if fun ptp_parse_header absent in "$classifyh" + gen HAVE_PTP_CANCEL_WORKER_SYNC if fun ptp_cancel_worker_sync in "$clockh" + gen HAVE_PTP_CLOCK_DO_AUX_WORK if method do_aux_work of ptp_clock_info in "$clockh" + gen HAVE_PTP_CLOCK_INFO_ADJFINE if method adjfine of ptp_clock_info in "$clockh" + gen HAVE_PTP_CLOCK_INFO_GETTIME64 if method gettime64 of ptp_clock_info in "$clockh" + gen HAVE_PTP_CLOCK_INFO_GETTIMEX64 if method gettimex64 of ptp_clock_info in "$clockh" + gen HAVE_PTP_FIND_PIN_UNLOCKED if fun ptp_find_pin_unlocked in "$clockh" + gen HAVE_PTP_SUPPORTED_EXTTS_FLAGS if struct ptp_clock_info matches supported_extts_flags in "$clockh" + gen HAVE_PTP_SUPPORTED_PEROUT_FLAGS if struct ptp_clock_info matches supported_perout_flags in "$clockh" + gen NEED_DIFF_BY_SCALED_PPM if fun diff_by_scaled_ppm absent in "$clockh" + gen NEED_PTP_SYSTEM_TIMESTAMP if fun ptp_read_system_prets absent in "$clockh" + gen HAVE_PTP_SYS_COUNTERVAL_CSID if struct system_counterval_t matches clocksource_ids in "$timekeepingh" + gen HAVE_PTP_TX_ONESTEP_P2P if enum hwtstamp_tx_types matches HWTSTAMP_TX_ONESTEP_P2P in include/uapi/linux/net_tstamp.h + gen HAVE_PTP_SYS_OFFSET_EXTENDED_IOCTL if macro PTP_SYS_OFFSET_EXTENDED in "$uapih" + + # aarch64 requires additional function to enable cross timestamping + if config_has CONFIG_ARM64 && + (check fun arch_timer_wrap_counter in include/clocksource/arm_arch_timer.h || + check struct system_counterval_t matches clocksource_ids in "$timekeepingh") ; then + HAVE_CROSS_TSTAMP=1 + elif config_has CONFIG_X86 && + (check fun convert_art_ns_to_tsc in arch/x86/include/asm/tsc.h || + check enum clocksource_ids matches CSID_X86_ART in include/linux/clocksource_ids.h) ; then + HAVE_CROSS_TSTAMP=1 + else + HAVE_CROSS_TSTAMP=0 + fi + gen HAVE_PTP_CROSSTIMESTAMP if string "${HAVE_CROSS_TSTAMP}" equals 1 +} + +function gen-stddef() { + stddef='include/linux/stddef.h' + ustddef='include/uapi/linux/stddef.h' + gen HAVE_STDDEF_OFFSETTOEND if macro offsetofend in "$stddef" + gen NEED_DECLARE_FLEX_ARRAY if macro DECLARE_FLEX_ARRAY absent in "$stddef" + gen NEED_STRUCT_GROUP if macro struct_group absent in "$stddef" + gen NEED___STRUCT_GROUP if macro __struct_group absent in "$ustddef" +} + +function gen-vdcm() { + gen NEED_EVENTFD_SIGNAL_NO_COUNTER if fun eventfd_signal matches '__u64 n' in include/linux/eventfd.h +} + +function gen-vfio() { + # PASID_SUPPORT depends on multiple different functions existing + PASID_SUPPORT=0 + if check fun mdev_set_iommu_device in include/linux/mdev.h && + check fun vfio_group_iommu_domain in include/linux/vfio.h ; then + PASID_SUPPORT=1 + fi + gen HAVE_PASID_SUPPORT if string "${PASID_SUPPORT}" equals 1 + + gen HAVE_VFIO_FREE_DEV if fun vfio_free_device in include/linux/vfio.h + gen HAVE_LMV1_SUPPORT if macro VFIO_REGION_TYPE_MIGRATION in include/uapi/linux/vfio.h +} + +function gen-other() { + pciaerh='include/linux/aer.h' + ush='include/linux/u64_stats_sync.h' + fsh='include/linux/fortify-string.h' + cth='include/linux/compiler_types.h' + gen HAVE_X86_STEPPING if struct cpuinfo_x86 matches x86_stepping in arch/x86/include/asm/processor.h + gen HAVE_PCI_ENABLE_PCIE_ERROR_REPORTING if fun pci_enable_pcie_error_reporting in "$pciaerh" + gen NEED_PCI_AER_CLEAR_NONFATAL_STATUS if fun pci_aer_clear_nonfatal_status absent in "$pciaerh" + gen NEED_BITMAP_COPY_CLEAR_TAIL if fun bitmap_copy_clear_tail absent in include/linux/bitmap.h + gen NEED_BITMAP_FROM_ARR32 if fun bitmap_from_arr32 absent in include/linux/bitmap.h + gen NEED_BITMAP_TO_ARR32 if fun bitmap_to_arr32 absent in include/linux/bitmap.h + gen NEED_ASSIGN_BIT if fun assign_bit absent in include/linux/bitops.h + gen NEED_STATIC_ASSERT if macro static_assert absent in include/linux/build_bug.h + # special case for kernels 6.2 - 6.6 and __struct_size macro + # there is an implicit dependency on CONFIG_FORTIFY_SOURCE config option and inclusion + # of 'forify-string.h' header (which includes that macro definition). + __STRUCT_SIZE_NEEDED=0 + if ! config_has CONFIG_FORTIFY_SOURCE && check macro __struct_size in "$fsh" ; then + __STRUCT_SIZE_NEEDED=1 + fi + if [ ${__STRUCT_SIZE_NEEDED} -eq 0 ] && check macro __struct_size absent in "$cth" "$fsh"; then + __STRUCT_SIZE_NEEDED=1 + fi + gen NEED___STRUCT_SIZE if string "${__STRUCT_SIZE_NEEDED}" equals 1 + gen HAVE_COMPLETION_RAW_SPINLOCK if struct completion matches 'struct swait_queue_head' in include/linux/completion.h + gen NEED_IS_CONSTEXPR if macro __is_constexpr absent in include/linux/const.h include/linux/minmax.h include/linux/kernel.h + gen NEED_DEBUGFS_LOOKUP if fun debugfs_lookup absent in include/linux/debugfs.h + gen NEED_DEBUGFS_LOOKUP_AND_REMOVE if fun debugfs_lookup_and_remove absent in include/linux/debugfs.h + gen NEED_DIM_END_SAMPLE_BY_POINTER if fun net_dim matches 'struct dim_sample end_sample' in include/linux/dim.h + gen NEED_ETH_GET_HEADLEN if fun eth_get_headlen absent in include/linux/etherdevice.h + gen NEED_ETH_GET_HEADLEN_NET_DEVICE_ARG if fun eth_get_headlen lacks 'struct net_device \\*' in include/linux/etherdevice.h + gen NEED_ETH_HW_ADDR_SET if fun eth_hw_addr_set absent in include/linux/etherdevice.h + gen NEED_FIND_NEXT_BIT_WRAP if fun find_next_bit_wrap absent in include/linux/find.h + gen HAVE_FILE_IN_SEQ_FILE if struct seq_file matches 'struct file' in include/linux/fs.h + gen NEED_FS_FILE_DENTRY if fun file_dentry absent in include/linux/fs.h + gen HAVE_HWMON_DEVICE_REGISTER_WITH_INFO if fun hwmon_device_register_with_info in include/linux/hwmon.h + gen NEED_HWMON_CHANNEL_INFO if macro HWMON_CHANNEL_INFO absent in include/linux/hwmon.h + gen NEED_ETH_TYPE_VLAN if fun eth_type_vlan absent in include/linux/if_vlan.h + gen HAVE_IOMMU_DEV_FEAT_AUX if enum iommu_dev_features matches IOMMU_DEV_FEAT_AUX in include/linux/iommu.h + gen NEED_READ_POLL_TIMEOUT if macro read_poll_timeout absent in include/linux/iopoll.h + gen NEED_READ_POLL_TIMEOUT_ATOMIC if macro read_poll_timeout_atomic absent in include/linux/iopoll.h + gen NEED_DEFINE_STATIC_KEY_FALSE if macro DEFINE_STATIC_KEY_FALSE absent in include/linux/jump_label.h + gen NEED_STATIC_BRANCH_LIKELY if macro static_branch_likely absent in include/linux/jump_label.h + gen HAVE_STRUCT_STATIC_KEY_FALSE if struct static_key_false in include/linux/jump_label.h include/linux/jump_label_type.h + gen NEED_DECLARE_STATIC_KEY_FALSE if macro DECLARE_STATIC_KEY_FALSE absent in include/linux/jump_label.h include/linux/jump_label_type.h + gen NEED_LOWER_16_BITS if macro lower_16_bits absent in include/linux/kernel.h + gen NEED_UPPER_16_BITS if macro upper_16_bits absent in include/linux/kernel.h + gen HAVE_LINKMODE if fun linkmode_zero in include/linux/linkmode.h + gen NEED_LINKMODE_SET_BIT_ARRAY if fun linkmode_set_bit_array absent in include/linux/linkmode.h + gen NEED_LINKMODE_ZERO if fun linkmode_zero absent in include/linux/linkmode.h + gen NEED_LIST_COUNT_NODES if fun list_count_nodes absent in include/linux/list.h + + # On aarch64 RHEL systems, mul_u64_u64_div_u64 appears to be declared + # in math64 header, but is not provided by kernel + # so on these systems, set it to need anyway. + NEED_MUL_U64=0 + if [ "$IS_ARM" ] || check fun mul_u64_u64_div_u64 absent in include/linux/math64.h ; then + NEED_MUL_U64=1 + fi + gen NEED_MUL_U64_U64_DIV_U64 if string "${NEED_MUL_U64}" equals 1 + + gen NEED_DIV_U64_ROUND_CLOSEST if macro DIV_U64_ROUND_CLOSEST absent in include/linux/math64.h + gen NEED_DIV_U64_ROUND_UP if macro DIV_U64_ROUND_UP absent in include/linux/math64.h + gen NEED_ROUNDUP_U64 if fun roundup_u64 absent in include/linux/math64.h + gen HAVE_MDEV_GET_DRVDATA if fun mdev_get_drvdata in include/linux/mdev.h + gen HAVE_MDEV_REGISTER_PARENT if fun mdev_register_parent in include/linux/mdev.h + gen HAVE_VM_FLAGS_API if fun vm_flags_init in include/linux/mm.h + gen HAVE_NL_SET_ERR_MSG_FMT if macro NL_SET_ERR_MSG_FMT in include/linux/netlink.h + gen NEED_DEV_PM_DOMAIN_ATTACH if fun dev_pm_domain_attach absent in include/linux/pm_domain.h include/linux/pm.h + gen NEED_DEV_PM_DOMAIN_DETACH if fun dev_pm_domain_detach absent in include/linux/pm_domain.h include/linux/pm.h + gen NEED_RADIX_TREE_EMPTY if fun radix_tree_empty absent in include/linux/radix-tree.h + gen HAVE_LINUX_REFCOUNT_HEADER if fun refcount_inc in include/linux/refcount.h + gen NEED_SCHED_PARAM if struct sched_param absent in include/linux/sched.h + gen NEED_SET_SCHED_FIFO if fun sched_set_fifo absent in include/linux/sched.h + gen NEED_RT_H if macro MAX_RT_PRIO absent in include/linux/sched/prio.h + gen HAVE_SKB_CSUM_IS_SCTP if fun skb_csum_is_sctp in include/linux/skbuff.h + gen NEED_DEV_PAGE_IS_REUSABLE if fun dev_page_is_reusable absent in include/linux/skbuff.h + gen NEED_NAPI_ALLOC_SKB if fun __napi_alloc_skb in include/linux/skbuff.h + gen NEED_NAPI_BUILD_SKB if fun napi_build_skb absent in include/linux/skbuff.h + gen NEED_SKB_FRAG_OFF if fun skb_frag_off absent in include/linux/skbuff.h + gen NEED_SKB_FRAG_OFF_ADD if fun skb_frag_off_add absent in include/linux/skbuff.h + gen NEED_SYSFS_MATCH_STRING if macro sysfs_match_string absent in include/linux/string.h + gen HAVE_STRING_CHOICES_H if fun str_enabled_disabled in include/linux/string_choices.h + gen NEED_STR_ENABLED_DISABLED if fun str_enabled_disabled absent in include/linux/string_choices.h include/linux/string_helpers.h + gen HAVE_STRING_HELPERS_H if enum string_size_units in include/linux/string_helpers.h + gen NEED_SYSFS_EMIT if fun sysfs_emit absent in include/linux/sysfs.h + gen HAVE_NON_CONST_CYCLECOUNTER if method read of cyclecounter lacks const in include/linux/timecounter.h + gen NEED_TIMER_CONTAINER_OF if macro timer_container_of absent in include/linux/timer.h + gen NEED_TIMER_DELETE if fun timer_delete absent in include/linux/timer.h + gen HAVE_TRACE_ENABLED_SUPPORT if implementation of macro __DECLARE_TRACE matches 'trace_##name##_enabled' in include/linux/tracepoint.h + gen HAVE_TTY_OP_WRITE_SIZE_T if method write of tty_operations matches size_t in include/linux/tty_driver.h + gen HAVE_U64_STATS_FETCH_BEGIN_IRQ if fun u64_stats_fetch_begin_irq in "$ush" + gen HAVE_U64_STATS_FETCH_RETRY_IRQ if fun u64_stats_fetch_retry_irq in "$ush" + gen NEED_U64_STATS_READ if fun u64_stats_read absent in "$ush" + gen NEED_U64_STATS_SET if fun u64_stats_set absent in "$ush" + gen HAVE_XARRAY_API if macro DEFINE_XARRAY in include/linux/xarray.h + gen HAVE_TC_FLOWER_ENC if enum flow_dissector_key_id matches FLOW_DISSECTOR_KEY_ENC_CONTROL in include/net/flow_dissector.h + gen HAVE_TC_FLOWER_VLAN_IN_TAGS if enum flow_dissector_key_id matches FLOW_DISSECTOR_KEY_VLANID in include/net/flow_dissector.h + gen HAVE_NET_RPS_H if macro RPS_NO_FILTER in include/net/rps.h + gen HAVE_UDP_TUNNEL_NIC_INFO_MAY_SLEEP if enum udp_tunnel_nic_info_flags matches UDP_TUNNEL_NIC_INFO_MAY_SLEEP in include/net/udp_tunnel.h + gen NEED_XDP_CONVERT_BUFF_TO_FRAME if fun xdp_convert_buff_to_frame absent in include/net/xdp.h + gen NEED_XSK_BUFF_DMA_SYNC_FOR_CPU_NO_POOL if fun xsk_buff_dma_sync_for_cpu matches 'struct xsk_buff_pool' in include/net/xdp_sock_drv.h + gen HAVE_ASSIGN_STR_2_PARAMS if macro __assign_str matches src in include/trace/stages/stage6_event_callback.h include/trace/trace_events.h include/trace/ftrace.h + + HAVE_LINUX_UNALIGNED=0 + if [ -n "$(filter-out-bad-files include/linux/unaligned.h)" ]; then + HAVE_LINUX_UNALIGNED=1 + fi + gen HAVE_LINUX_UNALIGNED_HEADER if string "${HAVE_LINUX_UNALIGNED}" equals 1 + + HAVE_LINUX_BITS=0 + if [ -n "$(filter-out-bad-files include/linux/bits.h)" ]; then + HAVE_LINUX_BITS=1 + fi + gen HAVE_LINUX_BITS_HEADER if string "${HAVE_LINUX_BITS}" equals 1 + + HAVE_LINUX_REFCOUNT_TYPES=0 + if [ -n "$(filter-out-bad-files include/linux/refcount_types.h)" ]; then + HAVE_LINUX_REFCOUNT_TYPES=1 + fi + gen HAVE_LINUX_REFCOUNT_TYPES_HEADER if string "${HAVE_LINUX_REFCOUNT_TYPES}" equals 1 +} + +# all the generations, extracted from main() to keep normal code and various +# prep separated +function gen-all() { + if config_has CONFIG_NET_DEVLINK; then + gen-devlink + fi + gen-netdevice + # code above is covered by unit_tests/test_gold.sh + if [ -n "${JUST_UNIT_TESTING-}" ]; then + return + fi + gen-aux + gen-bitfield + gen-cleanup + gen-device + gen-devres + gen-dma + gen-dpll + gen-ethtool + gen-exported-symbols + gen-filter + gen-flow-dissector + gen-gnss + gen-mdev + gen-mdio + gen-mm + gen-netif + gen-packing + gen-pci + gen-ptp + gen-stddef + gen-vdcm + gen-vfio + gen-other +} + +function main() { + if ! [ -d "${KSRC-}" ]; then + echo >&2 "env KSRC=${KSRC-} does not exist or is not a directory" + exit 11 + fi + + # Assume KOBJ is the same as KSRC if not set. + if [ -z "${KOBJ-}" ]; then + KOBJ="${KSRC-}" + fi + + # we need some flags from .config or (autoconf.h), try to find it + if [ -z "${CONFIG_FILE-}" ]; then + find_config_file + + if [ -z ${CONFIG_FILE-} ]; then + echo >&2 "unable to locate a config file at KOBJ=${KOBJ}. please set CONFIG_FILE to the kernel configuration file." + exit 10 + fi + fi + + if [ ! -f "${CONFIG_FILE-}" ]; then + echo >&2 ".config passed in by env CONFIG_FILE=${CONFIG_FILE} does not exist or is not a file" + exit 9 + fi + CONFIG_FILE=$(realpath "${CONFIG_FILE-}") + + # check if caller (like our makefile) wants to redirect output to file + if [ -n "${OUT-}" ]; then + + # in case OUT exists, we don't want to overwrite it, instead + # write to a temporary copy. + if [ -s "${OUT}" ]; then + TMP_OUT="$(mktemp "${OUT}.XXX")" + trap "rm -f '${TMP_OUT}'" EXIT + + REAL_OUT="${OUT}" + OUT="${TMP_OUT}" + fi + + exec > "$OUT" + # all stdout goes to OUT since now + echo "/* Autogenerated for KSRC=${KSRC-} via $(basename "$0") */" + fi + + cd "${KSRC}" + + # check if KSRC was ok/if we are in proper place to look for headers + if [ -z "$(filter-out-bad-files include/linux/kernel.h)" ]; then + echo >&2 "seems that there are no kernel includes placed in KSRC=${KSRC} + pwd=$(pwd); ls -l:" + ls -l >&2 + exit 8 + fi + + if [ -z ${UNIFDEF_MODE-} ]; then + echo "#ifndef _KCOMPAT_GENERATED_DEFS_H_" + echo "#define _KCOMPAT_GENERATED_DEFS_H_" + fi + + gen-all + + if [ -z ${UNIFDEF_MODE-} ]; then + echo "#endif /* _KCOMPAT_GENERATED_DEFS_H_ */" + fi + + if [ -n "${OUT-}" ]; then + cd "$ORIG_CWD" + + # Compare and see if anything changed. This avoids updating + # mtime of the file. + if [ -n "${REAL_OUT-}" ]; then + if cmp --silent "${REAL_OUT}" "${TMP_OUT}"; then + # exit now, skipping print of the output since + # there were no changes. the trap should + # cleanup TMP_OUT + exit 0 + fi + + mv -f "${TMP_OUT}" "${REAL_OUT}" + OUT="${REAL_OUT}" + fi + + # dump output, will be visible in CI + if [ -n "${JUST_UNIT_TESTING-}${QUIET_COMPAT-}" ]; then + return + fi + cat -n "$OUT" >&2 + fi +} + +main + +# Coding style: +# - rely on `set -e` handling as much as possible, so: +# - do not use <(bash process substitution) - it breaks error handling; +# - do not put substantial logic in `if`-like statement - it disables error +# handling inside of the conditional (`if big-fun call; then` is substantial) +# - make shellcheck happy - https://www.shellcheck.net +# +# That enables us to move processing out of `if` or `... && ...` statements, +# what finally means that bash error handling (`set -e`) would break on errors. diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-lib.sh b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-lib.sh new file mode 100644 index 0000000000..b54d656601 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat-lib.sh @@ -0,0 +1,490 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 1999 - 2026 Intel Corporation + +# to be sourced + +# General shell helpers + +# exit with non-zero exit code; if there is only one param: +# exit with msg $1 and exit code from last command (or 99 if = 0) +# otherwise, exit with $1 and use remaining arguments as msg +function die() { + rc=$? + if [ $# -gt 1 ]; then + rc="$1" + shift + fi + [ "$rc" -ne 0 ] || rc=99 + echo >&2 "$@" + exit $rc +} + +# filter out paths that are not files +# input $@, output via echo; +# note: pass `-` for stdin +# note: outputs nothing if all input files are "bad" (eg. not existing), but it +# is left for caller to decide if this is an erorr condition; +# note: whitespaces are considered "bad" as part of filename, it's an error. +function filter-out-bad-files() { + if [[ $# = 1 && "$1" = '-' ]]; then + echo - + return 0 + fi + if [ $# = 0 ]; then + die 10 "no files passed, use '-' when reading from pipe (|)" + fi + local any=0 diagmsgs=/dev/stderr re=$'[\t \n]' + [ -n "${QUIET_COMPAT-}" ] && diagmsgs=/dev/null + for x in "$@"; do + if [ -e "$x" ]; then + if [[ "$x" =~ $re ]]; then + die 11 "err: filename contains whitespaces: $x." + fi + echo "$x" + any=1 + else + echo >&"$diagmsgs" filtering "$x" out + fi + done + if [ $any = 0 ]; then + echo >&"$diagmsgs" 'all files (for given query) filtered out' + fi +} + +# Basics of regexp explained, as a reference for mostly-C programmers: +# (bash) "regexp-$VAR-regexp" - bash' VARs are placed into "QUOTED" strings +# /\);?$/ - match end of function declaration, $ is end of string +# ^[ \t]* - (heuristic), anything but comment, eg to exclude function docs +# /STH/, /END/ - (awk), print all lines sice STH matched, up to END, inclusive + +# "Whitespace only" +WB='[ \t\n]' + +# Helpers below print the thing that is looked for, for further grep'ping/etc. +# That simplifies process of excluding comments or spares us state machine impl. +# +# We take advantage of current/common linux codebase formatting here. +# +# Functions in this section require input file/s passed as args +# (usually one, but more could be supplied in case of renames in kernel), +# '-' could be used as an (only) file argument to read from stdin/pipe. + +# wrapper over find-something-decl() functions below, to avoid repetition +# pass $what as $1, $end as $2, and $files to look in as rest of args +function find-decl() { + test $# -ge 3 # ensure that there are at least 3 params + local what end files + what="$1" + end="$2" + shift 2 + files="$(filter-out-bad-files "$@")" || die + if [ -z "$files" ]; then + return 0 + fi + # shellcheck disable=SC2086 + awk " + /^$WB*\*/ {next} + $what, $end + " $files +} + +# yield $1 function declaration (signature), don't pass return type in $1 +# looks only in files specified ($2, $3...) +function find-fun-decl() { + test $# -ge 2 + local what end + what="/$WB*([(]\*)?$1$WB*($|[()])/" + end='/\);?$/' + shift + find-decl "$what" "$end" "$@" +} + +# yield $1 enum declaration (type/body) +function find-enum-decl() { + test $# -ge 2 + local what end + what="/^$WB*enum$WB+$1"' \{$/' + end='/\};$/' + shift + find-decl "$what" "$end" "$@" +} + +# yield anonymous enum declaration (type/body) +function find-anon-enum-decl() { + test $# -ge 2 + local what end + what="/^$WB*enum$WB+"'\{$/' + end='/\};$/' + shift + find-decl "$what" "$end" "$@" +} + +# yield $1 struct declaration (type/body) +function find-struct-decl() { + test $# -ge 2 + local what end + what="/^$WB*struct$WB+$1"' \{$/' + end='/^\};$/' # that's (^) different from enum-decl + shift + find-decl "$what" "$end" "$@" +} + +# yield first line of $1 macro definition +function find-macro-decl() { + test $# -ge 2 + local what end + # only unindented defines, only whole-word match + what="/^#define$WB+$1"'([ \t\(]|$)/' + end=1 # only first line; use find-macro-implementation-decl for full body + shift + find-decl "$what" "$end" "$@" +} + +# yield full macro implementation +function find-macro-implementation-decl() { + test $# -ge 2 + local what end + # only unindented defines, only whole-word match + what="/^#define$WB+$1"'([ \t\(]|$)/' + # full implementation, until a line not ending in a backslash. + # Does not handle macros with comments embedded within the definition. + end='/[^\\]$/' + shift + find-decl "$what" "$end" "$@" +} + +# yield all first lines of $1 macro invocations, +# heuristic for DEFINE_GUARD()-like macros +function find-macro-invocation-decl() { + test $# -ge 2 + local what end + # only unindented defines, only whole-word match, with opening brace + # on the first line + what="/^${1}$WB*\(/" + end=1 # only first line + shift + find-decl "$what" "$end" "$@" +} + +# yield first line of $1 typedef definition +# This only handles typedefs where the name is on first line +function find-typedef-decl() { + test $# -ge 2 + local what end + # Assumes type name is followed by other ')', '(', or ';', or + # whitespace + what="/^typedef$WB.*$1"'[\(\); \t\n]/' + end='/;$/' + shift + find-decl "$what" "$end" "$@" +} + +# yield symbol line from Module.symvers +function find-symbol-decl() { + test $# -ge 2 + local what end + what="/^0x[0-9a-f]+\t$1\t/" + end=1 # only one line + shift + find-decl "$what" "$end" "$@" +} + +# gen() - DSL-like function to wrap around all the other +# +# syntax: +# gen DEFINE if (KIND [METHOD of]) NAME [(matches|lacks) PATTERN|absent] in +# gen DEFINE if string "actual" equals "expected" + +# where: +# DEFINE is HAVE_ or NEED_ #define to print; +# `if` is there to just read it easier and made syntax easier to check; +# +# NAME is the name for what we are looking for; +# +# `if string` can be used to check if a provided string matches an expected +# value. The define will only be generated if the strings are exactly +# equal. Otherwise, the define will not be generated. When operating in +# UNIFDEF_MODE, -DDEFINE is output when the strings are equal, while +# -UDEFINE is output when the strings are not equal. This is intended +# for cases where a more complex conditional is required, such as +# generating a define when multiple different functions exist. +# +# Ex: +# +# FUNC1="$(find-fun-decl devlink_foo1 devlink.h)" +# FUNC2="$(find-fun-decl devlink_foo2 devlink.h)" +# gen HAVE_FOO_12 if string "${FUNC1:+1}${FUNC2:+1}" equals "11" +# +# KIND specifies what kind of declaration/definition we are looking for, +# could be: fun, enum, struct, method, macro, typedef, symbol, +# 'anonymous enum', or 'implementation of macro' +# for KIND=method, we are looking for function ptr named METHOD in struct +# named NAME (two optional args are then necessary (METHOD & of)); +# +# for KIND=symbol, we are looking for a symbol definition in the format of +# Module.symvers. To verify that the symbol is exported by a particular +# module, the matches syntax can be used. +# +# for KIND='anonymous enum' we are looking for all anonymous enum +# definitions (i.e. an enum without a name). This is usually combined with +# "matches" or "lacks" to check for a specific value in any anonymous enum +# within the files. Unlike other KINDs, 'anonymous enum' syntax does not +# include NAME. +# +# for KIND='implementation of macro' we are looking for the full +# implementation of the macro, not just its first line. This is usually +# combined with "matches" or "lacks". +# +# next [optional] args could be used: +# matches PATTERN - use to grep for the PATTERN within definition +# (eg, for ext_ack param) +# lacks - use to add #define only if there is no match of the PATTERN, +# *but* the NAME is *found* +# absent - the NAME that we grep for must be not found +# (ie: function not exisiting) +# +# without this optional params, behavior is the same as with +# `matches .` - use to grep just for existence of NAME; +# +# `in` is there to ease syntax, similar to `if` before. +# +# is just space-separate list of files to look in, +# single (-) for stdin. +# +# PATTERN is an awk pattern, will be wrapped by two slashes (/) +# +# The usual output is a list of "#define " lines for each flag that has +# a matched definition. When UNIFDEF_MODE is set to a non-zero string, the +# output is instead a sequence of "-D" for each matched definition, and +# "-U" for each definition which didn't match. +function gen() { + test $# -ge 4 || die 20 "too few arguments, $# given, at least 4 needed" + local define if_kw kind name in_kw # mandatory + local of_kw method_name operator pattern # optional + local src_line="${BASH_SOURCE[0]}:${BASH_LINENO[0]}" + define="$1" + if_kw="$2" + kind="$3" + local orig_args_cnt=$# + shift 3 + [ "$if_kw" != if ] && die 21 "$src_line: 'if' keyword expected, '$if_kw' given" + case "$kind" in + string) + local actual_str expect_str equals_kw missing_fmt found_fmt + + test $# -ge 3 || die 22 "$src_line: too few arguments, $orig_args_cnt given, at least 6 needed" + + actual_str="$1" + equals_kw="$2" + expect_str="$3" + shift 3 + + if [ -z ${UNIFDEF_MODE:+1} ]; then + found_fmt="#define %s 1\n" + missing_fmt="" + else + found_fmt="-D%s\n" + missing_fmt="-U%s\n" + fi + + if [ "${actual_str}" = "${expect_str}" ]; then + printf -- "$found_fmt" "$define" + else + printf -- "$missing_fmt" "$define" + fi + + return + ;; + anonymous) + test $# -ge 3 || die 22 "$src_line: too few arguments, $orig_args_cnt given, at least 6 needed" + anon_kind="$1" + name="" + shift + # Other anonymous matches may be added in the future. + [ "$anon_kind" != enum ] && die 31 "$src_line: anonymous checks do not work with '$anon_kind'" + kind="anon-$anon_kind" + ;; + fun|enum|struct|macro|typedef|symbol) + test $# -ge 3 || die 22 "$src_line: too few arguments, $orig_args_cnt given, at least 6 needed" + name="$1" + shift + ;; + method) + test $# -ge 5 || die 22 "$src_line: too few arguments, $orig_args_cnt given, at least 8 needed" + method_name="$1" + of_kw="$2" + name="$3" + shift 3 + [ "$of_kw" != of ] && die 23 "$src_line: 'of' keyword expected, '$of_kw' given" + ;; + implementation) + test $# -ge 5 || die 28 "$src_line: too few arguments, $orig_args_cnt given, at least 8 needed" + of_kw="$1" + kind="$2" + name="$3" + shift 3 + [ "$of_kw" != of ] && die 29 "$src_line: 'of' keyword expected, '$of_kw' given" + [ "$kind" != macro ] && die 30 "$src_line: implementation only supports 'macro', '$kind' given" + kind=macro-implementation + ;; + invocation) + test $# -ge 5 || die 32 "$src_line: too few arguments, $orig_args_cnt given, at least 8 needed" + of_kw="$1" + kind="$2" + name="$3" + shift 3 + [ "$of_kw" != of ] && die 33 "$src_line: 'of' keyword expected, '$of_kw' given" + [ "$kind" != macro ] && die 34 "$src_line: invocation only supports 'macro', '$kind' given" + kind=macro-invocation + ;; + *) die 24 "$src_line: unknown KIND ($kind) to look for" ;; + esac + operator="$1" + case "$operator" in + absent) + local next_kw next_op + next_kw="$2" + in_kw="$next_kw" + next_op="$3" + if [[ "$next_kw" = or && "$next_op" = lacks ]]; then + # intentionally keeping $operator as 'absent'... + # but setting 'pattern' to something (not just '.') + shift 3 + test $# -ge 3 || die 39 "$src_line: too few parameters following 'absent or lacks' operator composition, pattern, 'in' keyword and filename needed" + pattern="$1" + in_kw="$2" + else + pattern='.' + fi + shift 2 + ;; + matches|lacks) + pattern="$2" + in_kw="$3" + shift 3 + ;; + in) + operator=matches + pattern='.' + in_kw=in + shift + ;; + *) die 25 "$src_line: unknown OPERATOR ($operator) to look for" ;; + esac + [ "$in_kw" != in ] && die 26 "$src_line: 'in' keyword expected, '$in_kw' given" + test $# -ge 1 || die 27 "$src_line: too few arguments, at least one filename expected" + + local first_decl= + if [ "$kind" = method ]; then + first_decl="$(find-struct-decl "$name" "$@")" || exit 40 + # prepare params for next lookup phase + set -- - # overwrite $@ to be single dash (-) + name="$method_name" + kind=fun + elif [[ $# = 1 && "$1" = '-' ]]; then + # avoid losing stdin provided to gen() due to redirection (<<<) + first_decl="$(cat -)" + fi + + local unifdef + unifdef=${UNIFDEF_MODE:+1} + + # lookup the NAME + local body + body="$(find-$kind-decl "$name" "$@" <<< "$first_decl")" || exit 41 + awk -v define="$define" -v pattern="$pattern" -v "$operator"=1 -v unifdef="$unifdef" ' + BEGIN { + # prepend "identifier boundary" to pattern, also append + # it, but only for patterns not ending with such already + # + # eg: "foo" -> "\bfoo\b" + # "struct foo *" -> "\bstruct foo *" + + # Note that mawk does not support "\b", so we have our + # own approximation, NI + NI = "[^A-Za-z0-9_]" # "Not an Indentifier" + + if (!match(pattern, NI "$")) + pattern = pattern "(" NI "|$)" + pattern = "(^|" NI ")" pattern + } + /./ { not_empty = 1 } + $0 ~ pattern { found = 1 } + END { + if (unifdef) { + found_fmt="-D%s\n" + missing_fmt="-U%s\n" + } else { + found_fmt="#define %s 1\n" + missing_fmt="" + } + + if (lacks && !found && not_empty || matches && found || absent && !found) + printf(found_fmt, define) + else if (missing_fmt) + printf(missing_fmt, define) + } + ' <<< "$body" +} + +# check() - Like gen, but return true/false instead of generating output +# +# syntax: +# See gen(), except do not pass a DEFINE name, or the action keyword. +function check() { + # Always run check in unifdef mode + local UNIFDEF_MODE=1 + + [[ "$(gen CHECK if "$@")" = "-DCHECK" ]] +} + +# tell if given flag is enabled in .config +# return 0 if given flag is enabled, 1 otherwise +# inputs: +# $1 - flag to check (whole word, without _MODULE suffix) +# env flag $CONFIG_FILE +# +# there are two "config" formats supported, to ease up integrators lifes +# .config (without leading #~ prefix): +#~ # CONFIG_ACPI_EC_DEBUGFS is not set +#~ CONFIG_ACPI_AC=y +#~ CONFIG_ACPI_VIDEO=m +# and autoconf.h, which would be: +#~ #define CONFIG_ACPI_AC 1 +#~ #define CONFIG_ACPI_VIDEO_MODULE 1 +function config_has() { + grep -qE "^(#define )?$1((_MODULE)? 1|=m|=y)$" "$CONFIG_FILE" +} + +# try to locate a suitable config file from KOBJ +# +# On success, the CONFIG_FILE variable will be updated to reflect the full +# path to a configuration file. +# +# Depends on KSRC being set +function find_config_file() { + local -a CSP + local file + local diagmsgs=/dev/stderr + + [ -n "${QUIET_COMPAT-}" ] && diagmsgs=/dev/null + + if ! [ -d "${KSRC-}" ]; then + return + fi + + CSP=( + "$KOBJ/include/generated/autoconf.h" + "$KOBJ/include/linux/autoconf.h" + "$KOBJ/.config" + ) + + for file in "${CSP[@]}"; do + if [ -f $file ]; then + echo >&"$diagmsgs" "using CONFIG_FILE=$file" + CONFIG_FILE=$file + return + fi + done +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.c new file mode 100644 index 0000000000..2d7aa1ac16 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.c @@ -0,0 +1,3003 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#include "ixgbe.h" +#include "kcompat.h" + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) ) || defined __VMKLNX__ +/* From lib/vsprintf.c */ +#include + +static int skip_atoi(const char **s) +{ + int i=0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define _kc_ZEROPAD 1 /* pad with zero */ +#define _kc_SIGN 2 /* unsigned/signed long */ +#define _kc_PLUS 4 /* show plus */ +#define _kc_SPACE 8 /* space if plus */ +#define _kc_LEFT 16 /* left justified */ +#define _kc_SPECIAL 32 /* 0x */ +#define _kc_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type) +{ + char c,sign,tmp[66]; + const char *digits; + const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i; + + digits = (type & _kc_LARGE) ? large_digits : small_digits; + if (type & _kc_LEFT) + type &= ~_kc_ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & _kc_ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & _kc_SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & _kc_PLUS) { + sign = '+'; + size--; + } else if (type & _kc_SPACE) { + sign = ' '; + size--; + } + } + if (type & _kc_SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(_kc_ZEROPAD+_kc_LEFT))) { + while(size-->0) { + if (buf <= end) + *buf = ' '; + ++buf; + } + } + if (sign) { + if (buf <= end) + *buf = sign; + ++buf; + } + if (type & _kc_SPECIAL) { + if (base==8) { + if (buf <= end) + *buf = '0'; + ++buf; + } else if (base==16) { + if (buf <= end) + *buf = '0'; + ++buf; + if (buf <= end) + *buf = digits[33]; + ++buf; + } + } + if (!(type & _kc_LEFT)) { + while (size-- > 0) { + if (buf <= end) + *buf = c; + ++buf; + } + } + while (i < precision--) { + if (buf <= end) + *buf = '0'; + ++buf; + } + while (i-- > 0) { + if (buf <= end) + *buf = tmp[i]; + ++buf; + } + while (size-- > 0) { + if (buf <= end) + *buf = ' '; + ++buf; + } + return buf; +} + +int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + int len; + unsigned long long num; + int i, base; + char *str, *end, c; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + /* 'z' support added 23/7/1999 S.H. */ + /* 'z' changed to 'Z' --davidm 1/25/99 */ + + str = buf; + end = buf + size - 1; + + if (end < buf - 1) { + end = ((void *) -1); + size = end - buf + 1; + } + + for (; *fmt ; ++fmt) { + if (*fmt != '%') { + if (str <= end) + *str = *fmt; + ++str; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= _kc_LEFT; goto repeat; + case '+': flags |= _kc_PLUS; goto repeat; + case ' ': flags |= _kc_SPACE; goto repeat; + case '#': flags |= _kc_SPECIAL; goto repeat; + case '0': flags |= _kc_ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= _kc_LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (isdigit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & _kc_LEFT)) { + while (--field_width > 0) { + if (str <= end) + *str = ' '; + ++str; + } + } + c = (unsigned char) va_arg(args, int); + if (str <= end) + *str = c; + ++str; + while (--field_width > 0) { + if (str <= end) + *str = ' '; + ++str; + } + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = ""; + + len = strnlen(s, precision); + + if (!(flags & _kc_LEFT)) { + while (len < field_width--) { + if (str <= end) + *str = ' '; + ++str; + } + } + for (i = 0; i < len; ++i) { + if (str <= end) + *str = *s; + ++str; ++s; + } + while (len < field_width--) { + if (str <= end) + *str = ' '; + ++str; + } + continue; + + case 'p': + if ('M' == *(fmt+1)) { + str = get_mac(str, end, va_arg(args, unsigned char *)); + fmt++; + } else { + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= _kc_ZEROPAD; + } + str = number(str, end, + (unsigned long) va_arg(args, void *), + 16, field_width, precision, flags); + } + continue; + + case 'n': + /* FIXME: + * What does C99 say about the overflow case here? */ + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else if (qualifier == 'Z') { + size_t * ip = va_arg(args, size_t *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + if (str <= end) + *str = '%'; + ++str; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= _kc_LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= _kc_SIGN; + case 'u': + break; + + default: + if (str <= end) + *str = '%'; + ++str; + if (*fmt) { + if (str <= end) + *str = *fmt; + ++str; + } else { + --fmt; + } + continue; + } + if (qualifier == 'L') + num = va_arg(args, long long); + else if (qualifier == 'l') { + num = va_arg(args, unsigned long); + if (flags & _kc_SIGN) + num = (signed long) num; + } else if (qualifier == 'Z') { + num = va_arg(args, size_t); + } else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & _kc_SIGN) + num = (signed short) num; + } else { + num = va_arg(args, unsigned int); + if (flags & _kc_SIGN) + num = (signed int) num; + } + str = number(str, end, num, base, + field_width, precision, flags); + } + if (str <= end) + *str = '\0'; + else if (size > 0) + /* don't write out a null byte if the buf size is zero */ + *end = '\0'; + /* the trailing null byte doesn't count towards the total + * ++str; + */ + return str-buf; +} + +int _kc_snprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = _kc_vsnprintf(buf,size,fmt,args); + va_end(args); + return i; +} +#endif /* < 2.4.8 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) ) + +/**************************************/ +/* PCI DMA MAPPING */ + +#if defined(CONFIG_HIGHMEM) + +#ifndef PCI_DRAM_OFFSET +#define PCI_DRAM_OFFSET 0 +#endif + +u64 +_kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, + size_t size, int direction) +{ + return (((u64) (page - mem_map) << PAGE_SHIFT) + offset + + PCI_DRAM_OFFSET); +} + +#else /* CONFIG_HIGHMEM */ + +u64 +_kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, + size_t size, int direction) +{ + return pci_map_single(dev, (void *)page_address(page) + offset, size, + direction); +} + +#endif /* CONFIG_HIGHMEM */ + +void +_kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size, + int direction) +{ + return pci_unmap_single(dev, dma_addr, size, direction); +} + +#endif /* 2.4.13 => 2.4.3 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) ) + +/**************************************/ +/* PCI DRIVER API */ + +int +_kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask) +{ + if (!pci_dma_supported(dev, mask)) + return -EIO; + dev->dma_mask = mask; + return 0; +} + +int +_kc_pci_request_regions(struct pci_dev *dev, char *res_name) +{ + int i; + + for (i = 0; i < 6; i++) { + if (pci_resource_len(dev, i) == 0) + continue; + + if (pci_resource_flags(dev, i) & IORESOURCE_IO) { + if (!request_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) { + pci_release_regions(dev); + return -EBUSY; + } + } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) { + if (!request_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) { + pci_release_regions(dev); + return -EBUSY; + } + } + } + return 0; +} + +void +_kc_pci_release_regions(struct pci_dev *dev) +{ + int i; + + for (i = 0; i < 6; i++) { + if (pci_resource_len(dev, i) == 0) + continue; + + if (pci_resource_flags(dev, i) & IORESOURCE_IO) + release_region(pci_resource_start(dev, i), pci_resource_len(dev, i)); + + else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) + release_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i)); + } +} + +/**************************************/ +/* NETWORK DRIVER API */ + +struct net_device * +_kc_alloc_etherdev(int sizeof_priv) +{ + struct net_device *dev; + int alloc_size; + + alloc_size = sizeof(*dev) + sizeof_priv + IFNAMSIZ + 31; + dev = kzalloc(alloc_size, GFP_KERNEL); + if (!dev) + return NULL; + + if (sizeof_priv) + dev->priv = (void *) (((unsigned long)(dev + 1) + 31) & ~31); + dev->name[0] = '\0'; + ether_setup(dev); + + return dev; +} + +int +_kc_is_valid_ether_addr(u8 *addr) +{ + const char zaddr[6] = { 0, }; + + return !(addr[0] & 1) && memcmp(addr, zaddr, 6); +} + +#endif /* 2.4.3 => 2.4.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) ) + +int +_kc_pci_set_power_state(struct pci_dev *dev, int state) +{ + return 0; +} + +int +_kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable) +{ + return 0; +} + +#endif /* 2.4.6 => 2.4.3 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, + int off, int size) +{ + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + frag->page = page; + frag->page_offset = off; + frag->size = size; + skb_shinfo(skb)->nr_frags = i + 1; +} + +/* + * Original Copyright: + * find_next_bit.c: fallback find next bit implementation + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +/** + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + const unsigned long *p = addr + BITOP_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG-1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset %= BITS_PER_LONG; + if (offset) { + tmp = *(p++); + tmp &= (~0UL << offset); + if (size < BITS_PER_LONG) + goto found_first; + if (tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG-1)) { + if ((tmp = *(p++))) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= (~0UL >> (BITS_PER_LONG - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + ffs(tmp); +} + +size_t _kc_strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} + +#ifndef do_div +#if BITS_PER_LONG == 32 +uint32_t __attribute__((weak)) _kc__div64_32(uint64_t *n, uint32_t base) +{ + uint64_t rem = *n; + uint64_t b = base; + uint64_t res, d = 1; + uint32_t high = rem >> 32; + + /* Reduce the thing a bit first */ + res = 0; + if (high >= base) { + high /= base; + res = (uint64_t) high << 32; + rem -= (uint64_t) (high*base) << 32; + } + + while ((int64_t)b > 0 && b < rem) { + b = b+b; + d = d+d; + } + + do { + if (rem >= b) { + rem -= b; + res += d; + } + b >>= 1; + d >>= 1; + } while (d); + + *n = res; + return rem; +} +#endif /* BITS_PER_LONG == 32 */ +#endif /* do_div */ +#endif /* 2.6.0 => 2.4.6 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) +int _kc_scnprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vsnprintf(buf, size, fmt, args); + va_end(args); + return (i >= size) ? (size - 1) : i; +} +#endif /* < 2.6.4 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ) +DECLARE_BITMAP(_kcompat_node_online_map, MAX_NUMNODES) = {1}; +#endif /* < 2.6.10 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) ) +char *_kc_kstrdup(const char *s, unsigned int gfp) +{ + size_t len; + char *buf; + + if (!s) + return NULL; + + len = strlen(s) + 1; + buf = kmalloc(len, gfp); + if (buf) + memcpy(buf, s, len); + return buf; +} +#endif /* < 2.6.13 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ) +void *_kc_kzalloc(size_t size, int flags) +{ + void *ret = kmalloc(size, flags); + if (ret) + memset(ret, 0, size); + return ret; +} +#endif /* <= 2.6.13 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ) +int _kc_skb_pad(struct sk_buff *skb, int pad) +{ + int ntail; + + /* If the skbuff is non linear tailroom is always zero.. */ + if(!skb_cloned(skb) && skb_tailroom(skb) >= pad) { + memset(skb->data+skb->len, 0, pad); + return 0; + } + + ntail = skb->data_len + pad - (skb->end - skb->tail); + if (likely(skb_cloned(skb) || ntail > 0)) { + if (pskb_expand_head(skb, 0, ntail, GFP_ATOMIC)) + goto free_skb; + } + +#ifdef MAX_SKB_FRAGS + if (skb_is_nonlinear(skb) && + !__pskb_pull_tail(skb, skb->data_len)) + goto free_skb; + +#endif + memset(skb->data + skb->len, 0, pad); + return 0; + +free_skb: + kfree_skb(skb); + return -ENOMEM; +} + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4))) +int _kc_pci_save_state(struct pci_dev *pdev) +{ + struct adapter_struct *adapter = pci_get_drvdata(pdev); + int size = PCI_CONFIG_SPACE_LEN, i; + u16 pcie_cap_offset, pcie_link_status; + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) + /* no ->dev for 2.4 kernels */ + WARN_ON(pdev->dev.driver_data == NULL); +#endif + pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (pcie_cap_offset) { + if (!pci_read_config_word(pdev, + pcie_cap_offset + PCIE_LINK_STATUS, + &pcie_link_status)) + size = PCIE_CONFIG_SPACE_LEN; + } + pci_config_space_ich8lan(); +#ifdef HAVE_PCI_ERS + if (adapter->config_space == NULL) +#else + WARN_ON(adapter->config_space != NULL); +#endif + adapter->config_space = kmalloc(size, GFP_KERNEL); + if (!adapter->config_space) { + printk(KERN_ERR "Out of memory in pci_save_state\n"); + return -ENOMEM; + } + for (i = 0; i < (size / 4); i++) + pci_read_config_dword(pdev, i * 4, &adapter->config_space[i]); + return 0; +} + +void _kc_pci_restore_state(struct pci_dev *pdev) +{ + struct adapter_struct *adapter = pci_get_drvdata(pdev); + int size = PCI_CONFIG_SPACE_LEN, i; + u16 pcie_cap_offset; + u16 pcie_link_status; + + if (adapter->config_space != NULL) { + pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (pcie_cap_offset && + !pci_read_config_word(pdev, + pcie_cap_offset + PCIE_LINK_STATUS, + &pcie_link_status)) + size = PCIE_CONFIG_SPACE_LEN; + + pci_config_space_ich8lan(); + for (i = 0; i < (size / 4); i++) + pci_write_config_dword(pdev, i * 4, adapter->config_space[i]); +#ifndef HAVE_PCI_ERS + kfree(adapter->config_space); + adapter->config_space = NULL; +#endif + } +} +#endif /* !(RHEL_RELEASE_CODE >= RHEL 5.4) */ + +#ifdef HAVE_PCI_ERS +void _kc_free_netdev(struct net_device *netdev) +{ + struct adapter_struct *adapter = netdev_priv(netdev); + + kfree(adapter->config_space); +#ifdef CONFIG_SYSFS + if (netdev->reg_state == NETREG_UNINITIALIZED) { + kfree((char *)netdev - netdev->padded); + } else { + BUG_ON(netdev->reg_state != NETREG_UNREGISTERED); + netdev->reg_state = NETREG_RELEASED; + class_device_put(&netdev->class_dev); + } +#else + kfree((char *)netdev - netdev->padded); +#endif +} +#endif + +void *_kc_kmemdup(const void *src, size_t len, unsigned gfp) +{ + void *p; + + p = kzalloc(len, gfp); + if (p) + memcpy(p, src, len); + return p; +} +#endif /* <= 2.6.19 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ) +struct pci_dev *_kc_netdev_to_pdev(struct net_device *netdev) +{ + return ((struct adapter_struct *)netdev_priv(netdev))->pdev; +} +#endif /* < 2.6.21 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ) +/* hexdump code taken from lib/hexdump.c */ +static void _kc_hex_dump_to_buffer(const void *buf, size_t len, int rowsize, + int groupsize, unsigned char *linebuf, + size_t linebuflen, bool ascii) +{ + const u8 *ptr = buf; + u8 ch; + int j, lx = 0; + int ascii_column; + + if (rowsize != 16 && rowsize != 32) + rowsize = 16; + + if (!len) + goto nil; + if (len > rowsize) /* limit to one line at a time */ + len = rowsize; + if ((len % groupsize) != 0) /* no mixed size output */ + groupsize = 1; + + switch (groupsize) { + case 8: { + const u64 *ptr8 = buf; + int ngroups = len / groupsize; + + for (j = 0; j < ngroups; j++) + lx += scnprintf((char *)(linebuf + lx), linebuflen - lx, + "%s%16.16llx", j ? " " : "", + (unsigned long long)*(ptr8 + j)); + ascii_column = 17 * ngroups + 2; + break; + } + + case 4: { + const u32 *ptr4 = buf; + int ngroups = len / groupsize; + + for (j = 0; j < ngroups; j++) + lx += scnprintf((char *)(linebuf + lx), linebuflen - lx, + "%s%8.8x", j ? " " : "", *(ptr4 + j)); + ascii_column = 9 * ngroups + 2; + break; + } + + case 2: { + const u16 *ptr2 = buf; + int ngroups = len / groupsize; + + for (j = 0; j < ngroups; j++) + lx += scnprintf((char *)(linebuf + lx), linebuflen - lx, + "%s%4.4x", j ? " " : "", *(ptr2 + j)); + ascii_column = 5 * ngroups + 2; + break; + } + + default: + for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) { + ch = ptr[j]; + linebuf[lx++] = hex_asc(ch >> 4); + linebuf[lx++] = hex_asc(ch & 0x0f); + linebuf[lx++] = ' '; + } + if (j) + lx--; + + ascii_column = 3 * rowsize + 2; + break; + } + if (!ascii) + goto nil; + + while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) + linebuf[lx++] = ' '; + for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) + linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j] + : '.'; +nil: + linebuf[lx++] = '\0'; +} + +void _kc_print_hex_dump(const char *level, + const char *prefix_str, int prefix_type, + int rowsize, int groupsize, + const void *buf, size_t len, bool ascii) +{ + const u8 *ptr = buf; + int i, linelen, remaining = len; + unsigned char linebuf[200]; + + if (rowsize != 16 && rowsize != 32) + rowsize = 16; + + for (i = 0; i < len; i += rowsize) { + linelen = min(remaining, rowsize); + remaining -= rowsize; + _kc_hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, + linebuf, sizeof(linebuf), ascii); + + switch (prefix_type) { + case DUMP_PREFIX_ADDRESS: + printk("%s%s%*p: %s\n", level, prefix_str, + (int)(2 * sizeof(void *)), ptr + i, linebuf); + break; + case DUMP_PREFIX_OFFSET: + printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf); + break; + default: + printk("%s%s%s\n", level, prefix_str, linebuf); + break; + } + } +} + +#endif /* < 2.6.22 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) ) +int ixgbe_dcb_netlink_register(void) +{ + return 0; +} + +int ixgbe_dcb_netlink_unregister(void) +{ + return 0; +} + +int ixgbe_copy_dcb_cfg(struct ixgbe_adapter __always_unused *adapter, int __always_unused tc_max) +{ + return 0; +} +#endif /* < 2.6.23 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) +#ifdef NAPI +struct net_device *napi_to_poll_dev(const struct napi_struct *napi) +{ + struct adapter_q_vector *q_vector = container_of(napi, + struct adapter_q_vector, + napi); + return &q_vector->poll_dev; +} + +int __kc_adapter_clean(struct net_device *netdev, int *budget) +{ + int work_done; + int work_to_do = min(*budget, netdev->quota); + /* kcompat.h netif_napi_add puts napi struct in "fake netdev->priv" */ + struct napi_struct *napi = netdev->priv; + work_done = napi->poll(napi, work_to_do); + *budget -= work_done; + netdev->quota -= work_done; + return (work_done >= work_to_do) ? 1 : 0; +} +#endif /* NAPI */ +#endif /* <= 2.6.24 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ) +void _kc_pci_disable_link_state(struct pci_dev *pdev, int state) +{ + struct pci_dev *parent = pdev->bus->self; + u16 link_state; + int pos; + + if (!parent) + return; + + pos = pci_find_capability(parent, PCI_CAP_ID_EXP); + if (pos) { + pci_read_config_word(parent, pos + PCI_EXP_LNKCTL, &link_state); + link_state &= ~state; + pci_write_config_word(parent, pos + PCI_EXP_LNKCTL, link_state); + } +} +#endif /* < 2.6.26 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) ) +#ifdef HAVE_TX_MQ +void _kc_netif_tx_stop_all_queues(struct net_device *netdev) +{ + struct adapter_struct *adapter = netdev_priv(netdev); + int i; + + netif_stop_queue(netdev); + if (netif_is_multiqueue(netdev)) + for (i = 0; i < adapter->num_tx_queues; i++) + netif_stop_subqueue(netdev, i); +} +void _kc_netif_tx_wake_all_queues(struct net_device *netdev) +{ + struct adapter_struct *adapter = netdev_priv(netdev); + int i; + + netif_wake_queue(netdev); + if (netif_is_multiqueue(netdev)) + for (i = 0; i < adapter->num_tx_queues; i++) + netif_wake_subqueue(netdev, i); +} +void _kc_netif_tx_start_all_queues(struct net_device *netdev) +{ + struct adapter_struct *adapter = netdev_priv(netdev); + int i; + + netif_start_queue(netdev); + if (netif_is_multiqueue(netdev)) + for (i = 0; i < adapter->num_tx_queues; i++) + netif_start_subqueue(netdev, i); +} +#endif /* HAVE_TX_MQ */ + +void __kc_warn_slowpath(const char *file, int line, const char *fmt, ...) +{ + va_list args; + + printk(KERN_WARNING "------------[ cut here ]------------\n"); + printk(KERN_WARNING "WARNING: at %s:%d \n", file, line); + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + + dump_stack(); +} +#endif /* __VMKLNX__ */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ) + +int +_kc_pci_prepare_to_sleep(struct pci_dev *dev) +{ + pci_power_t target_state; + int error; + + target_state = pci_choose_state(dev, PMSG_SUSPEND); + + pci_enable_wake(dev, target_state, true); + + error = pci_set_power_state(dev, target_state); + + if (error) + pci_enable_wake(dev, target_state, false); + + return error; +} + +int +_kc_pci_wake_from_d3(struct pci_dev *dev, bool enable) +{ + int err; + + err = pci_enable_wake(dev, PCI_D3cold, enable); + if (err) + goto out; + + err = pci_enable_wake(dev, PCI_D3hot, enable); + +out: + return err; +} +#endif /* < 2.6.28 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ) +static void __kc_pci_set_main(struct pci_dev *pdev, bool enable) +{ + u16 old_cmd, cmd; + + pci_read_config_word(pdev, PCI_COMMAND, &old_cmd); + if (enable) + cmd = old_cmd | PCI_COMMAND_MASTER; + else + cmd = old_cmd & ~PCI_COMMAND_MASTER; + if (cmd != old_cmd) { + dev_dbg(pci_dev_to_dev(pdev), "%s bus DMA control\n", + enable ? "enabling" : "disabling"); + pci_write_config_word(pdev, PCI_COMMAND, cmd); + } +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) ) + pdev->is_busmaster = enable; +#endif +} + +void _kc_pci_clear_main(struct pci_dev *dev) +{ + __kc_pci_set_main(dev, false); +} +#endif /* < 2.6.29 */ + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) ) +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0)) +int _kc_pci_num_vf(struct pci_dev __maybe_unused *dev) +{ + int num_vf = 0; +#ifdef CONFIG_PCI_IOV + struct pci_dev *vfdev; + + /* loop through all ethernet devices starting at PF dev */ + vfdev = pci_get_class(PCI_CLASS_NETWORK_ETHERNET << 8, NULL); + while (vfdev) { + if (vfdev->is_virtfn && vfdev->physfn == dev) + num_vf++; + + vfdev = pci_get_class(PCI_CLASS_NETWORK_ETHERNET << 8, vfdev); + } + +#endif + return num_vf; +} +#endif /* RHEL_RELEASE_CODE */ +#endif /* < 2.6.34 */ + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) +#ifdef HAVE_TX_MQ +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0))) +#ifndef CONFIG_NETDEVICES_MULTIQUEUE +int _kc_netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) +{ + unsigned int real_num = dev->real_num_tx_queues; + struct Qdisc *qdisc; + int i; + + if (txq < 1 || txq > dev->num_tx_queues) + return -EINVAL; + + else if (txq > real_num) + dev->real_num_tx_queues = txq; + else if (txq < real_num) { + dev->real_num_tx_queues = txq; + for (i = txq; i < dev->num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc; + if (qdisc) { + spin_lock_bh(qdisc_lock(qdisc)); + qdisc_reset(qdisc); + spin_unlock_bh(qdisc_lock(qdisc)); + } + } + } + + return 0; +} +#endif /* CONFIG_NETDEVICES_MULTIQUEUE */ +#endif /* !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) */ +#endif /* HAVE_TX_MQ */ + +ssize_t _kc_simple_write_to_buffer(void *to, size_t available, loff_t *ppos, + const void __user *from, size_t count) +{ + loff_t pos = *ppos; + size_t res; + + if (pos < 0) + return -EINVAL; + if (pos >= available || !count) + return 0; + if (count > available - pos) + count = available - pos; + res = copy_from_user(to + pos, from, count); + if (res == count) + return -EFAULT; + count -= res; + *ppos = pos + count; + return count; +} + +#endif /* < 2.6.35 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ) +static const u32 _kc_flags_dup_features = + (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH); + +u32 _kc_ethtool_op_get_flags(struct net_device *dev) +{ + return dev->features & _kc_flags_dup_features; +} + +int _kc_ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) +{ + if (data & ~supported) + return -EINVAL; + + dev->features = ((dev->features & ~_kc_flags_dup_features) | + (data & _kc_flags_dup_features)); + return 0; +} +#endif /* < 2.6.36 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) ) +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0))) +#ifdef HAVE_NETDEV_SELECT_QUEUE +#include +#include + +u16 ___kc_skb_tx_hash(struct net_device *dev, const struct sk_buff *skb, + u16 num_tx_queues) +{ + u32 hash; + u16 qoffset = 0; + u16 qcount = num_tx_queues; + + if (skb_rx_queue_recorded(skb)) { + hash = skb_get_rx_queue(skb); + while (unlikely(hash >= num_tx_queues)) + hash -= num_tx_queues; + return hash; + } + + if (netdev_get_num_tc(dev)) { + struct adapter_struct *kc_adapter = netdev_priv(dev); + + if (skb->priority == TC_PRIO_CONTROL) { + qoffset = kc_adapter->dcb_tc - 1; + } else { + qoffset = skb->vlan_tci; + qoffset &= IXGBE_TX_FLAGS_VLAN_PRIO_MASK; + qoffset >>= 13; + } + + qcount = kc_adapter->ring_feature[RING_F_RSS].indices; + qoffset *= qcount; + } + + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else +#ifdef NETIF_F_RXHASH + hash = (__force u16) skb->protocol ^ skb->rxhash; +#else + hash = skb->protocol; +#endif + + hash = jhash_1word(hash, _kc_hashrnd); + + return (u16) (((u64) hash * qcount) >> 32) + qoffset; +} +#endif /* HAVE_NETDEV_SELECT_QUEUE */ + +u8 _kc_netdev_get_num_tc(struct net_device *dev) +{ + struct adapter_struct *kc_adapter = netdev_priv(dev); + if (kc_adapter->flags & IXGBE_FLAG_DCB_ENABLED) + return kc_adapter->dcb_tc; + else + return 0; +} + +int _kc_netdev_set_num_tc(struct net_device *dev, u8 num_tc) +{ + struct adapter_struct *kc_adapter = netdev_priv(dev); + + if (num_tc > IXGBE_DCB_MAX_TRAFFIC_CLASS) + return -EINVAL; + + kc_adapter->dcb_tc = num_tc; + + return 0; +} + +u8 _kc_netdev_get_prio_tc_map(struct net_device __maybe_unused *dev, u8 __maybe_unused up) +{ + struct adapter_struct *kc_adapter = netdev_priv(dev); + + return ixgbe_dcb_get_tc_from_up(&kc_adapter->dcb_cfg, 0, up); +} + +#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */ +#endif /* < 2.6.39 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) ) +void _kc_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, + int off, int size, unsigned int truesize) +{ + skb_fill_page_desc(skb, i, page, off, size); + skb->len += size; + skb->data_len += size; + skb->truesize += truesize; +} + +#if !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) +int _kc_simple_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} +#endif /* SLE_VERSION < 11,3,0 */ + +#endif /* < 3.4.0 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) ) +static inline int __kc_pcie_cap_version(struct pci_dev *dev) +{ + int pos; + u16 reg16; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return 0; + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); + return reg16 & PCI_EXP_FLAGS_VERS; +} + +static inline bool __kc_pcie_cap_has_devctl(const struct pci_dev __always_unused *dev) +{ + return true; +} + +static inline bool __kc_pcie_cap_has_lnkctl(struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + + return __kc_pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_ENDPOINT || + type == PCI_EXP_TYPE_LEG_END; +} + +static inline bool __kc_pcie_cap_has_sltctl(struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + int pos; + u16 pcie_flags_reg; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return false; + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &pcie_flags_reg); + + return __kc_pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + (type == PCI_EXP_TYPE_DOWNSTREAM && + pcie_flags_reg & PCI_EXP_FLAGS_SLOT); +} + +static inline bool __kc_pcie_cap_has_rtctl(struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + + return __kc_pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_RC_EC; +} + +static bool __kc_pcie_capability_reg_implemented(struct pci_dev *dev, int pos) +{ + if (!pci_is_pcie(dev)) + return false; + + switch (pos) { + case PCI_EXP_FLAGS_TYPE: + return true; + case PCI_EXP_DEVCAP: + case PCI_EXP_DEVCTL: + case PCI_EXP_DEVSTA: + return __kc_pcie_cap_has_devctl(dev); + case PCI_EXP_LNKCAP: + case PCI_EXP_LNKCTL: + case PCI_EXP_LNKSTA: + return __kc_pcie_cap_has_lnkctl(dev); + case PCI_EXP_SLTCAP: + case PCI_EXP_SLTCTL: + case PCI_EXP_SLTSTA: + return __kc_pcie_cap_has_sltctl(dev); + case PCI_EXP_RTCTL: + case PCI_EXP_RTCAP: + case PCI_EXP_RTSTA: + return __kc_pcie_cap_has_rtctl(dev); + case PCI_EXP_DEVCAP2: + case PCI_EXP_DEVCTL2: + case PCI_EXP_LNKCAP2: + case PCI_EXP_LNKCTL2: + case PCI_EXP_LNKSTA2: + return __kc_pcie_cap_version(dev) > 1; + default: + return false; + } +} + +/* + * Note that these accessor functions are only for the "PCI Express + * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the + * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.) + */ +int __kc_pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) +{ + int ret; + + *val = 0; + if (pos & 1) + return -EINVAL; + + if (__kc_pcie_capability_reg_implemented(dev, pos)) { + ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); + /* + * Reset *val to 0 if pci_read_config_word() fails, it may + * have been written as 0xFFFF if hardware error happens + * during pci_read_config_word(). + */ + if (ret) + *val = 0; + return ret; + } + + /* + * For Functions that do not implement the Slot Capabilities, + * Slot Status, and Slot Control registers, these spaces must + * be hardwired to 0b, with the exception of the Presence Detect + * State bit in the Slot Status register of Downstream Ports, + * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) + */ + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + + return 0; +} + +int __kc_pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) +{ + int ret; + + *val = 0; + if (pos & 3) + return -EINVAL; + + if (__kc_pcie_capability_reg_implemented(dev, pos)) { + ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); + /* + * Reset *val to 0 if pci_read_config_dword() fails, it may + * have been written as 0xFFFFFFFF if hardware error happens + * during pci_read_config_dword(). + */ + if (ret) + *val = 0; + return ret; + } + + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + + return 0; +} + +int __kc_pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) +{ + if (pos & 1) + return -EINVAL; + + if (!__kc_pcie_capability_reg_implemented(dev, pos)) + return 0; + + return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); +} + +int __kc_pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, + u16 clear, u16 set) +{ + int ret; + u16 val; + + ret = __kc_pcie_capability_read_word(dev, pos, &val); + if (!ret) { + val &= ~clear; + val |= set; + ret = __kc_pcie_capability_write_word(dev, pos, val); + } + + return ret; +} + +int __kc_pcie_capability_clear_word(struct pci_dev *dev, int pos, + u16 clear) +{ + return __kc_pcie_capability_clear_and_set_word(dev, pos, clear, 0); +} +#endif /* < 3.7.0 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) +#ifdef CONFIG_XPS +#if NR_CPUS < 64 +#define _KC_MAX_XPS_CPUS NR_CPUS +#else +#define _KC_MAX_XPS_CPUS 64 +#endif + +/* + * netdev_queue sysfs structures and functions. + */ +struct _kc_netdev_queue_attribute { + struct attribute attr; + ssize_t (*show)(struct netdev_queue *queue, + struct _kc_netdev_queue_attribute *attr, char *buf); + ssize_t (*store)(struct netdev_queue *queue, + struct _kc_netdev_queue_attribute *attr, const char *buf, size_t len); +}; + +#define to_kc_netdev_queue_attr(_attr) container_of(_attr, \ + struct _kc_netdev_queue_attribute, attr) + +int __kc_netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask, + u16 index) +{ + struct netdev_queue *txq = netdev_get_tx_queue(dev, index); +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) ) + /* Redhat requires some odd extended netdev structures */ + struct netdev_tx_queue_extended *txq_ext = + netdev_extended(dev)->_tx_ext + index; + struct kobj_type *ktype = txq_ext->kobj.ktype; +#else + struct kobj_type *ktype = txq->kobj.ktype; +#endif + struct _kc_netdev_queue_attribute *xps_attr; + struct attribute *attr = NULL; + int i, len, err; +#define _KC_XPS_BUFLEN (DIV_ROUND_UP(_KC_MAX_XPS_CPUS, 32) * 9) + char buf[_KC_XPS_BUFLEN]; + + if (!ktype) + return -ENOMEM; + + /* attempt to locate the XPS attribute in the Tx queue */ + for (i = 0; (attr = ktype->default_attrs[i]); i++) { + if (!strcmp("xps_cpus", attr->name)) + break; + } + + /* if we did not find it return an error */ + if (!attr) + return -EINVAL; + + /* copy the mask into a string */ + len = bitmap_scnprintf(buf, _KC_XPS_BUFLEN, + cpumask_bits(mask), _KC_MAX_XPS_CPUS); + if (!len) + return -ENOMEM; + + xps_attr = to_kc_netdev_queue_attr(attr); + + /* Store the XPS value using the SYSFS store call */ + err = xps_attr->store(txq, xps_attr, buf, len); + + /* we only had an error on err < 0 */ + return (err < 0) ? err : 0; +} +#endif /* CONFIG_XPS */ +#ifdef HAVE_NETDEV_SELECT_QUEUE +static inline int kc_get_xps_queue(struct net_device *dev, struct sk_buff *skb) +{ +#ifdef CONFIG_XPS + struct xps_dev_maps *dev_maps; + struct xps_map *map; + int queue_index = -1; + + rcu_read_lock(); +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) ) + /* Redhat requires some odd extended netdev structures */ + dev_maps = rcu_dereference(netdev_extended(dev)->xps_maps); +#else + dev_maps = rcu_dereference(dev->xps_maps); +#endif + if (dev_maps) { + map = rcu_dereference( + dev_maps->cpu_map[raw_smp_processor_id()]); + if (map) { + if (map->len == 1) + queue_index = map->queues[0]; + else { + u32 hash; + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else + hash = (__force u16) skb->protocol ^ + skb->rxhash; + hash = jhash_1word(hash, _kc_hashrnd); + queue_index = map->queues[ + ((u64)hash * map->len) >> 32]; + } + if (unlikely(queue_index >= dev->real_num_tx_queues)) + queue_index = -1; + } + } + rcu_read_unlock(); + + return queue_index; +#else + struct adapter_struct *kc_adapter = netdev_priv(dev); + int queue_index = -1; + + if (kc_adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { + queue_index = skb_rx_queue_recorded(skb) ? + skb_get_rx_queue(skb) : + smp_processor_id(); + while (unlikely(queue_index >= dev->real_num_tx_queues)) + queue_index -= dev->real_num_tx_queues; + return queue_index; + } + + return -1; +#endif +} + +u16 __kc_netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + int queue_index = sk_tx_queue_get(sk); + int new_index; + + if (queue_index >= 0 && queue_index < dev->real_num_tx_queues) { +#ifdef CONFIG_XPS + if (!skb->ooo_okay) +#endif + return queue_index; + } + + new_index = kc_get_xps_queue(dev, skb); + if (new_index < 0) + new_index = skb_tx_hash(dev, skb); + + if (queue_index != new_index && sk) { + struct dst_entry *dst = + rcu_dereference(sk->sk_dst_cache); + + if (dst && skb_dst(skb) == dst) + sk_tx_queue_set(sk, new_index); + + } + + return new_index; +} + +#endif /* HAVE_NETDEV_SELECT_QUEUE */ +#endif /* 3.9.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) +#ifdef CONFIG_PCI_IOV +int __kc_pci_vfs_assigned(struct pci_dev __maybe_unused *dev) +{ + unsigned int vfs_assigned = 0; +#ifdef HAVE_PCI_DEV_FLAGS_ASSIGNED + int pos; + struct pci_dev *vfdev; + unsigned short dev_id; + + /* only search if we are a PF */ + if (!dev->is_physfn) + return 0; + + /* find SR-IOV capability */ + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) + return 0; + + /* + * determine the device ID for the VFs, the vendor ID will be the + * same as the PF so there is no need to check for that one + */ + pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &dev_id); + + /* loop through all the VFs to see if we own any that are assigned */ + vfdev = pci_get_device(dev->vendor, dev_id, NULL); + while (vfdev) { + /* + * It is considered assigned if it is a virtual function with + * our dev as the physical function and the assigned bit is set + */ + if (vfdev->is_virtfn && (vfdev->physfn == dev) && + (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) + vfs_assigned++; + + vfdev = pci_get_device(dev->vendor, dev_id, vfdev); + } + +#endif /* HAVE_PCI_DEV_FLAGS_ASSIGNED */ + return vfs_assigned; +} + +#endif /* CONFIG_PCI_IOV */ +#endif /* 3.10.0 */ + +static const unsigned char __maybe_unused pcie_link_speed[] = { + PCI_SPEED_UNKNOWN, /* 0 */ + PCIE_SPEED_2_5GT, /* 1 */ + PCIE_SPEED_5_0GT, /* 2 */ + PCIE_SPEED_8_0GT, /* 3 */ + PCIE_SPEED_16_0GT, /* 4 */ + PCI_SPEED_UNKNOWN, /* 5 */ + PCI_SPEED_UNKNOWN, /* 6 */ + PCI_SPEED_UNKNOWN, /* 7 */ + PCI_SPEED_UNKNOWN, /* 8 */ + PCI_SPEED_UNKNOWN, /* 9 */ + PCI_SPEED_UNKNOWN, /* A */ + PCI_SPEED_UNKNOWN, /* B */ + PCI_SPEED_UNKNOWN, /* C */ + PCI_SPEED_UNKNOWN, /* D */ + PCI_SPEED_UNKNOWN, /* E */ + PCI_SPEED_UNKNOWN /* F */ +}; + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) ) +int __kc_pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, + enum pcie_link_width *width) +{ + + *speed = PCI_SPEED_UNKNOWN; + *width = PCIE_LNK_WIDTH_UNKNOWN; + + while (dev) { + u16 lnksta; + enum pci_bus_speed next_speed; + enum pcie_link_width next_width; + int ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta); + + if (ret) + return ret; + + next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS]; + next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> + PCI_EXP_LNKSTA_NLW_SHIFT; + + if (next_speed < *speed) + *speed = next_speed; + + if (next_width < *width) + *width = next_width; + + dev = dev->bus->self; + } + + return 0; +} + +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,7)) +int _kc_pci_wait_for_pending_transaction(struct pci_dev *dev) +{ + int i; + u16 status; + + /* Wait for Transaction Pending bit clean */ + for (i = 0; i < 4; i++) { + if (i) + msleep((1 << (i - 1)) * 100); + + pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); + if (!(status & PCI_EXP_DEVSTA_TRPND)) + return 1; + } + + return 0; +} +#endif /* crs_timeout) { + printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not " + "responding\n", pci_domain_nr(bus), + bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn)); + return false; + } + } + + return true; +} + +bool _kc_pci_device_is_present(struct pci_dev *pdev) +{ + u32 v; + + return _kc_pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0); +} +#endif /* nexthdr; + bool found; + +#define __KC_IP6_FH_F_FRAG BIT(0) +#define __KC_IP6_FH_F_AUTH BIT(1) +#define __KC_IP6_FH_F_SKIP_RH BIT(2) + + if (fragoff) + *fragoff = 0; + + if (*offset) { + struct ipv6hdr _ip6, *ip6; + + ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6); + if (!ip6 || (ip6->version != 6)) { + printk(KERN_ERR "IPv6 header not found\n"); + return -EBADMSG; + } + start = *offset + sizeof(struct ipv6hdr); + nexthdr = ip6->nexthdr; + } + + do { + struct ipv6_opt_hdr _hdr, *hp; + unsigned int hdrlen; + found = (nexthdr == target); + + if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { + if (target < 0 || found) + break; + return -ENOENT; + } + + hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); + if (!hp) + return -EBADMSG; + + if (nexthdr == NEXTHDR_ROUTING) { + struct ipv6_rt_hdr _rh, *rh; + + rh = skb_header_pointer(skb, start, sizeof(_rh), + &_rh); + if (!rh) + return -EBADMSG; + + if (flags && (*flags & __KC_IP6_FH_F_SKIP_RH) && + rh->segments_left == 0) + found = false; + } + + if (nexthdr == NEXTHDR_FRAGMENT) { + unsigned short _frag_off; + __be16 *fp; + + if (flags) /* Indicate that this is a fragment */ + *flags |= __KC_IP6_FH_F_FRAG; + fp = skb_header_pointer(skb, + start+offsetof(struct frag_hdr, + frag_off), + sizeof(_frag_off), + &_frag_off); + if (!fp) + return -EBADMSG; + + _frag_off = ntohs(*fp) & ~0x7; + if (_frag_off) { + if (target < 0 && + ((!ipv6_ext_hdr(hp->nexthdr)) || + hp->nexthdr == NEXTHDR_NONE)) { + if (fragoff) + *fragoff = _frag_off; + return hp->nexthdr; + } + return -ENOENT; + } + hdrlen = 8; + } else if (nexthdr == NEXTHDR_AUTH) { + if (flags && (*flags & __KC_IP6_FH_F_AUTH) && (target < 0)) + break; + hdrlen = (hp->hdrlen + 2) << 2; + } else + hdrlen = ipv6_optlen(hp); + + if (!found) { + nexthdr = hp->nexthdr; + start += hdrlen; + } + } while (!found); + + *offset = start; + return nexthdr; +} + +int __kc_pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, + int minvec, int maxvec) +{ + int nvec = maxvec; + int rc; + + if (maxvec < minvec) + return -ERANGE; + + do { + rc = pci_enable_msix(dev, entries, nvec); + if (rc < 0) { + return rc; + } else if (rc > 0) { + if (rc < minvec) + return -ENOSPC; + nvec = rc; + } + } while (rc); + + return nvec; +} +#endif /* 3.14.0 */ + +#ifdef NEED_DEVM_KSTRDUP +char *_kc_devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) +{ + size_t size; + char *buf; + + if (!s) + return NULL; + + size = strlen(s) + 1; + buf = devm_kzalloc(dev, size, gfp); + if (buf) + memcpy(buf, s, size); + return buf; +} +#endif /* NEED_DEVM_KSTRDUP */ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)) +void __kc_netdev_rss_key_fill(void *buffer, size_t len) +{ + /* Set of random keys generated using kernel random number generator */ + static const u8 seed[NETDEV_RSS_KEY_LEN] = {0xE6, 0xFA, 0x35, 0x62, + 0x95, 0x12, 0x3E, 0xA3, 0xFB, 0x46, 0xC1, 0x5F, + 0xB1, 0x43, 0x82, 0x5B, 0x6A, 0x49, 0x50, 0x95, + 0xCD, 0xAB, 0xD8, 0x11, 0x8F, 0xC5, 0xBD, 0xBC, + 0x6A, 0x4A, 0xB2, 0xD4, 0x1F, 0xFE, 0xBC, 0x41, + 0xBF, 0xAC, 0xB2, 0x9A, 0x8F, 0x70, 0xE9, 0x2A, + 0xD7, 0xB2, 0x80, 0xB6, 0x5B, 0xAA, 0x9D, 0x20}; + + BUG_ON(len > NETDEV_RSS_KEY_LEN); + memcpy(buffer, seed, len); +} +#endif /* 3.15.0 */ + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0) ) +#ifdef HAVE_SET_RX_MODE +#ifdef NETDEV_HW_ADDR_T_UNICAST +int __kc_hw_addr_sync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*sync)(struct net_device *, const unsigned char *), + int (*unsync)(struct net_device *, const unsigned char *)) +{ + struct netdev_hw_addr *ha, *tmp; + int err; + + /* first go through and flush out any stale entries */ + list_for_each_entry_safe(ha, tmp, &list->list, list) { +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) + if (!ha->synced || ha->refcount != 1) +#else + if (!ha->sync_cnt || ha->refcount != 1) +#endif + continue; + + if (unsync && unsync(dev, ha->addr)) + continue; + + list_del_rcu(&ha->list); + kfree_rcu(ha, rcu_head); + list->count--; + } + + /* go through and sync new entries to the list */ + list_for_each_entry_safe(ha, tmp, &list->list, list) { +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) + if (ha->synced) +#else + if (ha->sync_cnt) +#endif + continue; + + err = sync(dev, ha->addr); + if (err) + return err; +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) + ha->synced = true; +#else + ha->sync_cnt++; +#endif + ha->refcount++; + } + + return 0; +} + +void __kc_hw_addr_unsync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*unsync)(struct net_device *, const unsigned char *)) +{ + struct netdev_hw_addr *ha, *tmp; + + list_for_each_entry_safe(ha, tmp, &list->list, list) { +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) + if (!ha->synced) +#else + if (!ha->sync_cnt) +#endif + continue; + + if (unsync && unsync(dev, ha->addr)) + continue; + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) + ha->synced = false; +#else + ha->sync_cnt--; +#endif + if (--ha->refcount) + continue; + + list_del_rcu(&ha->list); + kfree_rcu(ha, rcu_head); + list->count--; + } +} + +#endif /* NETDEV_HW_ADDR_T_UNICAST */ +#ifndef NETDEV_HW_ADDR_T_MULTICAST +int __kc_dev_addr_sync_dev(struct dev_addr_list **list, int *count, + struct net_device *dev, + int (*sync)(struct net_device *, const unsigned char *), + int (*unsync)(struct net_device *, const unsigned char *)) +{ + struct dev_addr_list *da, **next = list; + int err; + + /* first go through and flush out any stale entries */ + while ((da = *next) != NULL) { + if (da->da_synced && da->da_users == 1) { + if (!unsync || !unsync(dev, da->da_addr)) { + *next = da->next; + kfree(da); + (*count)--; + continue; + } + } + next = &da->next; + } + + /* go through and sync new entries to the list */ + for (da = *list; da != NULL; da = da->next) { + if (da->da_synced) + continue; + + err = sync(dev, da->da_addr); + if (err) + return err; + + da->da_synced++; + da->da_users++; + } + + return 0; +} + +void __kc_dev_addr_unsync_dev(struct dev_addr_list **list, int *count, + struct net_device *dev, + int (*unsync)(struct net_device *, const unsigned char *)) +{ + struct dev_addr_list *da; + + while ((da = *list) != NULL) { + if (da->da_synced) { + if (!unsync || !unsync(dev, da->da_addr)) { + da->da_synced--; + if (--da->da_users == 0) { + *list = da->next; + kfree(da); + (*count)--; + continue; + } + } + } + list = &da->next; + } +} +#endif /* NETDEV_HW_ADDR_T_MULTICAST */ +#endif /* HAVE_SET_RX_MODE */ +#endif /* 3.16.0 */ + +#ifdef NEED_DEVM_KMEMDUP +void *_kc_devm_kmemdup(struct device *dev, const void *src, size_t len, + gfp_t gfp) +{ + void *p; + + p = devm_kzalloc(dev, len, gfp); + if (p) + memcpy(p, src, len); + + return p; +} +#endif /* NEED_DEVM_KMEMDUP */ + +/******************************************************************************/ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5))) +#endif /* <3.17.0 && RHEL_RELEASE_CODE < RHEL7.5 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) ) +#ifndef NO_PTP_SUPPORT +static void __kc_sock_efree(struct sk_buff *skb) +{ + sock_put(skb->sk); +} + +struct sk_buff *__kc_skb_clone_sk(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + struct sk_buff *clone; + + if (!sk || !atomic_inc_not_zero(&sk->sk_refcnt)) + return NULL; + + clone = skb_clone(skb, GFP_ATOMIC); + if (!clone) { + sock_put(sk); + return NULL; + } + + clone->sk = sk; + clone->destructor = __kc_sock_efree; + + return clone; +} + +void __kc_skb_complete_tx_timestamp(struct sk_buff *skb, + struct skb_shared_hwtstamps *hwtstamps) +{ + struct sock_exterr_skb *serr; + struct sock *sk = skb->sk; + int err; + + sock_hold(sk); + + *skb_hwtstamps(skb) = *hwtstamps; + + serr = SKB_EXT_ERR(skb); + memset(serr, 0, sizeof(*serr)); + serr->ee.ee_errno = ENOMSG; + serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; + + err = sock_queue_err_skb(sk, skb); + if (err) + kfree_skb(skb); + + sock_put(sk); +} +#endif /* NO_PTP_SUPPORT */ +#endif /* < 3.18.0 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) ) +#ifdef HAVE_NET_GET_RANDOM_ONCE +static u8 __kc_netdev_rss_key[NETDEV_RSS_KEY_LEN]; + +void __kc_netdev_rss_key_fill(void *buffer, size_t len) +{ + BUG_ON(len > sizeof(__kc_netdev_rss_key)); + net_get_random_once(__kc_netdev_rss_key, sizeof(__kc_netdev_rss_key)); + memcpy(buffer, __kc_netdev_rss_key, len); +} +#endif + +int _kc_bitmap_print_to_pagebuf(bool list, char *buf, + const unsigned long *maskp, + int nmaskbits) +{ + ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf - 2; + int n = 0; + + if (len > 1) { + n = list ? bitmap_scnlistprintf(buf, len, maskp, nmaskbits) : + bitmap_scnprintf(buf, len, maskp, nmaskbits); + buf[n++] = '\n'; + buf[n] = '\0'; + } + return n; +} +#endif + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0) ) +#if !((RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,8) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) && \ + (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) && \ + (SLE_VERSION_CODE > SLE_VERSION(12,1,0))) +unsigned int _kc_cpumask_local_spread(unsigned int i, int node) +{ + int cpu; + + /* Wrap: we always want a cpu. */ + i %= num_online_cpus(); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ) + /* Kernels prior to 2.6.28 do not have for_each_cpu or + * cpumask_of_node, so just use for_each_online_cpu() + */ + for_each_online_cpu(cpu) + if (i-- == 0) + return cpu; + + return 0; +#else + if (node == -1) { + for_each_cpu(cpu, cpu_online_mask) + if (i-- == 0) + return cpu; + } else { + /* NUMA first. */ + for_each_cpu_and(cpu, cpumask_of_node(node), cpu_online_mask) + if (i-- == 0) + return cpu; + + for_each_cpu(cpu, cpu_online_mask) { + /* Skip NUMA nodes, done above. */ + if (cpumask_test_cpu(cpu, cpumask_of_node(node))) + continue; + + if (i-- == 0) + return cpu; + } + } +#endif /* KERNEL_VERSION >= 2.6.28 */ + BUG(); +} +#endif +#endif + +/******************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)) +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(12,2,0))) +/** + * _kc_skb_flow_dissect_flow_keys - parse SKB to fill _kc_flow_keys + * @skb: SKB used to fille _kc_flow_keys + * @flow: _kc_flow_keys to set with SKB fields + * @flags: currently unused flags + * + * The purpose of using kcompat for this function is so the caller doesn't have + * to care about which kernel version they are on, which prevents a larger than + * normal #ifdef mess created by using a HAVE_* flag for this case. This is also + * done for 4.2 kernels to simplify calling skb_flow_dissect_flow_keys() + * because in 4.2 kernels skb_flow_dissect_flow_keys() exists, but only has 2 + * arguments. Recent kernels have skb_flow_dissect_flow_keys() that has 3 + * arguments. + * + * The caller needs to understand that this function was only implemented as a + * bare-minimum replacement for recent versions of skb_flow_dissect_flow_keys() + * and this function is in no way similar to skb_flow_dissect_flow_keys(). An + * example use can be found in the ice driver, specifically ice_arfs.c. + * + * This function is treated as a allowlist of supported fields the SKB can + * parse. If new functionality is added make sure to keep this format (i.e. only + * check for fields that are explicity wanted). + * + * Current allowlist: + * + * TCPv4, TCPv6, UDPv4, UDPv6 + * + * If any unexpected protocol or other field is found this function memsets the + * flow passed in back to 0 and returns false. Otherwise the flow is populated + * and returns true. + */ +bool +_kc_skb_flow_dissect_flow_keys(const struct sk_buff *skb, + struct _kc_flow_keys *flow, + unsigned int __always_unused flags) +{ + memset(flow, 0, sizeof(*flow)); + + flow->basic.n_proto = skb->protocol; + switch (flow->basic.n_proto) { + case htons(ETH_P_IP): + flow->basic.ip_proto = ip_hdr(skb)->protocol; + flow->addrs.v4addrs.src = ip_hdr(skb)->saddr; + flow->addrs.v4addrs.dst = ip_hdr(skb)->daddr; + break; + case htons(ETH_P_IPV6): + flow->basic.ip_proto = ipv6_hdr(skb)->nexthdr; + memcpy(&flow->addrs.v6addrs.src, &ipv6_hdr(skb)->saddr, + sizeof(struct in6_addr)); + memcpy(&flow->addrs.v6addrs.dst, &ipv6_hdr(skb)->daddr, + sizeof(struct in6_addr)); + break; + default: + netdev_dbg(skb->dev, "%s: Unsupported/unimplemented layer 3 protocol %04x\n", __func__, htons(flow->basic.n_proto)); + goto unsupported; + } + + switch (flow->basic.ip_proto) { + case IPPROTO_TCP: + { + struct tcphdr *tcph; + + tcph = tcp_hdr(skb); + flow->ports.src = tcph->source; + flow->ports.dst = tcph->dest; + break; + } + case IPPROTO_UDP: + { + struct udphdr *udph; + + udph = udp_hdr(skb); + flow->ports.src = udph->source; + flow->ports.dst = udph->dest; + break; + } + default: + netdev_dbg(skb->dev, "%s: Unsupported/unimplemented layer 4 protocol %02x\n", __func__, flow->basic.ip_proto); + return false; + } + + return true; + +unsupported: + memset(flow, 0, sizeof(*flow)); + return false; +} +#endif /* ! >= RHEL7.4 && ! >= SLES12.2 */ +#endif /* 4.3.0 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) ) +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3))) +#ifdef CONFIG_SPARC +#include +#include +#endif +int _kc_eth_platform_get_mac_address(struct device *dev __maybe_unused, + u8 *mac_addr __maybe_unused) +{ +#if (((LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) && defined(CONFIG_OF) && \ + !defined(HAVE_STRUCT_DEVICE_OF_NODE) || !defined(CONFIG_OF)) && \ + !defined(CONFIG_SPARC)) + return -ENODEV; +#else + const unsigned char *addr; + struct device_node *dp; + + if (dev_is_pci(dev)) + dp = pci_device_to_OF_node(to_pci_dev(dev)); + else +#if defined(HAVE_STRUCT_DEVICE_OF_NODE) && defined(CONFIG_OF) + dp = dev->of_node; +#else + dp = NULL; +#endif + + addr = NULL; + if (dp) + addr = of_get_mac_address(dp); +#ifdef CONFIG_SPARC + /* Kernel hasn't implemented arch_get_platform_mac_address, but we + * should handle the SPARC case here since it was supported + * originally. This is replaced by arch_get_platform_mac_address() + * upstream. + */ + if (!addr) + addr = idprom->id_ethaddr; +#endif + if (!addr) + return -ENODEV; + + ether_addr_copy(mac_addr, addr); + return 0; +#endif +} +#endif /* !(RHEL_RELEASE >= 7.3) */ +#endif /* < 4.5.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) +int _kc_kstrtobool(const char *s, bool *res) +{ + if (!s) + return -EINVAL; + + switch (s[0]) { + case 'y': + case 'Y': + case '1': + *res = true; + return 0; + case 'n': + case 'N': + case '0': + *res = false; + return 0; + case 'o': + case 'O': + switch (s[1]) { + case 'n': + case 'N': + *res = true; + return 0; + case 'f': + case 'F': + *res = false; + return 0; + default: + break; + } + break; + default: + break; + } + + return -EINVAL; +} +#endif /* < 4.6.0 */ + +/*****************************************************************************/ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)) || \ + (SLE_VERSION_CODE && (SLE_VERSION_CODE <= SLE_VERSION(12,3,0))) || \ + (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7,5)))) +const char *_kc_phy_speed_to_str(int speed) +{ + switch (speed) { + case SPEED_10: + return "10Mbps"; + case SPEED_100: + return "100Mbps"; + case SPEED_1000: + return "1Gbps"; + case SPEED_2500: + return "2.5Gbps"; + case SPEED_5000: + return "5Gbps"; + case SPEED_10000: + return "10Gbps"; + case SPEED_14000: + return "14Gbps"; + case SPEED_20000: + return "20Gbps"; + case SPEED_25000: + return "25Gbps"; + case SPEED_40000: + return "40Gbps"; + case SPEED_50000: + return "50Gbps"; + case SPEED_56000: + return "56Gbps"; +#ifdef SPEED_100000 + case SPEED_100000: + return "100Gbps"; +#endif +#ifdef SPEED_200000 + case SPEED_200000: + return "200Gbps"; +#endif + case SPEED_UNKNOWN: + return "Unknown"; + default: + return "Unsupported (update phy-core.c)"; + } +} +#endif /* (LINUX < 4.14.0) || (SLES <= 12.3.0) || (RHEL <= 7.5) */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) ) +void _kc_ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst, + struct ethtool_link_ksettings *src) +{ + unsigned int size = BITS_TO_LONGS(__ETHTOOL_LINK_MODE_MASK_NBITS); + unsigned int idx = 0; + + for (; idx < size; idx++) { + dst->link_modes.supported[idx] &= + src->link_modes.supported[idx]; + dst->link_modes.advertising[idx] &= + src->link_modes.advertising[idx]; + } +} +#endif /* 4.15.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,17,0)) +/* PCIe link information */ +#define PCIE_SPEED2STR(speed) \ + ((speed) == PCIE_SPEED_16_0GT ? "16 GT/s" : \ + (speed) == PCIE_SPEED_8_0GT ? "8 GT/s" : \ + (speed) == PCIE_SPEED_5_0GT ? "5 GT/s" : \ + (speed) == PCIE_SPEED_2_5GT ? "2.5 GT/s" : \ + "Unknown speed") + +/* PCIe speed to Mb/s reduced by encoding overhead */ +#define PCIE_SPEED2MBS_ENC(speed) \ + ((speed) == PCIE_SPEED_16_0GT ? 16000*128/130 : \ + (speed) == PCIE_SPEED_8_0GT ? 8000*128/130 : \ + (speed) == PCIE_SPEED_5_0GT ? 5000*8/10 : \ + (speed) == PCIE_SPEED_2_5GT ? 2500*8/10 : \ + 0) + +static u32 +_kc_pcie_bandwidth_available(struct pci_dev *dev, + struct pci_dev **limiting_dev, + enum pci_bus_speed *speed, + enum pcie_link_width *width) +{ + u16 lnksta; + enum pci_bus_speed next_speed; + enum pcie_link_width next_width; + u32 bw, next_bw; + + if (speed) + *speed = PCI_SPEED_UNKNOWN; + if (width) + *width = PCIE_LNK_WIDTH_UNKNOWN; + + bw = 0; + + while (dev) { + pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta); + + next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS]; + next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> + PCI_EXP_LNKSTA_NLW_SHIFT; + + next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed); + + /* Check if current device limits the total bandwidth */ + if (!bw || next_bw <= bw) { + bw = next_bw; + + if (limiting_dev) + *limiting_dev = dev; + if (speed) + *speed = next_speed; + if (width) + *width = next_width; + } + + dev = pci_upstream_bridge(dev); + } + + return bw; +} + +static enum pci_bus_speed _kc_pcie_get_speed_cap(struct pci_dev *dev) +{ + u32 lnkcap2, lnkcap; + + /* + * PCIe r4.0 sec 7.5.3.18 recommends using the Supported Link + * Speeds Vector in Link Capabilities 2 when supported, falling + * back to Max Link Speed in Link Capabilities otherwise. + */ + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2); + if (lnkcap2) { /* PCIe r3.0-compliant */ + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB) + return PCIE_SPEED_16_0GT; + else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB) + return PCIE_SPEED_8_0GT; + else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB) + return PCIE_SPEED_5_0GT; + else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB) + return PCIE_SPEED_2_5GT; + return PCI_SPEED_UNKNOWN; + } + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); + if (lnkcap) { + if (lnkcap & PCI_EXP_LNKCAP_SLS_16_0GB) + return PCIE_SPEED_16_0GT; + else if (lnkcap & PCI_EXP_LNKCAP_SLS_8_0GB) + return PCIE_SPEED_8_0GT; + else if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB) + return PCIE_SPEED_5_0GT; + else if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB) + return PCIE_SPEED_2_5GT; + } + + return PCI_SPEED_UNKNOWN; +} + +static enum pcie_link_width _kc_pcie_get_width_cap(struct pci_dev *dev) +{ + u32 lnkcap; + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); + if (lnkcap) + return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4; + + return PCIE_LNK_WIDTH_UNKNOWN; +} + +static u32 +_kc_pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed, + enum pcie_link_width *width) +{ + *speed = _kc_pcie_get_speed_cap(dev); + *width = _kc_pcie_get_width_cap(dev); + + if (*speed == PCI_SPEED_UNKNOWN || *width == PCIE_LNK_WIDTH_UNKNOWN) + return 0; + + return *width * PCIE_SPEED2MBS_ENC(*speed); +} + +void _kc_pcie_print_link_status(struct pci_dev *dev) { + enum pcie_link_width width, width_cap; + enum pci_bus_speed speed, speed_cap; + struct pci_dev *limiting_dev = NULL; + u32 bw_avail, bw_cap; + + bw_cap = _kc_pcie_bandwidth_capable(dev, &speed_cap, &width_cap); + bw_avail = _kc_pcie_bandwidth_available(dev, &limiting_dev, &speed, + &width); + + if (bw_avail >= bw_cap) + pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)\n", + bw_cap / 1000, bw_cap % 1000, + PCIE_SPEED2STR(speed_cap), width_cap); + else + pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n", + bw_avail / 1000, bw_avail % 1000, + PCIE_SPEED2STR(speed), width, + limiting_dev ? pci_name(limiting_dev) : "", + bw_cap / 1000, bw_cap % 1000, + PCIE_SPEED2STR(speed_cap), width_cap); +} +#endif /* 4.17.0 */ + +#ifdef NEED_FLOW_BLOCK_CB_SETUP_SIMPLE +#ifdef HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO +int _kc_flow_block_cb_setup_simple(struct flow_block_offload *f, + struct list_head __always_unused *driver_list, + tc_setup_cb_t *cb, + void *cb_ident, void *cb_priv, + bool ingress_only) +{ + if (ingress_only && + f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) + return -EOPNOTSUPP; + + /* Note: Upstream has driver_block_list, but older kernels do not */ + switch (f->command) { + case TC_BLOCK_BIND: +#ifdef HAVE_TCF_BLOCK_CB_REGISTER_EXTACK + return tcf_block_cb_register(f->block, cb, cb_ident, cb_priv, + f->extack); +#else + return tcf_block_cb_register(f->block, cb, cb_ident, cb_priv); +#endif + case TC_BLOCK_UNBIND: + tcf_block_cb_unregister(f->block, cb, cb_ident); + return 0; + default: + return -EOPNOTSUPP; + } +} +#endif /* HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO */ +#endif /* NEED_FLOW_BLOCK_CB_SETUP_SIMPLE */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0)) +u64 _kc_pci_get_dsn(struct pci_dev *dev) +{ + u32 dword; + u64 dsn; + int pos; + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DSN); + if (!pos) + return 0; + + /* + * The Device Serial Number is two dwords offset 4 bytes from the + * capability position. The specification says that the first dword is + * the lower half, and the second dword is the upper half. + */ + pos += 4; + pci_read_config_dword(dev, pos, &dword); + dsn = (u64)dword; + pci_read_config_dword(dev, pos + 4, &dword); + dsn |= ((u64)dword) << 32; + + return dsn; +} +#endif /* 5.7.0 */ + +#ifdef NEED_DEVM_KVASPRINTF +char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, + va_list ap) +{ + unsigned int len; + char *p; + va_list aq; + + va_copy(aq, ap); + len = vsnprintf(NULL, 0, fmt, aq); + va_end(aq); + + p = devm_kmalloc(dev, len + 1, gfp); + if (!p) + return NULL; + + vsnprintf(p, len + 1, fmt, ap); + + return p; +} +#endif /* NEED_DEVM_KVASPRINTF */ + +#ifdef NEED_DEVM_KASPRINTF +char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...) +{ + va_list ap; + char *p; + + va_start(ap, fmt); + p = devm_kvasprintf(dev, gfp, fmt, ap); + va_end(ap); + + return p; +} +#endif /* NEED_DEVM_KASPRINTF */ + +#ifdef NEED_PCI_IOV_VF_ID +#ifdef CONFIG_PCI_IOV +/* + * Below function needs to access pci_sriov offset and stride. Since + * pci_sriov structure is defined in drivers/pci/pci.h which can not + * be included as linux kernel header file, the structure definition + * is not globally visible. + * As a result, one copy of structure definition is added. Since the + * definition is a copy, you need to make sure the kernel you want + * to backport must have exactly the same pci_sriov definition as the + * copy, otherwise you'll access wrong field offset and value. + */ + +/* Single Root I/O Virtualization */ +struct pci_sriov { + int pos; /* Capability position */ + int nres; /* Number of resources */ + u32 cap; /* SR-IOV Capabilities */ + u16 ctrl; /* SR-IOV Control */ + u16 total_VFs; /* Total VFs associated with the PF */ + u16 initial_VFs; /* Initial VFs associated with the PF */ + u16 num_VFs; /* Number of VFs available */ + u16 offset; /* First VF Routing ID offset */ + u16 stride; /* Following VF stride */ + u16 vf_device; /* VF device ID */ + u32 pgsz; /* Page size for BAR alignment */ + u8 link; /* Function Dependency Link */ + u8 max_VF_buses; /* Max buses consumed by VFs */ + u16 driver_max_VFs; /* Max num VFs driver supports */ + struct pci_dev *dev; /* Lowest numbered PF */ + struct pci_dev *self; /* This PF */ + u32 cfg_size; /* VF config space size */ + u32 class; /* VF device */ + u8 hdr_type; /* VF header type */ + u16 subsystem_vendor; /* VF subsystem vendor */ + u16 subsystem_device; /* VF subsystem device */ + resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */ + bool drivers_autoprobe; /* Auto probing of VFs by driver */ +}; + +int _kc_pci_iov_vf_id(struct pci_dev *dev) +{ + struct pci_dev *pf; + + if (!dev->is_virtfn) + return -EINVAL; + + pf = pci_physfn(dev); + return (((dev->bus->number << 8) + dev->devfn) - + ((pf->bus->number << 8) + pf->devfn + pf->sriov->offset)) / + pf->sriov->stride; +} +#endif /* CONFIG_PCI_IOV */ +#endif /* NEED_PCI_IOV_VF_ID */ + +#ifdef NEED_MUL_U64_U64_DIV_U64 +u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c) +{ + u64 res = 0, div, rem; + int shift; + + /* can a * b overflow ? */ + if (ilog2(a) + ilog2(b) > 62) { + /* + * (b * a) / c is equal to + * + * (b / c) * a + + * (b % c) * a / c + * + * if nothing overflows. Can the 1st multiplication + * overflow? Yes, but we do not care: this can only + * happen if the end result can't fit in u64 anyway. + * + * So the code below does + * + * res = (b / c) * a; + * b = b % c; + */ + div = div64_u64_rem(b, c, &rem); + res = div * a; + b = rem; + + shift = ilog2(a) + ilog2(b) - 62; + if (shift > 0) { + /* drop precision */ + b >>= shift; + c >>= shift; + if (!c) + return res; + } + } + + return res + div64_u64(a * b, c); +} +#endif /* NEED_MUL_U64_U64_DIV_U64 */ + +#ifdef NEED_ETHTOOL_SPRINTF +void ethtool_sprintf(u8 **data, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsnprintf(*data, ETH_GSTRING_LEN, fmt, args); + va_end(args); + + *data += ETH_GSTRING_LEN; +} +#endif /* NEED_ETHTOOL_SPRINTF */ + +#ifdef NEED_SYSFS_EMIT +int sysfs_emit(char *buf, const char *fmt, ...) +{ + va_list args; + int len; + + if (WARN(!buf || offset_in_page(buf), + "invalid %s: buf:%p\n", __func__, buf)) + return 0; + + va_start(args, fmt); + len = vscnprintf(buf, PAGE_SIZE, fmt, args); + va_end(args); + + return len; +} +#endif /* NEED_SYSFS_EMIT */ + +#ifndef HAVE_ETHTOOL_KEEE +void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, + u32 legacy_u32) +{ + bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS); + dst[0] = legacy_u32; +} + +bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, + const unsigned long *src) +{ + *legacy_u32 = src[0]; + return find_next_bit(src, __ETHTOOL_LINK_MODE_MASK_NBITS, 32) == + __ETHTOOL_LINK_MODE_MASK_NBITS; +} + +void eee_to_keee(struct ethtool_keee *keee, + const struct ethtool_eee *eee) +{ + memset(keee, 0, sizeof(*keee)); + + keee->eee_enabled = eee->eee_enabled; + keee->tx_lpi_enabled = eee->tx_lpi_enabled; + keee->tx_lpi_timer = eee->tx_lpi_timer; + + ethtool_convert_legacy_u32_to_link_mode(keee->supported, + eee->supported); + ethtool_convert_legacy_u32_to_link_mode(keee->advertised, + eee->advertised); + ethtool_convert_legacy_u32_to_link_mode(keee->lp_advertised, + eee->lp_advertised); +} + +bool ethtool_eee_use_linkmodes(const struct ethtool_keee *eee) +{ +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,0))) + return !linkmode_empty(eee->supported); +#else + return false; +#endif /* RH7.9 */ +} + +void keee_to_eee(struct ethtool_eee *eee, + const struct ethtool_keee *keee) +{ + bool overflow; + + memset(eee, 0, sizeof(*eee)); + + eee->eee_active = keee->eee_active; + eee->eee_enabled = keee->eee_enabled; + eee->tx_lpi_enabled = keee->tx_lpi_enabled; + eee->tx_lpi_timer = keee->tx_lpi_timer; + + overflow = !ethtool_convert_link_mode_to_legacy_u32(&eee->supported, + keee->supported); + ethtool_convert_link_mode_to_legacy_u32(&eee->advertised, + keee->advertised); + ethtool_convert_link_mode_to_legacy_u32(&eee->lp_advertised, + keee->lp_advertised); + if (overflow) + pr_warn("Ethtool ioctl interface doesn't support passing EEE linkmodes beyond bit 32\n"); +} +#endif /* !HAVE_ETHTOOL_KEEE */ + +#ifdef NEED_PCI_DISABLE_PTM +#if defined(HAVE_STRUCT_PCI_DEV_PTM_ENABLED) && defined(CONFIG_PCIE_PTM) +static void __pci_disable_ptm(struct pci_dev *dev) +{ +#if defined(HAVE_STRUCT_PCI_DEV_PTM_CAP) + u16 ptm = dev->ptm_cap; + u32 ctrl; + + if (!ptm) + return; + + pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, &ctrl); + ctrl &= ~(PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT); + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); +#else + return; +#endif /* HAVE_STRUCT_PCI_DEV_PTM_CAP */ +} +#endif /* HAVE_STRUCT_PCI_DEV_PTM_ENABLED && CONFIG_PCIE_PTM */ + +/** + * pci_disable_ptm() - Disable Precision Time Measurement + * @dev: PCI device + * + * Disable Precision Time Measurement for @dev. + */ +void pci_disable_ptm(struct pci_dev *dev) +{ +#if defined(HAVE_STRUCT_PCI_DEV_PTM_ENABLED) && defined(CONFIG_PCIE_PTM) + if (dev->ptm_enabled) { + __pci_disable_ptm(dev); + dev->ptm_enabled = 0; + } +#else + return; +#endif /* HAVE_STRUCT_PCI_DEV_PTM_ENABLED && CONFIG_PCIE_PTM */ +} +#endif /* NEED_PCI_DISABLE_PTM */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.h new file mode 100644 index 0000000000..9b5d167c84 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat.h @@ -0,0 +1,6932 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_H_ +#define _KCOMPAT_H_ + +#ifndef LINUX_VERSION_CODE +#include +#else +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#ifdef __LINUX_COMPILER_H +#error "kcompat.h must be included prior to kernel headers" +#endif + +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) +#endif /* GCC_VERSION */ + +/* as GCC_VERSION yields 40201 for any modern clang (checked on clang 7 & 13) + * we want other means to add workarounds for "old GCC" */ +#ifdef __clang__ +#define GCC_IS_BELOW(x) 0 +#else +#define GCC_IS_BELOW(x) (GCC_VERSION < (x)) +#endif + +/* + * upstream commit 4eb6bd55cfb2 ("compiler.h: drop fallback overflow checkers") + * removed bunch of code for builitin overflow fallback implementations, that + * we need for gcc prior to 5.1 + */ +#if !GCC_IS_BELOW(50100) +#ifndef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW +#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 +#endif +#endif /* GCC_VERSION >= 50100 */ + +/* Headers that must be before the rest, as they build like-current kerrnel + * infra for all other COMPAT and CORE code. + */ +#include "kcompat_generated_defs.h" +#include "kcompat_overflow.h" +#include "kcompat_gcc.h" +/* end of must-be-really-first headers */ + +#include "kcompat_cleanup.h" + +#ifndef HAVE_XARRAY_API +#include "kcompat_xarray.h" +#endif /* !HAVE_XARRAY_API */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LINUX_REFCOUNT_TYPES_HEADER +#include +#elif defined(HAVE_LINUX_REFCOUNT_HEADER) +#include +#endif /* HAVE_LINUX_REFCOUNT_TYPES_HEADER */ + +#ifndef IEEE_8021QAZ_APP_SEL_DSCP +#define IEEE_8021QAZ_APP_SEL_DSCP 5 +#endif + +#ifndef NSEC_PER_MSEC +#define NSEC_PER_MSEC 1000000L +#endif +#include +/* UTS_RELEASE is in a different header starting in kernel 2.6.18 */ +#ifndef UTS_RELEASE +/* utsrelease.h changed locations in 2.6.33 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) ) +#include +#else +#include +#endif +#endif + +/* NAPI enable/disable flags here */ +#define NAPI + +#define adapter_struct ixgbe_adapter +#define adapter_q_vector ixgbe_q_vector + +/* and finally set defines so that the code sees the changes */ +#ifdef NAPI +#else +#endif /* NAPI */ + +/* Dynamic LTR and deeper C-State support disable/enable */ + +/* packet split disable/enable */ +#ifdef DISABLE_PACKET_SPLIT +#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT +#define CONFIG_IXGBE_DISABLE_PACKET_SPLIT +#endif +#endif /* DISABLE_PACKET_SPLIT */ + +/* MSI compatibility code for all kernels and drivers */ +#ifdef DISABLE_PCI_MSI +#undef CONFIG_PCI_MSI +#endif +#ifndef CONFIG_PCI_MSI +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ) +struct msix_entry { + u16 vector; /* kernel uses to write allocated vector */ + u16 entry; /* driver uses to specify entry, OS writes */ +}; +#endif +#undef pci_enable_msi +#define pci_enable_msi(a) -ENOTSUPP +#undef pci_disable_msi +#define pci_disable_msi(a) do {} while (0) +#undef pci_enable_msix +#define pci_enable_msix(a, b, c) -ENOTSUPP +#undef pci_disable_msix +#define pci_disable_msix(a) do {} while (0) +#define msi_remove_pci_irq_vectors(a) do {} while (0) +#endif /* CONFIG_PCI_MSI */ +#ifdef DISABLE_PM +#undef CONFIG_PM +#endif + +#ifdef DISABLE_NET_POLL_CONTROLLER +#undef CONFIG_NET_POLL_CONTROLLER +#endif + +#ifndef PMSG_SUSPEND +#define PMSG_SUSPEND 3 +#endif + +/* generic boolean compatibility */ +#undef TRUE +#undef FALSE +#define TRUE true +#define FALSE false +#ifdef GCC_VERSION +#if ( GCC_VERSION < 3000 ) +#define _Bool char +#endif +#else +#define _Bool char +#endif + +#ifndef BIT +#define BIT(nr) (1UL << (nr)) +#endif + +#undef __always_unused +#define __always_unused __attribute__((__unused__)) + +#undef __maybe_unused +#define __maybe_unused __attribute__((__unused__)) + +/* kernels less than 2.4.14 don't have this */ +#ifndef ETH_P_8021Q +#define ETH_P_8021Q 0x8100 +#endif + +#ifndef module_param +#define module_param(v,t,p) MODULE_PARM(v, "i"); +#endif + +#ifndef DMA_64BIT_MASK +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#endif + +#ifndef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef PCI_CAP_ID_EXP +#define PCI_CAP_ID_EXP 0x10 +#endif + +#ifndef uninitialized_var +#define uninitialized_var(x) x = x +#endif + +#ifndef PCIE_LINK_STATE_L0S +#define PCIE_LINK_STATE_L0S 1 +#endif +#ifndef PCIE_LINK_STATE_L1 +#define PCIE_LINK_STATE_L1 2 +#endif + +#ifndef SET_NETDEV_DEV +#define SET_NETDEV_DEV(net, pdev) +#endif + +#if !defined(HAVE_FREE_NETDEV) && ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) ) +#define free_netdev(x) kfree(x) +#endif + +#ifdef HAVE_POLL_CONTROLLER +#define CONFIG_NET_POLL_CONTROLLER +#endif + +#ifndef SKB_DATAREF_SHIFT +/* if we do not have the infrastructure to detect if skb_header is cloned + just return false in all cases */ +#define skb_header_cloned(x) 0 +#endif + +#ifndef NETIF_F_GSO +#define gso_size tso_size +#define gso_segs tso_segs +#endif + +#ifndef NETIF_F_GRO +#define vlan_gro_receive(_napi, _vlgrp, _vlan, _skb) \ + vlan_hwaccel_receive_skb(_skb, _vlgrp, _vlan) +#define napi_gro_receive(_napi, _skb) netif_receive_skb(_skb) +#endif + +#ifndef NETIF_F_SCTP_CSUM +#define NETIF_F_SCTP_CSUM 0 +#endif + +#ifndef NETIF_F_LRO +#define NETIF_F_LRO BIT(15) +#endif + +#ifndef NETIF_F_NTUPLE +#define NETIF_F_NTUPLE BIT(27) +#endif + +#ifndef NETIF_F_ALL_FCOE +#define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ + NETIF_F_FSO) +#endif + +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +#ifndef IPPROTO_UDPLITE +#define IPPROTO_UDPLITE 136 +#endif + +#ifndef CHECKSUM_PARTIAL +#define CHECKSUM_PARTIAL CHECKSUM_HW +#define CHECKSUM_COMPLETE CHECKSUM_HW +#endif + +#ifndef __read_mostly +#define __read_mostly +#endif + +#ifndef MII_RESV1 +#define MII_RESV1 0x17 /* Reserved... */ +#endif + +#ifndef unlikely +#define unlikely(_x) _x +#define likely(_x) _x +#endif + +#ifndef WARN_ON +#define WARN_ON(x) ({0;}) +#endif + +#ifndef PCI_DEVICE +#define PCI_DEVICE(vend,dev) \ + .vendor = (vend), .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID +#endif + +#ifndef node_online +#define node_online(node) ((node) == 0) +#endif + +#ifndef _LINUX_RANDOM_H +#include +#endif + +#ifndef BITS_PER_TYPE +#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) +#endif + +#ifndef BITS_TO_LONGS +#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) +#endif + +#ifndef DECLARE_BITMAP +#define DECLARE_BITMAP(name,bits) long name[BITS_TO_LONGS(bits)] +#endif + +#ifndef VLAN_HLEN +#define VLAN_HLEN 4 +#endif + +#ifndef VLAN_ETH_HLEN +#define VLAN_ETH_HLEN 18 +#endif + +#ifndef VLAN_ETH_FRAME_LEN +#define VLAN_ETH_FRAME_LEN 1518 +#endif + +#ifndef DCA_GET_TAG_TWO_ARGS +#define dca3_get_tag(a,b) dca_get_tag(b) +#endif + +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +#if defined(__i386__) || defined(__x86_64__) +#define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +#endif +#endif + +/* taken from 2.6.24 definition in linux/kernel.h */ +#ifndef IS_ALIGNED +#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) +#endif + +#define __ARG_PLACEHOLDER_1 0, +#define __take_second_arg(__ignored, val, ...) val + +/* + * The use of "&&" / "||" is limited in certain expressions. + * The following enable to calculate "and" / "or" with macro expansion only. + */ +#define __and(x, y) ___and(x, y) +#define ___and(x, y) ____and(__ARG_PLACEHOLDER_##x, y) +#define ____and(arg1_or_junk, y) __take_second_arg(arg1_or_junk y, 0) + +#define __or(x, y) ___or(x, y) +#define ___or(x, y) ____or(__ARG_PLACEHOLDER_##x, y) +#define ____or(arg1_or_junk, y) __take_second_arg(arg1_or_junk 1, y) + +/* + * Helper macros to use CONFIG_ options in C/CPP expressions. Note that + * these only work with boolean and tristate options. + */ + +/* + * Getting something that works in C and CPP for an arg that may or may + * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" + * we match on the placeholder define, insert the "0," for arg1 and generate + * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). + * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when + * the last step cherry picks the 2nd arg, we get a zero. + */ +#define __is_defined(x) ___is_defined(x) +#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val) +#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0) + +/* + * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 + * otherwise. For boolean options, this is equivalent to + * IS_ENABLED(CONFIG_FOO). + */ +#define IS_BUILTIN(option) __is_defined(option) + +/* + * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 + * otherwise. CONFIG_FOO=m results in "#define CONFIG_FOO_MODULE 1" in + * autoconf.h. + */ +#define IS_MODULE(option) __is_defined(option##_MODULE) + +/* + * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled + * code can call a function defined in code compiled based on CONFIG_FOO. + * This is similar to IS_ENABLED(), but returns false when invoked from + * built-in code when CONFIG_FOO is set to 'm'. + */ +#define IS_REACHABLE(option) __or(IS_BUILTIN(option), \ + __and(IS_MODULE(option), __is_defined(MODULE))) + +/* + * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', + * 0 otherwise. Note that CONFIG_FOO=y results in "#define CONFIG_FOO 1" in + * autoconf.h, while CONFIG_FOO=m results in "#define CONFIG_FOO_MODULE 1". + */ +#define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) + +#if !defined(NETIF_F_HW_VLAN_TX) && !defined(NETIF_F_HW_VLAN_CTAG_TX) +struct _kc_vlan_ethhdr { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + __be16 h_vlan_encapsulated_proto; +}; +#define vlan_ethhdr _kc_vlan_ethhdr +struct _kc_vlan_hdr { + __be16 h_vlan_TCI; + __be16 h_vlan_encapsulated_proto; +}; +#define vlan_hdr _kc_vlan_hdr +#define vlan_tx_tag_present(_skb) 0 +#define vlan_tx_tag_get(_skb) 0 +#endif /* NETIF_F_HW_VLAN_TX && NETIF_F_HW_VLAN_CTAG_TX */ + +#ifndef VLAN_PRIO_SHIFT +#define VLAN_PRIO_SHIFT 13 +#endif + +#ifndef PCI_EXP_LNKSTA_CLS_2_5GB +#define PCI_EXP_LNKSTA_CLS_2_5GB 0x0001 +#endif + +#ifndef PCI_EXP_LNKSTA_CLS_5_0GB +#define PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 +#endif + +#ifndef PCI_EXP_LNKSTA_CLS_8_0GB +#define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 +#endif + +#ifndef PCI_EXP_LNKSTA_NLW_X1 +#define PCI_EXP_LNKSTA_NLW_X1 0x0010 +#endif + +#ifndef PCI_EXP_LNKSTA_NLW_X2 +#define PCI_EXP_LNKSTA_NLW_X2 0x0020 +#endif + +#ifndef PCI_EXP_LNKSTA_NLW_X4 +#define PCI_EXP_LNKSTA_NLW_X4 0x0040 +#endif + +#ifndef PCI_EXP_LNKSTA_NLW_X8 +#define PCI_EXP_LNKSTA_NLW_X8 0x0080 +#endif + +#ifndef __GFP_COLD +#define __GFP_COLD 0 +#endif + +#ifndef __GFP_COMP +#define __GFP_COMP 0 +#endif + +#ifndef IP_OFFSET +#define IP_OFFSET 0x1FFF /* "Fragment Offset" part */ +#endif + +/*****************************************************************************/ +/* Installations with ethtool version without eeprom, adapter id, or statistics + * support */ + +#ifndef ETH_GSTRING_LEN +#define ETH_GSTRING_LEN 32 +#endif + +#ifndef ETHTOOL_GSTATS +#define ETHTOOL_GSTATS 0x1d +#undef ethtool_drvinfo +#define ethtool_drvinfo k_ethtool_drvinfo +struct k_ethtool_drvinfo { + u32 cmd; + char driver[32]; + char version[32]; + char fw_version[32]; + char bus_info[32]; + char reserved1[32]; + char reserved2[16]; + u32 n_stats; + u32 testinfo_len; + u32 eedump_len; + u32 regdump_len; +}; + +struct ethtool_stats { + u32 cmd; + u32 n_stats; + u64 data[0]; +}; +#endif /* ETHTOOL_GSTATS */ + +#ifndef ETHTOOL_PHYS_ID +#define ETHTOOL_PHYS_ID 0x1c +#endif /* ETHTOOL_PHYS_ID */ + +#ifndef ETHTOOL_GSTRINGS +#define ETHTOOL_GSTRINGS 0x1b +enum ethtool_stringset { + ETH_SS_TEST = 0, + ETH_SS_STATS, +}; +struct ethtool_gstrings { + u32 cmd; /* ETHTOOL_GSTRINGS */ + u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ + u32 len; /* number of strings in the string set */ + u8 data[0]; +}; +#endif /* ETHTOOL_GSTRINGS */ + +#ifndef ETHTOOL_TEST +#define ETHTOOL_TEST 0x1a +enum ethtool_test_flags { + ETH_TEST_FL_OFFLINE = BIT(0), + ETH_TEST_FL_FAILED = BIT(1), +}; +struct ethtool_test { + u32 cmd; + u32 flags; + u32 reserved; + u32 len; + u64 data[0]; +}; +#endif /* ETHTOOL_TEST */ + +#ifndef ETHTOOL_GEEPROM +#define ETHTOOL_GEEPROM 0xb +#undef ETHTOOL_GREGS +struct ethtool_eeprom { + u32 cmd; + u32 magic; + u32 offset; + u32 len; + u8 data[0]; +}; + +struct ethtool_value { + u32 cmd; + u32 data; +}; +#endif /* ETHTOOL_GEEPROM */ + +#ifndef ETHTOOL_GLINK +#define ETHTOOL_GLINK 0xa +#endif /* ETHTOOL_GLINK */ + +#ifndef ETHTOOL_GWOL +#define ETHTOOL_GWOL 0x5 +#define ETHTOOL_SWOL 0x6 +#define SOPASS_MAX 6 +struct ethtool_wolinfo { + u32 cmd; + u32 supported; + u32 wolopts; + u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */ +}; +#endif /* ETHTOOL_GWOL */ + +#ifndef ETHTOOL_GREGS +#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */ +#define ethtool_regs _kc_ethtool_regs +/* for passing big chunks of data */ +struct _kc_ethtool_regs { + u32 cmd; + u32 version; /* driver-specific, indicates different chips/revs */ + u32 len; /* bytes */ + u8 data[0]; +}; +#endif /* ETHTOOL_GREGS */ + +#ifndef ETHTOOL_GMSGLVL +#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ +#endif +#ifndef ETHTOOL_SMSGLVL +#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */ +#endif +#ifndef ETHTOOL_NWAY_RST +#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */ +#endif +#ifndef ETHTOOL_GLINK +#define ETHTOOL_GLINK 0x0000000a /* Get link status */ +#endif +#ifndef ETHTOOL_GEEPROM +#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ +#endif +#ifndef ETHTOOL_SEEPROM +#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */ +#endif +#ifndef ETHTOOL_GCOALESCE +#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ +/* for configuring coalescing parameters of chip */ +#define ethtool_coalesce _kc_ethtool_coalesce +struct _kc_ethtool_coalesce { + u32 cmd; /* ETHTOOL_{G,S}COALESCE */ + + /* How many usecs to delay an RX interrupt after + * a packet arrives. If 0, only rx_max_coalesced_frames + * is used. + */ + u32 rx_coalesce_usecs; + + /* How many packets to delay an RX interrupt after + * a packet arrives. If 0, only rx_coalesce_usecs is + * used. It is illegal to set both usecs and max frames + * to zero as this would cause RX interrupts to never be + * generated. + */ + u32 rx_max_coalesced_frames; + + /* Same as above two parameters, except that these values + * apply while an IRQ is being serviced by the host. Not + * all cards support this feature and the values are ignored + * in that case. + */ + u32 rx_coalesce_usecs_irq; + u32 rx_max_coalesced_frames_irq; + + /* How many usecs to delay a TX interrupt after + * a packet is sent. If 0, only tx_max_coalesced_frames + * is used. + */ + u32 tx_coalesce_usecs; + + /* How many packets to delay a TX interrupt after + * a packet is sent. If 0, only tx_coalesce_usecs is + * used. It is illegal to set both usecs and max frames + * to zero as this would cause TX interrupts to never be + * generated. + */ + u32 tx_max_coalesced_frames; + + /* Same as above two parameters, except that these values + * apply while an IRQ is being serviced by the host. Not + * all cards support this feature and the values are ignored + * in that case. + */ + u32 tx_coalesce_usecs_irq; + u32 tx_max_coalesced_frames_irq; + + /* How many usecs to delay in-memory statistics + * block updates. Some drivers do not have an in-memory + * statistic block, and in such cases this value is ignored. + * This value must not be zero. + */ + u32 stats_block_coalesce_usecs; + + /* Adaptive RX/TX coalescing is an algorithm implemented by + * some drivers to improve latency under low packet rates and + * improve throughput under high packet rates. Some drivers + * only implement one of RX or TX adaptive coalescing. Anything + * not implemented by the driver causes these values to be + * silently ignored. + */ + u32 use_adaptive_rx_coalesce; + u32 use_adaptive_tx_coalesce; + + /* When the packet rate (measured in packets per second) + * is below pkt_rate_low, the {rx,tx}_*_low parameters are + * used. + */ + u32 pkt_rate_low; + u32 rx_coalesce_usecs_low; + u32 rx_max_coalesced_frames_low; + u32 tx_coalesce_usecs_low; + u32 tx_max_coalesced_frames_low; + + /* When the packet rate is below pkt_rate_high but above + * pkt_rate_low (both measured in packets per second) the + * normal {rx,tx}_* coalescing parameters are used. + */ + + /* When the packet rate is (measured in packets per second) + * is above pkt_rate_high, the {rx,tx}_*_high parameters are + * used. + */ + u32 pkt_rate_high; + u32 rx_coalesce_usecs_high; + u32 rx_max_coalesced_frames_high; + u32 tx_coalesce_usecs_high; + u32 tx_max_coalesced_frames_high; + + /* How often to do adaptive coalescing packet rate sampling, + * measured in seconds. Must not be zero. + */ + u32 rate_sample_interval; +}; +#endif /* ETHTOOL_GCOALESCE */ + +#ifndef ETHTOOL_SCOALESCE +#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */ +#endif +#ifndef ETHTOOL_GRINGPARAM +#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ +/* for configuring RX/TX ring parameters */ +#define ethtool_ringparam _kc_ethtool_ringparam +struct _kc_ethtool_ringparam { + u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */ + + /* Read only attributes. These indicate the maximum number + * of pending RX/TX ring entries the driver will allow the + * user to set. + */ + u32 rx_max_pending; + u32 rx_mini_max_pending; + u32 rx_jumbo_max_pending; + u32 tx_max_pending; + + /* Values changeable by the user. The valid values are + * in the range 1 to the "*_max_pending" counterpart above. + */ + u32 rx_pending; + u32 rx_mini_pending; + u32 rx_jumbo_pending; + u32 tx_pending; +}; +#endif /* ETHTOOL_GRINGPARAM */ + +#ifndef ETHTOOL_SRINGPARAM +#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ +#endif +#ifndef ETHTOOL_GPAUSEPARAM +#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ +/* for configuring link flow control parameters */ +#define ethtool_pauseparam _kc_ethtool_pauseparam +struct _kc_ethtool_pauseparam { + u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ + + /* If the link is being auto-negotiated (via ethtool_cmd.autoneg + * being true) the user may set 'autoneg' here non-zero to have the + * pause parameters be auto-negotiated too. In such a case, the + * {rx,tx}_pause values below determine what capabilities are + * advertised. + * + * If 'autoneg' is zero or the link is not being auto-negotiated, + * then {rx,tx}_pause force the driver to use/not-use pause + * flow control. + */ + u32 autoneg; + u32 rx_pause; + u32 tx_pause; +}; +#endif /* ETHTOOL_GPAUSEPARAM */ + +#ifndef ETHTOOL_SPAUSEPARAM +#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */ +#endif +#ifndef ETHTOOL_GRXCSUM +#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_SRXCSUM +#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_GTXCSUM +#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_STXCSUM +#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_GSG +#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable + * (ethtool_value) */ +#endif +#ifndef ETHTOOL_SSG +#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable + * (ethtool_value). */ +#endif +#ifndef ETHTOOL_TEST +#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */ +#endif +#ifndef ETHTOOL_GSTRINGS +#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ +#endif +#ifndef ETHTOOL_PHYS_ID +#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ +#endif +#ifndef ETHTOOL_GSTATS +#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ +#endif +#ifndef ETHTOOL_GTSO +#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_STSO +#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ +#endif + +#ifndef ETHTOOL_BUSINFO_LEN +#define ETHTOOL_BUSINFO_LEN 32 +#endif + +#if defined(HAVE_ETHTOOL_SUPPORTED_RING_PARAMS) && !defined(NEED_ETHTOOL_RING_USE_TCP_DATA_SPLIT) +/** + * enum _kc_ethtool_supported_ring_param - indicator caps for setting ring params + * @ETHTOOL_RING_USE_TCP_DATA_SPLIT: capture for setting tcp_data_split + */ +enum _kc_ethtool_supported_ring_param { + ETHTOOL_RING_USE_TCP_DATA_SPLIT = BIT(5), +}; +#endif + +#ifndef WAKE_FILTER +#define WAKE_FILTER BIT(7) +#endif + +#ifndef SPEED_2500 +#define SPEED_2500 2500 +#endif +#ifndef SPEED_5000 +#define SPEED_5000 5000 +#endif +#ifndef SPEED_14000 +#define SPEED_14000 14000 +#endif +#ifndef SPEED_25000 +#define SPEED_25000 25000 +#endif +#ifndef SPEED_50000 +#define SPEED_50000 50000 +#endif +#ifndef SPEED_56000 +#define SPEED_56000 56000 +#endif +#ifndef SPEED_100000 +#define SPEED_100000 100000 +#endif +#ifndef SPEED_200000 +#define SPEED_200000 200000 +#endif + +#ifndef RHEL_RELEASE_VERSION +#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b)) +#endif +#ifndef AX_RELEASE_VERSION +#define AX_RELEASE_VERSION(a,b) (((a) << 8) + (b)) +#endif + +#ifndef AX_RELEASE_CODE +#define AX_RELEASE_CODE 0 +#endif + +#if (AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3,0)) +#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5,0) +#elif (AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3,1)) +#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5,1) +#elif (AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3,2)) +#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5,3) +#endif + +#ifndef RHEL_RELEASE_CODE +/* NOTE: RHEL_RELEASE_* introduced in RHEL4.5 */ +#define RHEL_RELEASE_CODE 0 +#endif + +/* RHEL 7 didn't backport the parameter change in + * create_singlethread_workqueue. + * If/when RH corrects this we will want to tighten up the version check. + */ +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,0)) +#undef create_singlethread_workqueue +#define create_singlethread_workqueue(name) \ + alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, name) +#endif + +/* Ubuntu Release ABI is the 4th digit of their kernel version. You can find + * it in /usr/src/linux/$(uname -r)/include/generated/utsrelease.h for new + * enough versions of Ubuntu. Otherwise you can simply see it in the output of + * uname as the 4th digit of the kernel. The UTS_UBUNTU_RELEASE_ABI is not in + * the linux-source package, but in the linux-headers package. It begins to + * appear in later releases of 14.04 and 14.10. + * + * Ex: + * + * $uname -r + * 3.13.0-45-generic + * ABI is 45 + * + * + * $uname -r + * 3.16.0-23-generic + * ABI is 23 + */ +#ifndef UTS_UBUNTU_RELEASE_ABI +#define UTS_UBUNTU_RELEASE_ABI 0 +#define UBUNTU_VERSION_CODE 0 +#else +/* Ubuntu does not provide actual release version macro, so we use the kernel + * version plus the ABI to generate a unique version code specific to Ubuntu. + * In addition, we mask the lower 8 bits of LINUX_VERSION_CODE in order to + * ignore differences in sublevel which are not important since we have the + * ABI value. Otherwise, it becomes impossible to correlate ABI to version for + * ordering checks. + * + * This also lets us store an ABI value up to 65535, since it can take the + * space that would use the lower byte of the Linux version code. + */ +#define UBUNTU_VERSION_CODE (((~0xFF & LINUX_VERSION_CODE) << 8) + \ + UTS_UBUNTU_RELEASE_ABI) + +#if UTS_UBUNTU_RELEASE_ABI > 65535 +#error UTS_UBUNTU_RELEASE_ABI is larger than 65535... +#endif /* UTS_UBUNTU_RELEASE_ABI > 65535 */ + +#if ( LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,0) ) +/* Our version code scheme does not make sense for non 3.x or newer kernels, + * and we have no support in kcompat for this scenario. Thus, treat this as a + * non-Ubuntu kernel. Possibly might be better to error here. + */ +#define UTS_UBUNTU_RELEASE_ABI 0 +#define UBUNTU_VERSION_CODE 0 +#endif /* <= 3.0.0 */ +#endif /* !UTS_UBUNTU_RELEASE_ABI */ + +/* We ignore the 3rd digit since we want to give precedence to the additional + * ABI value provided by Ubuntu. + */ +#define UBUNTU_VERSION(a,b,c,d) (((a) << 24) + ((b) << 16) + (d)) + +/* SLE_VERSION is used to generate a 3-digit encoding that can order SLE + * kernels based on their major release, service pack, and a possible + * maintenance release. + */ +#define SLE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +/* The SLE_LOCALVERSION_CODE comes from a 3-digit code added as part of the + * Linux kernel version. It is extracted by the driver Makefile. This macro is + * used to generate codes for making comparisons below. + */ +#define SLE_LOCALVERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +#ifdef CONFIG_SUSE_KERNEL +/* Starting since at least SLE 12sp4 and SLE 15, the SUSE kernels have + * provided CONFIG_SUSE_VERSION, CONFIG_SUSE_PATCHLEVEL and + * CONFIG_SUSE_AUXRELEASE. Use these to generate SLE_VERSION if available. + * Only fall back to the manual table otherwise. We expect all future versions + * of SLE kernels to include these values, so the table will remain only for + * the older releases. + */ +#ifdef CONFIG_SUSE_VERSION +#ifndef CONFIG_SUSE_PATCHLEVEL +#error "CONFIG_SUSE_VERSION exists but CONFIG_SUSE_PATCHLEVEL is missing" +#endif +#ifndef CONFIG_SUSE_AUXRELEASE +#error "CONFIG_SUSE_VERSION exists but CONFIG_SUSE_AUXRELEASE is missing" +#endif +#define SLE_VERSION_CODE SLE_VERSION(CONFIG_SUSE_VERSION, CONFIG_SUSE_PATCHLEVEL, CONFIG_SUSE_AUXRELEASE) +#else +/* If we do not have the CONFIG_SUSE_VERSION configuration values, fall back + * to the following table for older releases. + */ +#if ( LINUX_VERSION_CODE == KERNEL_VERSION(2,6,27) ) +/* SLES11 GA is 2.6.27 based */ +#define SLE_VERSION_CODE SLE_VERSION(11,0,0) +#elif ( LINUX_VERSION_CODE == KERNEL_VERSION(2,6,32) ) +/* SLES11 SP1 is 2.6.32 based */ +#define SLE_VERSION_CODE SLE_VERSION(11,1,0) +#elif ( LINUX_VERSION_CODE == KERNEL_VERSION(3,0,13) ) +/* SLES11 SP2 GA is 3.0.13-0.27 */ +#define SLE_VERSION_CODE SLE_VERSION(11,2,0) +#elif ((LINUX_VERSION_CODE == KERNEL_VERSION(3,0,76))) +/* SLES11 SP3 GA is 3.0.76-0.11 */ +#define SLE_VERSION_CODE SLE_VERSION(11,3,0) +#elif (LINUX_VERSION_CODE == KERNEL_VERSION(3,0,101)) + #if (SLE_LOCALVERSION_CODE < SLE_LOCALVERSION(0,8,0)) + /* some SLES11sp2 update kernels up to 3.0.101-0.7.x */ + #define SLE_VERSION_CODE SLE_VERSION(11,2,0) + #elif (SLE_LOCALVERSION_CODE < SLE_LOCALVERSION(63,0,0)) + /* most SLES11sp3 update kernels */ + #define SLE_VERSION_CODE SLE_VERSION(11,3,0) + #else + /* SLES11 SP4 GA (3.0.101-63) and update kernels 3.0.101-63+ */ + #define SLE_VERSION_CODE SLE_VERSION(11,4,0) + #endif +#elif (LINUX_VERSION_CODE == KERNEL_VERSION(3,12,28)) +/* SLES12 GA is 3.12.28-4 + * kernel updates 3.12.xx-<33 through 52>[.yy] */ +#define SLE_VERSION_CODE SLE_VERSION(12,0,0) +#elif (LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)) +/* SLES12 SP1 GA is 3.12.49-11 + * updates 3.12.xx-60.yy where xx={51..} */ +#define SLE_VERSION_CODE SLE_VERSION(12,1,0) +#elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,21) && \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(4,4,59))) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,74) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) && \ + SLE_LOCALVERSION_CODE >= KERNEL_VERSION(92,0,0) && \ + SLE_LOCALVERSION_CODE < KERNEL_VERSION(93,0,0))) +/* SLES12 SP2 GA is 4.4.21-69. + * SLES12 SP2 updates before SLES12 SP3 are: 4.4.{21,38,49,59} + * SLES12 SP2 updates after SLES12 SP3 are: 4.4.{74,90,103,114,120} + * but they all use a SLE_LOCALVERSION_CODE matching 92.nn.y */ +#define SLE_VERSION_CODE SLE_VERSION(12,2,0) +#elif ((LINUX_VERSION_CODE == KERNEL_VERSION(4,4,73) || \ + LINUX_VERSION_CODE == KERNEL_VERSION(4,4,82) || \ + LINUX_VERSION_CODE == KERNEL_VERSION(4,4,92)) || \ + (LINUX_VERSION_CODE == KERNEL_VERSION(4,4,103) && \ + (SLE_LOCALVERSION_CODE == KERNEL_VERSION(6,33,0) || \ + SLE_LOCALVERSION_CODE == KERNEL_VERSION(6,38,0))) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,114) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) && \ + SLE_LOCALVERSION_CODE >= KERNEL_VERSION(94,0,0) && \ + SLE_LOCALVERSION_CODE < KERNEL_VERSION(95,0,0)) ) +/* SLES12 SP3 GM is 4.4.73-5 and update kernels are 4.4.82-6.3. + * SLES12 SP3 updates not conflicting with SP2 are: 4.4.{82,92} + * SLES12 SP3 updates conflicting with SP2 are: + * - 4.4.103-6.33.1, 4.4.103-6.38.1 + * - 4.4.{114,120}-94.nn.y */ +#define SLE_VERSION_CODE SLE_VERSION(12,3,0) +#else +#error "This looks like a SUSE kernel, but it has an unrecognized local version code." +#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(x,y,z) */ +#endif /* !CONFIG_SUSE_VERSION */ +#endif /* CONFIG_SUSE_KERNEL */ +#ifndef SLE_VERSION_CODE +#define SLE_VERSION_CODE 0 +#endif /* SLE_VERSION_CODE */ +#ifndef SLE_LOCALVERSION_CODE +#define SLE_LOCALVERSION_CODE 0 +#endif /* SLE_LOCALVERSION_CODE */ + +/* Include definitions from the new kcompat layout */ +#include "kcompat_defs.h" + +#ifdef NEED_FLOW_CLS_OFFLOAD +#define flow_block_offload tc_block_offload +#define flow_block_command tc_block_command +#define flow_cls_offload tc_cls_flower_offload +#define flow_block_binder_type tcf_block_binder_type +#define flow_cls_common_offload tc_cls_common_offload +#define flow_cls_offload_flow_rule tc_cls_flower_offload_flow_rule +#endif + +/* + * ADQ depends on __TC_MQPRIO_MODE_MAX and related kernel code + * added around 4.15. Some distributions (e.g. Oracle Linux 7.7) + * have done a partial back-port of that to their kernels based + * on older mainline kernels that did not include all the necessary + * kernel enablement to support ADQ. + * Undefine __TC_MQPRIO_MODE_MAX for all OSV distributions with + * kernels based on mainline kernels older than 4.15 except for + * RHEL, SLES and Ubuntu which are known to have good back-ports. + */ +#if (!RHEL_RELEASE_CODE && !SLE_VERSION_CODE && !UBUNTU_VERSION_CODE) + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) + #undef __TC_MQPRIO_MODE_MAX + #endif /* LINUX_VERSION_CODE == KERNEL_VERSION(4,15,0) */ +#endif /* if (NOT RHEL && NOT SLES && NOT UBUNTU) */ + +#ifdef __KLOCWORK__ +#ifdef ARRAY_SIZE +#undef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#define memcpy(dest, src, len) memcpy_s(dest, len, src, len) +#define memset(dest, ch, len) memset_s(dest, len, ch, len) + +static inline int _kc_test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + unsigned long flags = 0; + + _atomic_spin_lock_irqsave(p, flags); + old = *p; + *p = old & ~mask; + _atomic_spin_unlock_irqrestore(p, flags); + + return (old & mask) != 0; +} +#define test_and_clear_bit(nr, addr) _kc_test_and_clear_bit(nr, addr) + +static inline int _kc_test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + unsigned long flags = 0; + + _atomic_spin_lock_irqsave(p, flags); + old = *p; + *p = old | mask; + _atomic_spin_unlock_irqrestore(p, flags); + + return (old & mask) != 0; +} +#define test_and_set_bit(nr, addr) _kc_test_and_set_bit(nr, addr) + +#ifdef CONFIG_DYNAMIC_DEBUG +#undef dev_dbg +#define dev_dbg(dev, format, arg...) dev_printk(KERN_DEBUG, dev, format, ##arg) +#undef pr_debug +#define pr_debug(format, arg...) printk(KERN_DEBUG format, ##arg) +#endif /* CONFIG_DYNAMIC_DEBUG */ + +#undef hlist_for_each_entry_safe +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (n = NULL, pos = hlist_entry_safe((head)->first, typeof(*(pos)), \ + member); \ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +#ifdef uninitialized_var +#undef uninitialized_var +#define uninitialized_var(x) x = *(&(x)) +#endif + +#ifdef WRITE_ONCE +#undef WRITE_ONCE +#define WRITE_ONCE(x, val) ((x) = (val)) +#endif /* WRITE_ONCE */ + +#ifdef wait_event_interruptible_timeout +#undef wait_event_interruptible_timeout +#define wait_event_interruptible_timeout(wq_head, condition, timeout) ({ \ + long ret; \ + if ((condition)) \ + ret = timeout; \ + else \ + ret = 0; \ + ret; \ +}) +#endif /* wait_event_interruptible_timeout */ + +#ifdef max_t +#undef max_t +#define max_t(type, x, y) ({ \ +type __x = (x); \ +type __y = (y); \ +__x > __y ? __x : __y; \ +}) +#endif /* max_t */ + +#ifdef min_t +#undef min_t +#define min_t(type, x, y) ({ \ +type __x = (x); \ +type __y = (y); \ +__x < __y ? __x : __y; \ +}) +#endif /* min_t */ +#endif /* __KLOCWORK__ */ + +/* Older versions of GCC will trigger -Wformat-nonliteral warnings for const + * char * strings. Unfortunately, the implementation of do_trace_printk does + * this, in order to add a storage attribute to the memory. This was fixed in + * GCC 5.1, but we still use older distributions built with GCC 4.x. + * + * The string pointer is only passed as a const char * to the __trace_bprintk + * function. Since that function has the __printf attribute, it will trigger + * the warnings. We can't remove the attribute, so instead we'll use the + * __diag macro to disable -Wformat-nonliteral around the call to + * __trace_bprintk. + */ +#if GCC_VERSION < 50100 +#define __trace_bprintk(ip, fmt, args...) ({ \ + int err; \ + __diag_push(); \ + __diag(ignored "-Wformat-nonliteral"); \ + err = __trace_bprintk(ip, fmt, ##args); \ + __diag_pop(); \ + err; \ +}) +#endif /* GCC_VERSION < 5.1.0 */ + +/* Newer kernels removed */ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)) && \ + (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,3)) && \ + !(SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(15,3,0))))) +#define HAVE_PCI_ASPM_H +#endif + +/*****************************************************************************/ +/* 2.4.3 => 2.4.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) ) + +/**************************************/ +/* PCI DRIVER API */ + +#ifndef pci_set_dma_mask +#define pci_set_dma_mask _kc_pci_set_dma_mask +int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask); +#endif + +#ifndef pci_request_regions +#define pci_request_regions _kc_pci_request_regions +int _kc_pci_request_regions(struct pci_dev *pdev, char *res_name); +#endif + +#ifndef pci_release_regions +#define pci_release_regions _kc_pci_release_regions +void _kc_pci_release_regions(struct pci_dev *pdev); +#endif + +/**************************************/ +/* NETWORK DRIVER API */ + +#ifndef alloc_etherdev +#define alloc_etherdev _kc_alloc_etherdev +struct net_device * _kc_alloc_etherdev(int sizeof_priv); +#endif + +#ifndef is_valid_ether_addr +#define is_valid_ether_addr _kc_is_valid_ether_addr +int _kc_is_valid_ether_addr(u8 *addr); +#endif + +/**************************************/ +/* MISCELLANEOUS */ + +#ifndef INIT_TQUEUE +#define INIT_TQUEUE(_tq, _routine, _data) \ + do { \ + INIT_LIST_HEAD(&(_tq)->list); \ + (_tq)->sync = 0; \ + (_tq)->routine = _routine; \ + (_tq)->data = _data; \ + } while (0) +#endif + +#endif /* 2.4.3 => 2.4.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) ) +/* Generic MII registers. */ +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +/* Basic mode control register. */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +/* Advertisement control register. */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) +/* Expansion register for auto-negotiation. */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#endif + +/*****************************************************************************/ +/* 2.4.6 => 2.4.3 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) ) + +#ifndef pci_set_power_state +#define pci_set_power_state _kc_pci_set_power_state +int _kc_pci_set_power_state(struct pci_dev *dev, int state); +#endif + +#ifndef pci_enable_wake +#define pci_enable_wake _kc_pci_enable_wake +int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable); +#endif + +#ifndef pci_disable_device +#define pci_disable_device _kc_pci_disable_device +void _kc_pci_disable_device(struct pci_dev *pdev); +#endif + +/* PCI PM entry point syntax changed, so don't support suspend/resume */ +#undef CONFIG_PM + +#endif /* 2.4.6 => 2.4.3 */ + +#ifndef HAVE_PCI_SET_MWI +#define pci_set_mwi(X) pci_write_config_word(X, \ + PCI_COMMAND, adapter->hw.bus.pci_cmd_word | \ + PCI_COMMAND_INVALIDATE); +#define pci_clear_mwi(X) pci_write_config_word(X, \ + PCI_COMMAND, adapter->hw.bus.pci_cmd_word & \ + ~PCI_COMMAND_INVALIDATE); +#endif + +/*****************************************************************************/ +/* 2.4.10 => 2.4.9 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) ) + +/**************************************/ +/* MODULE API */ + +#ifndef MODULE_LICENSE + #define MODULE_LICENSE(X) +#endif + +/**************************************/ +/* OTHER */ + +#undef min +#define min(x,y) ({ \ + const typeof(x) _x = (x); \ + const typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x < _y ? _x : _y; }) + +#undef max +#define max(x,y) ({ \ + const typeof(x) _x = (x); \ + const typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x > _y ? _x : _y; }) + +#define min_t(type,x,y) ({ \ + type _x = (x); \ + type _y = (y); \ + _x < _y ? _x : _y; }) + +#define max_t(type,x,y) ({ \ + type _x = (x); \ + type _y = (y); \ + _x > _y ? _x : _y; }) + +#ifndef list_for_each_safe +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) +#endif + +#ifndef ____cacheline_aligned_in_smp +#ifdef CONFIG_SMP +#define ____cacheline_aligned_in_smp ____cacheline_aligned +#else +#define ____cacheline_aligned_in_smp +#endif /* CONFIG_SMP */ +#endif + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) ) +int _kc_snprintf(char * buf, size_t size, const char *fmt, ...); +#define snprintf(buf, size, fmt, args...) _kc_snprintf(buf, size, fmt, ##args) +int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args); +#define vsnprintf(buf, size, fmt, args) _kc_vsnprintf(buf, size, fmt, args) +#else /* 2.4.8 => 2.4.9 */ +int snprintf(char * buf, size_t size, const char *fmt, ...); +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); +#endif +#endif /* 2.4.10 -> 2.4.6 */ + +/*****************************************************************************/ +/* 2.4.12 => 2.4.10 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,12) ) +#ifndef HAVE_NETIF_MSG +#define HAVE_NETIF_MSG 1 +enum { + NETIF_MSG_DRV = 0x0001, + NETIF_MSG_PROBE = 0x0002, + NETIF_MSG_LINK = 0x0004, + NETIF_MSG_TIMER = 0x0008, + NETIF_MSG_IFDOWN = 0x0010, + NETIF_MSG_IFUP = 0x0020, + NETIF_MSG_RX_ERR = 0x0040, + NETIF_MSG_TX_ERR = 0x0080, + NETIF_MSG_TX_QUEUED = 0x0100, + NETIF_MSG_INTR = 0x0200, + NETIF_MSG_TX_DONE = 0x0400, + NETIF_MSG_RX_STATUS = 0x0800, + NETIF_MSG_PKTDATA = 0x1000, + NETIF_MSG_HW = 0x2000, + NETIF_MSG_WOL = 0x4000, +}; + +#define netif_msg_drv(p) ((p)->msg_enable & NETIF_MSG_DRV) +#define netif_msg_probe(p) ((p)->msg_enable & NETIF_MSG_PROBE) +#define netif_msg_link(p) ((p)->msg_enable & NETIF_MSG_LINK) +#define netif_msg_timer(p) ((p)->msg_enable & NETIF_MSG_TIMER) +#define netif_msg_ifdown(p) ((p)->msg_enable & NETIF_MSG_IFDOWN) +#define netif_msg_ifup(p) ((p)->msg_enable & NETIF_MSG_IFUP) +#define netif_msg_rx_err(p) ((p)->msg_enable & NETIF_MSG_RX_ERR) +#define netif_msg_tx_err(p) ((p)->msg_enable & NETIF_MSG_TX_ERR) +#define netif_msg_tx_queued(p) ((p)->msg_enable & NETIF_MSG_TX_QUEUED) +#define netif_msg_intr(p) ((p)->msg_enable & NETIF_MSG_INTR) +#define netif_msg_tx_done(p) ((p)->msg_enable & NETIF_MSG_TX_DONE) +#define netif_msg_rx_status(p) ((p)->msg_enable & NETIF_MSG_RX_STATUS) +#define netif_msg_pktdata(p) ((p)->msg_enable & NETIF_MSG_PKTDATA) +#endif /* !HAVE_NETIF_MSG */ +#endif /* 2.4.12 => 2.4.10 */ + +/*****************************************************************************/ +/* 2.4.13 => 2.4.12 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) ) + +/**************************************/ +/* PCI DMA MAPPING */ + +#ifndef virt_to_page + #define virt_to_page(v) (mem_map + (virt_to_phys(v) >> PAGE_SHIFT)) +#endif + +#ifndef pci_map_page +#define pci_map_page _kc_pci_map_page +u64 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, size_t size, int direction); +#endif + +#ifndef pci_unmap_page +#define pci_unmap_page _kc_pci_unmap_page +void _kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size, int direction); +#endif + +/* pci_set_dma_mask takes dma_addr_t, which is only 32-bits prior to 2.4.13 */ + +#undef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0xffffffff +#undef DMA_64BIT_MASK +#define DMA_64BIT_MASK 0xffffffff + +/**************************************/ +/* OTHER */ + +#ifndef cpu_relax +#define cpu_relax() rep_nop() +#endif + +struct vlan_ethhdr { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + unsigned short h_vlan_proto; + unsigned short h_vlan_TCI; + unsigned short h_vlan_encapsulated_proto; +}; +#endif /* 2.4.13 => 2.4.12 */ + +/*****************************************************************************/ +/* 2.4.17 => 2.4.12 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17) ) + +#ifndef __devexit_p + #define __devexit_p(x) &(x) +#endif + +#endif /* 2.4.17 => 2.4.13 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) ) +#define NETIF_MSG_HW 0x2000 +#define NETIF_MSG_WOL 0x4000 + +#ifndef netif_msg_hw +#define netif_msg_hw(p) ((p)->msg_enable & NETIF_MSG_HW) +#endif +#ifndef netif_msg_wol +#define netif_msg_wol(p) ((p)->msg_enable & NETIF_MSG_WOL) +#endif +#endif /* 2.4.18 */ + +/*****************************************************************************/ + +/*****************************************************************************/ +/* 2.4.20 => 2.4.19 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20) ) + +/* we won't support NAPI on less than 2.4.20 */ +#ifdef NAPI +#undef NAPI +#endif + +#endif /* 2.4.20 => 2.4.19 */ + +/*****************************************************************************/ +/* 2.4.22 => 2.4.17 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) +#define pci_name(x) ((x)->slot_name) +#define cpu_online(cpuid) test_bit((cpuid), &cpu_online_map) + +#ifndef SUPPORTED_10000baseT_Full +#define SUPPORTED_10000baseT_Full BIT(12) +#endif +#ifndef ADVERTISED_10000baseT_Full +#define ADVERTISED_10000baseT_Full BIT(12) +#endif +#endif + +/*****************************************************************************/ +/* 2.4.22 => 2.4.17 */ + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) +#endif + +/*****************************************************************************/ +/*****************************************************************************/ +/* 2.4.23 => 2.4.22 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) ) +/*****************************************************************************/ +#ifdef NAPI +#ifndef netif_poll_disable +#define netif_poll_disable(x) _kc_netif_poll_disable(x) +static inline void _kc_netif_poll_disable(struct net_device *netdev) +{ + while (test_and_set_bit(__LINK_STATE_RX_SCHED, &netdev->state)) { + /* No hurry */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + } +} +#endif +#ifndef netif_poll_enable +#define netif_poll_enable(x) _kc_netif_poll_enable(x) +static inline void _kc_netif_poll_enable(struct net_device *netdev) +{ + clear_bit(__LINK_STATE_RX_SCHED, &netdev->state); +} +#endif +#endif /* NAPI */ +#ifndef netif_tx_disable +#define netif_tx_disable(x) _kc_netif_tx_disable(x) +static inline void _kc_netif_tx_disable(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); + netif_stop_queue(dev); + spin_unlock_bh(&dev->xmit_lock); +} +#endif +#else /* 2.4.23 => 2.4.22 */ +#define HAVE_SCTP +#endif /* 2.4.23 => 2.4.22 */ + +/*****************************************************************************/ +/* 2.6.4 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) || \ + ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) ) +#define ETHTOOL_OPS_COMPAT +#endif /* 2.6.4 => 2.6.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) +#define __user +#endif /* < 2.4.27 */ + +/*****************************************************************************/ +/* 2.5.71 => 2.4.x */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) ) +#define sk_protocol protocol +#define pci_get_device pci_find_device +#endif /* 2.5.70 => 2.4.x */ + +/*****************************************************************************/ +/* < 2.4.27 or 2.6.0 <= 2.6.5 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) || \ + ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) ) + +#ifndef netif_msg_init +#define netif_msg_init _kc_netif_msg_init +static inline u32 _kc_netif_msg_init(int debug_value, int default_msg_enable_bits) +{ + /* use default */ + if (debug_value < 0 || debug_value >= (sizeof(u32) * 8)) + return default_msg_enable_bits; + if (debug_value == 0) /* no output */ + return 0; + /* set low N bits */ + return (1 << debug_value) -1; +} +#endif + +#endif /* < 2.4.27 or 2.6.0 <= 2.6.5 */ +/*****************************************************************************/ +#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \ + (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \ + ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ))) +#define netdev_priv(x) x->priv +#endif + +/*****************************************************************************/ +/* <= 2.5.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ) +#include +#undef pci_register_driver +#define pci_register_driver pci_module_init + +/* + * Most of the dma compat code is copied/modifed from the 2.4.37 + * /include/linux/libata-compat.h header file + */ +/* These definitions mirror those in pci.h, so they can be used + * interchangeably with their PCI_ counterparts */ +enum dma_data_direction { + DMA_BIDIRECTIONAL = 0, + DMA_TO_DEVICE = 1, + DMA_FROM_DEVICE = 2, + DMA_NONE = 3, +}; + +struct device { + struct pci_dev pdev; +}; + +static inline struct pci_dev *to_pci_dev (struct device *dev) +{ + return (struct pci_dev *) dev; +} +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) +{ + return (struct device *) pdev; +} +#define pdev_printk(lvl, pdev, fmt, args...) \ + printk("%s %s: " fmt, lvl, pci_name(pdev), ## args) +#define dev_err(dev, fmt, args...) \ + pdev_printk(KERN_ERR, to_pci_dev(dev), fmt, ## args) +#define dev_info(dev, fmt, args...) \ + pdev_printk(KERN_INFO, to_pci_dev(dev), fmt, ## args) +#define dev_warn(dev, fmt, args...) \ + pdev_printk(KERN_WARNING, to_pci_dev(dev), fmt, ## args) +#define dev_notice(dev, fmt, args...) \ + pdev_printk(KERN_NOTICE, to_pci_dev(dev), fmt, ## args) +#define dev_dbg(dev, fmt, args...) \ + pdev_printk(KERN_DEBUG, to_pci_dev(dev), fmt, ## args) + +/* NOTE: dangerous! we ignore the 'gfp' argument */ +#define dma_alloc_coherent(dev,sz,dma,gfp) \ + pci_alloc_consistent(to_pci_dev(dev),(sz),(dma)) +#define dma_free_coherent(dev,sz,addr,dma_addr) \ + pci_free_consistent(to_pci_dev(dev),(sz),(addr),(dma_addr)) + +#define dma_map_page(dev,a,b,c,d) \ + pci_map_page(to_pci_dev(dev),(a),(b),(c),(d)) +#define dma_unmap_page(dev,a,b,c) \ + pci_unmap_page(to_pci_dev(dev),(a),(b),(c)) + +#define dma_map_single(dev,a,b,c) \ + pci_map_single(to_pci_dev(dev),(a),(b),(c)) +#define dma_unmap_single(dev,a,b,c) \ + pci_unmap_single(to_pci_dev(dev),(a),(b),(c)) + +#define dma_map_sg(dev, sg, nents, dir) \ + pci_map_sg(to_pci_dev(dev), (sg), (nents), (dir) +#define dma_unmap_sg(dev, sg, nents, dir) \ + pci_unmap_sg(to_pci_dev(dev), (sg), (nents), (dir) + +#define dma_sync_single(dev,a,b,c) \ + pci_dma_sync_single(to_pci_dev(dev),(a),(b),(c)) + +/* for range just sync everything, that's all the pci API can do */ +#define dma_sync_single_range(dev,addr,off,sz,dir) \ + pci_dma_sync_single(to_pci_dev(dev),(addr),(off)+(sz),(dir)) + +#define dma_set_mask(dev,mask) \ + pci_set_dma_mask(to_pci_dev(dev),(mask)) + +/* hlist_* code - double linked lists */ +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +static inline void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + *pprev = next; + if (next) + next->pprev = pprev; +} + +static inline void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = NULL; + n->pprev = NULL; +} + +static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + if (first) + first->pprev = &n->next; + h->first = n; + n->pprev = &h->first; +} + +static inline int hlist_empty(const struct hlist_head *h) +{ + return !h->first; +} +#define HLIST_HEAD_INIT { .first = NULL } +#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +static inline void INIT_HLIST_NODE(struct hlist_node *h) +{ + h->next = NULL; + h->pprev = NULL; +} + +#ifndef might_sleep +#define might_sleep() +#endif +#else +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) +{ + return &pdev->dev; +} +#endif /* <= 2.5.0 */ + +/*****************************************************************************/ +/* 2.5.28 => 2.4.23 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) + +#include +#define work_struct tq_struct +#undef INIT_WORK +#define INIT_WORK(a,b) INIT_TQUEUE(a,(void (*)(void *))b,a) +#undef container_of +#define container_of list_entry +#define schedule_work schedule_task +#define flush_scheduled_work flush_scheduled_tasks +#define cancel_work_sync(x) flush_scheduled_work() + +#endif /* 2.5.28 => 2.4.17 */ + +/*****************************************************************************/ +/* 2.6.0 => 2.5.28 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#ifndef read_barrier_depends +#define read_barrier_depends() rmb() +#endif + +#ifndef rcu_head +struct __kc_callback_head { + struct __kc_callback_head *next; + void (*func)(struct callback_head *head); +}; +#define rcu_head __kc_callback_head +#endif + +#undef get_cpu +#define get_cpu() smp_processor_id() +#undef put_cpu +#define put_cpu() do { } while(0) +#define MODULE_INFO(version, _version) +#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT +#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1 +#endif +#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT +#define CONFIG_IGB_DISABLE_PACKET_SPLIT 1 +#endif +#ifndef CONFIG_IGC_DISABLE_PACKET_SPLIT +#define CONFIG_IGC_DISABLE_PACKET_SPLIT 1 +#endif + +#define dma_set_coherent_mask(dev,mask) 1 + +#undef dev_put +#define dev_put(dev) __dev_put(dev) + +#ifndef skb_fill_page_desc +#define skb_fill_page_desc _kc_skb_fill_page_desc +void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size); +#endif + +#undef ALIGN +#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) + +#ifndef page_count +#define page_count(p) atomic_read(&(p)->count) +#endif + +#ifdef MAX_NUMNODES +#undef MAX_NUMNODES +#endif +#define MAX_NUMNODES 1 + +/* find_first_bit and find_next bit are not defined for most + * 2.4 kernels (except for the redhat 2.4.21 kernels + */ +#include +#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) +#undef find_next_bit +#define find_next_bit _kc_find_next_bit +unsigned long _kc_find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset); +#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) + +#ifndef netdev_name +static inline const char *_kc_netdev_name(const struct net_device *dev) +{ + if (strchr(dev->name, '%')) + return "(unregistered net_device)"; + return dev->name; +} +#define netdev_name(netdev) _kc_netdev_name(netdev) +#endif /* netdev_name */ + +#ifndef strlcpy +#define strlcpy _kc_strlcpy +size_t _kc_strlcpy(char *dest, const char *src, size_t size); +#endif /* strlcpy */ + +#ifndef do_div +#if BITS_PER_LONG == 64 +# define do_div(n,base) ({ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ + }) +#elif BITS_PER_LONG == 32 +uint32_t _kc__div64_32(uint64_t *dividend, uint32_t divisor); +# define do_div(n,base) ({ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + if (likely(((n) >> 32) == 0)) { \ + __rem = (uint32_t)(n) % __base; \ + (n) = (uint32_t)(n) / __base; \ + } else \ + __rem = _kc__div64_32(&(n), __base); \ + __rem; \ + }) +#else /* BITS_PER_LONG == ?? */ +# error do_div() does not yet support the C64 +#endif /* BITS_PER_LONG */ +#endif /* do_div */ + +#ifndef NSEC_PER_SEC +#define NSEC_PER_SEC 1000000000L +#endif + +#undef HAVE_I2C_SUPPORT +#else /* 2.6.0 */ + +#endif /* 2.6.0 => 2.5.28 */ +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ) +#define dma_pool pci_pool +#define dma_pool_destroy pci_pool_destroy +#define dma_pool_alloc pci_pool_alloc +#define dma_pool_free pci_pool_free + +#define dma_pool_create(name,dev,size,align,allocation) \ + pci_pool_create((name),to_pci_dev(dev),(size),(align),(allocation)) +#endif /* < 2.6.3 */ + +/*****************************************************************************/ +/* 2.6.4 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) +#define MODULE_VERSION(_version) MODULE_INFO(version, _version) +#endif /* 2.6.4 => 2.6.0 */ + +/*****************************************************************************/ +/* 2.6.5 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) +#define dma_sync_single_for_cpu dma_sync_single +#define dma_sync_single_for_device dma_sync_single +#define dma_sync_single_range_for_cpu dma_sync_single_range +#define dma_sync_single_range_for_device dma_sync_single_range +#ifndef pci_dma_mapping_error +#define pci_dma_mapping_error _kc_pci_dma_mapping_error +static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr) +{ + return dma_addr == 0; +} +#endif +#endif /* 2.6.5 => 2.6.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) +int _kc_scnprintf(char * buf, size_t size, const char *fmt, ...); +#define scnprintf(buf, size, fmt, args...) _kc_scnprintf(buf, size, fmt, ##args) +#endif /* < 2.6.4 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6) ) +/* taken from 2.6 include/linux/bitmap.h */ +#undef bitmap_zero +#define bitmap_zero _kc_bitmap_zero +static inline void _kc_bitmap_zero(unsigned long *dst, int nbits) +{ + if (nbits <= BITS_PER_LONG) + *dst = 0UL; + else { + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memset(dst, 0, len); + } +} +#define page_to_nid(x) 0 + +#endif /* < 2.6.6 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) ) +#undef if_mii +#define if_mii _kc_if_mii +static inline struct mii_ioctl_data *_kc_if_mii(struct ifreq *rq) +{ + return (struct mii_ioctl_data *) &rq->ifr_ifru; +} + +#ifndef __force +#define __force +#endif +#endif /* < 2.6.7 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ) +#ifndef PCI_EXP_DEVCTL +#define PCI_EXP_DEVCTL 8 +#endif +#ifndef PCI_EXP_DEVCTL_CERE +#define PCI_EXP_DEVCTL_CERE 0x0001 +#endif +#define PCI_EXP_FLAGS 2 /* Capabilities register */ +#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */ +#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ +#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */ +#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */ +#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ +#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ +#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ +#define PCI_EXP_DEVCAP 4 /* Device capabilities */ +#define PCI_EXP_DEVSTA 10 /* Device Status */ +#define msleep(x) do { set_current_state(TASK_UNINTERRUPTIBLE); \ + schedule_timeout((x * HZ)/1000 + 2); \ + } while (0) + +#endif /* < 2.6.8 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) +#include +#define __iomem + +#ifndef kcalloc +#define kcalloc(n, size, flags) _kc_kzalloc(((n) * (size)), flags) +void *_kc_kzalloc(size_t size, int flags); +#endif +#define MSEC_PER_SEC 1000L +static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j) +{ +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (MSEC_PER_SEC / HZ) * j; +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); +#else + return (j * MSEC_PER_SEC) / HZ; +#endif +} +static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m) +{ + if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return m * (HZ / MSEC_PER_SEC); +#else + return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; +#endif +} + +#define msleep_interruptible _kc_msleep_interruptible +static inline unsigned long _kc_msleep_interruptible(unsigned int msecs) +{ + unsigned long timeout = _kc_msecs_to_jiffies(msecs) + 1; + + while (timeout && !signal_pending(current)) { + __set_current_state(TASK_INTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } + return _kc_jiffies_to_msecs(timeout); +} + +/* Basic mode control register. */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ + +#ifndef __le16 +#define __le16 u16 +#endif +#ifndef __le32 +#define __le32 u32 +#endif +#ifndef __le64 +#define __le64 u64 +#endif +#ifndef __be16 +#define __be16 u16 +#endif +#ifndef __be32 +#define __be32 u32 +#endif +#ifndef __be64 +#define __be64 u64 +#endif + +static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) +{ + return (struct vlan_ethhdr *)skb->mac.raw; +} + +/* Wake-On-Lan options. */ +#define WAKE_PHY BIT(0) +#define WAKE_UCAST BIT(1) +#define WAKE_MCAST BIT(2) +#define WAKE_BCAST BIT(3) +#define WAKE_ARP BIT(4) +#define WAKE_MAGIC BIT(5) +#define WAKE_MAGICSECURE BIT(6) /* only meaningful if WAKE_MAGIC */ + +#define skb_header_pointer _kc_skb_header_pointer +static inline void *_kc_skb_header_pointer(const struct sk_buff *skb, + int offset, int len, void *buffer) +{ + int hlen = skb_headlen(skb); + + if (hlen - offset >= len) + return skb->data + offset; + +#ifdef MAX_SKB_FRAGS + if (skb_copy_bits(skb, offset, buffer, len) < 0) + return NULL; + + return buffer; +#else + return NULL; +#endif + +#ifndef NETDEV_TX_OK +#define NETDEV_TX_OK 0 +#endif +#ifndef NETDEV_TX_BUSY +#define NETDEV_TX_BUSY 1 +#endif +#ifndef NETDEV_TX_LOCKED +#define NETDEV_TX_LOCKED -1 +#endif +} + +#ifndef __bitwise +#define __bitwise +#endif +#endif /* < 2.6.9 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ) +#ifdef module_param_array_named +#undef module_param_array_named +#define module_param_array_named(name, array, type, nump, perm) \ + static struct kparam_array __param_arr_##name \ + = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type, \ + sizeof(array[0]), array }; \ + module_param_call(name, param_array_set, param_array_get, \ + &__param_arr_##name, perm) +#endif /* module_param_array_named */ +/* + * num_online is broken for all < 2.6.10 kernels. This is needed to support + * Node module parameter of ixgbe. + */ +#undef num_online_nodes +#define num_online_nodes(n) 1 +extern DECLARE_BITMAP(_kcompat_node_online_map, MAX_NUMNODES); +#undef node_online_map +#define node_online_map _kcompat_node_online_map +#define pci_get_class pci_find_class +#endif /* < 2.6.10 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) ) +#define PCI_D0 0 +#define PCI_D1 1 +#define PCI_D2 2 +#define PCI_D3hot 3 +#define PCI_D3cold 4 +typedef int pci_power_t; +#define pci_choose_state(pdev,state) state +#define PMSG_SUSPEND 3 +#define PCI_EXP_LNKCTL 16 + +#undef NETIF_F_LLTX + +#ifndef ARCH_HAS_PREFETCH +#define prefetch(X) +#endif + +#ifndef NET_IP_ALIGN +#define NET_IP_ALIGN 2 +#endif + +#define KC_USEC_PER_SEC 1000000L +#define usecs_to_jiffies _kc_usecs_to_jiffies +static inline unsigned int _kc_jiffies_to_usecs(const unsigned long j) +{ +#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ) + return (KC_USEC_PER_SEC / HZ) * j; +#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC) + return (j + (HZ / KC_USEC_PER_SEC) - 1)/(HZ / KC_USEC_PER_SEC); +#else + return (j * KC_USEC_PER_SEC) / HZ; +#endif +} +static inline unsigned long _kc_usecs_to_jiffies(const unsigned int m) +{ + if (m > _kc_jiffies_to_usecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ) + return (m + (KC_USEC_PER_SEC / HZ) - 1) / (KC_USEC_PER_SEC / HZ); +#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC) + return m * (HZ / KC_USEC_PER_SEC); +#else + return (m * HZ + KC_USEC_PER_SEC - 1) / KC_USEC_PER_SEC; +#endif +} + +#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKSTA 18 /* Link Status */ +#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ +#define PCI_EXP_SLTCTL 24 /* Slot Control */ +#define PCI_EXP_SLTSTA 26 /* Slot Status */ +#define PCI_EXP_RTCTL 28 /* Root Control */ +#define PCI_EXP_RTCAP 30 /* Root Capabilities */ +#define PCI_EXP_RTSTA 32 /* Root Status */ +#endif /* < 2.6.11 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ) +#include +#define USE_REBOOT_NOTIFIER + +/* Generic MII registers. */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +/* Advertisement control register. */ +#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ +#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymmetric pause */ +/* Link partner ability register. */ +#define LPA_PAUSE_CAP 0x0400 /* Can pause */ +#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ +/* 1000BASE-T Control register */ +#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ +#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ +/* 1000BASE-T Status register */ +#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ +#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ + +#ifndef is_zero_ether_addr +#define is_zero_ether_addr _kc_is_zero_ether_addr +static inline int _kc_is_zero_ether_addr(const u8 *addr) +{ + return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); +} +#endif /* is_zero_ether_addr */ +#ifndef is_multicast_ether_addr +#define is_multicast_ether_addr _kc_is_multicast_ether_addr +static inline int _kc_is_multicast_ether_addr(const u8 *addr) +{ + return addr[0] & 0x01; +} +#endif /* is_multicast_ether_addr */ +#endif /* < 2.6.12 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) ) +#ifndef kstrdup +#define kstrdup _kc_kstrdup +char *_kc_kstrdup(const char *s, unsigned int gfp); +#endif +#endif /* < 2.6.13 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ) +#define pm_message_t u32 +#ifndef kzalloc +#define kzalloc _kc_kzalloc +void *_kc_kzalloc(size_t size, int flags); +#endif + +/* Generic MII registers. */ +#define MII_ESTATUS 0x0f /* Extended Status */ +/* Basic mode status register. */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +/* Extended status register. */ +#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ +#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ + +#define SUPPORTED_Pause BIT(13) +#define SUPPORTED_Asym_Pause BIT(14) +#define ADVERTISED_Pause BIT(13) +#define ADVERTISED_Asym_Pause BIT(14) + +#if (!(RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,3)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0)))) +#if ((LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9)) && !defined(gfp_t)) +#define gfp_t unsigned +#else +typedef unsigned gfp_t; +#endif +#endif /* !RHEL4.3->RHEL5.0 */ + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) ) +#ifdef CONFIG_X86_64 +#define dma_sync_single_range_for_cpu(dev, addr, off, sz, dir) \ + dma_sync_single_for_cpu((dev), (addr), (off) + (sz), (dir)) +#define dma_sync_single_range_for_device(dev, addr, off, sz, dir) \ + dma_sync_single_for_device((dev), (addr), (off) + (sz), (dir)) +#endif +#endif +#endif /* < 2.6.14 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) ) +#ifndef kfree_rcu +/* this is placed here due to a lack of rcu_barrier in previous kernels */ +#define kfree_rcu(_ptr, _offset) kfree(_ptr) +#endif /* kfree_rcu */ +#ifndef vmalloc_node +#define vmalloc_node(a,b) vmalloc(a) +#endif /* vmalloc_node*/ + +#define setup_timer(_timer, _function, _data) \ +do { \ + (_timer)->function = _function; \ + (_timer)->data = _data; \ + init_timer(_timer); \ +} while (0) +#ifndef device_can_wakeup +#define device_can_wakeup(dev) (1) +#endif +#ifndef device_set_wakeup_enable +#define device_set_wakeup_enable(dev, val) do{}while(0) +#endif +#ifndef device_init_wakeup +#define device_init_wakeup(dev,val) do {} while (0) +#endif +static inline unsigned _kc_compare_ether_addr(const u8 *addr1, const u8 *addr2) +{ + const u16 *a = (const u16 *) addr1; + const u16 *b = (const u16 *) addr2; + + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; +} +#undef compare_ether_addr +#define compare_ether_addr(addr1, addr2) _kc_compare_ether_addr(addr1, addr2) +#endif /* < 2.6.15 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) ) +#undef DEFINE_MUTEX +#define DEFINE_MUTEX(x) DECLARE_MUTEX(x) +#define mutex_lock(x) down_interruptible(x) +#define mutex_unlock(x) up(x) + +#ifndef ____cacheline_internodealigned_in_smp +#ifdef CONFIG_SMP +#define ____cacheline_internodealigned_in_smp ____cacheline_aligned_in_smp +#else +#define ____cacheline_internodealigned_in_smp +#endif /* CONFIG_SMP */ +#endif /* ____cacheline_internodealigned_in_smp */ +#undef HAVE_PCI_ERS +#else /* 2.6.16 and above */ +#undef HAVE_PCI_ERS +#define HAVE_PCI_ERS +#if ( SLE_VERSION_CODE && SLE_VERSION_CODE == SLE_VERSION(10,4,0) ) +#ifdef device_can_wakeup +#undef device_can_wakeup +#endif /* device_can_wakeup */ +#define device_can_wakeup(dev) 1 +#endif /* SLE_VERSION(10,4,0) */ +#endif /* < 2.6.16 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) ) +#ifndef dev_notice +#define dev_notice(dev, fmt, args...) \ + dev_printk(KERN_NOTICE, dev, fmt, ## args) +#endif + +#ifndef first_online_node +#define first_online_node 0 +#endif +#ifndef NET_SKB_PAD +#define NET_SKB_PAD 16 +#endif +#endif /* < 2.6.17 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ) + +#ifndef IRQ_HANDLED +#define irqreturn_t void +#define IRQ_HANDLED +#define IRQ_NONE +#endif + +#ifndef IRQF_PROBE_SHARED +#ifdef SA_PROBEIRQ +#define IRQF_PROBE_SHARED SA_PROBEIRQ +#else +#define IRQF_PROBE_SHARED 0 +#endif +#endif + +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#ifndef skb_is_gso +#ifdef NETIF_F_TSO +#define skb_is_gso _kc_skb_is_gso +static inline int _kc_skb_is_gso(const struct sk_buff *skb) +{ + return skb_shinfo(skb)->gso_size; +} +#else +#define skb_is_gso(a) 0 +#endif +#endif + +#ifndef resource_size_t +#define resource_size_t unsigned long +#endif + +#ifdef skb_pad +#undef skb_pad +#endif +#define skb_pad(x,y) _kc_skb_pad(x, y) +int _kc_skb_pad(struct sk_buff *skb, int pad); +#ifdef skb_padto +#undef skb_padto +#endif +#define skb_padto(x,y) _kc_skb_padto(x, y) +static inline int _kc_skb_padto(struct sk_buff *skb, unsigned int len) +{ + unsigned int size = skb->len; + if(likely(size >= len)) + return 0; + return _kc_skb_pad(skb, len - size); +} + +#ifndef DECLARE_PCI_UNMAP_ADDR +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ + dma_addr_t ADDR_NAME +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ + u32 LEN_NAME +#define pci_unmap_addr(PTR, ADDR_NAME) \ + ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ + (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) \ + ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ + (((PTR)->LEN_NAME) = (VAL)) +#endif /* DECLARE_PCI_UNMAP_ADDR */ +#endif /* < 2.6.18 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ) +enum pcie_link_width { + PCIE_LNK_WIDTH_RESRV = 0x00, + PCIE_LNK_X1 = 0x01, + PCIE_LNK_X2 = 0x02, + PCIE_LNK_X4 = 0x04, + PCIE_LNK_X8 = 0x08, + PCIE_LNK_X12 = 0x0C, + PCIE_LNK_X16 = 0x10, + PCIE_LNK_X32 = 0x20, + PCIE_LNK_WIDTH_UNKNOWN = 0xFF, +}; + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,0))) +#define i_private u.generic_ip +#endif /* >= RHEL 5.0 */ + +#ifndef DIV_ROUND_UP +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#endif +#ifndef __ALIGN_MASK +#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#endif +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ) +#if (!((RHEL_RELEASE_CODE && \ + ((RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,4) && \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0)) || \ + (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,0)))))) +typedef irqreturn_t (*irq_handler_t)(int, void*, struct pt_regs *); +#endif +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0)) +#undef CONFIG_INET_LRO +#undef CONFIG_INET_LRO_MODULE +#undef CONFIG_FCOE +#undef CONFIG_FCOE_MODULE +#endif +typedef irqreturn_t (*new_handler_t)(int, void*); +static inline irqreturn_t _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id) +#else /* 2.4.x */ +typedef void (*irq_handler_t)(int, void*, struct pt_regs *); +typedef void (*new_handler_t)(int, void*); +static inline int _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id) +#endif /* >= 2.5.x */ +{ + irq_handler_t new_handler = (irq_handler_t) handler; + return request_irq(irq, new_handler, flags, devname, dev_id); +} + +#undef request_irq +#define request_irq(irq, handler, flags, devname, dev_id) _kc_request_irq((irq), (handler), (flags), (devname), (dev_id)) + +#define irq_handler_t new_handler_t + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) ) +#ifndef skb_checksum_help +static inline int __kc_skb_checksum_help(struct sk_buff *skb) +{ + return skb_checksum_help(skb, 0); +} +#define skb_checksum_help(skb) __kc_skb_checksum_help((skb)) +#endif +#endif /* < 2.6.19 && >= 2.6.11 */ + +/* pci_restore_state and pci_save_state handles MSI/PCIE from 2.6.19 */ +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4))) +#define PCIE_CONFIG_SPACE_LEN 256 +#define PCI_CONFIG_SPACE_LEN 64 +#define PCIE_LINK_STATUS 0x12 +#define pci_config_space_ich8lan() do {} while(0) +#undef pci_save_state +int _kc_pci_save_state(struct pci_dev *); +#define pci_save_state(pdev) _kc_pci_save_state(pdev) +#undef pci_restore_state +void _kc_pci_restore_state(struct pci_dev *); +#define pci_restore_state(pdev) _kc_pci_restore_state(pdev) +#endif /* !(RHEL_RELEASE_CODE >= RHEL 5.4) */ + +#ifdef HAVE_PCI_ERS +#undef free_netdev +void _kc_free_netdev(struct net_device *); +#define free_netdev(netdev) _kc_free_netdev(netdev) +#endif +#define pci_cleanup_aer_uncorrect_error_status(dev) do {} while (0) + +void *_kc_kmemdup(const void *src, size_t len, unsigned gfp); +#define kmemdup(src, len, gfp) _kc_kmemdup(src, len, gfp) +#ifndef bool +#define bool _Bool +#define true 1 +#define false 0 +#endif +#else /* 2.6.19 */ +#include +#include + +#define NEW_SKB_CSUM_HELP +#endif /* < 2.6.19 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ) +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) ) +#undef INIT_WORK +#define INIT_WORK(_work, _func) \ +do { \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->pending = 0; \ + (_work)->func = (void (*)(void *))_func; \ + (_work)->data = _work; \ + init_timer(&(_work)->timer); \ +} while (0) +#endif + +#ifndef PCI_VDEVICE +#define PCI_VDEVICE(ven, dev) \ + PCI_VENDOR_ID_##ven, (dev), \ + PCI_ANY_ID, PCI_ANY_ID, 0, 0 +#endif + +#ifndef PCI_VENDOR_ID_INTEL +#define PCI_VENDOR_ID_INTEL 0x8086 +#endif + +#ifndef round_jiffies +#define round_jiffies(x) x +#endif + +#define csum_offset csum + +#define HAVE_EARLY_VMALLOC_NODE +#define dev_to_node(dev) -1 +#undef set_dev_node +/* remove compiler warning with b=b, for unused variable */ +#define set_dev_node(a, b) do { (b) = (b); } while(0) + +#if (!(RHEL_RELEASE_CODE && \ + (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(4,7)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))) || \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,6)))) && \ + !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,2,0))) +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __wsum; +#endif + +#if (!(RHEL_RELEASE_CODE && \ + (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(4,7)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))) || \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4)))) && \ + !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,2,0))) +static inline __wsum csum_unfold(__sum16 n) +{ + return (__force __wsum)n; +} +#endif + +#else /* < 2.6.20 */ +#define HAVE_DEVICE_NUMA_NODE +#endif /* < 2.6.20 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ) +#define to_net_dev(class) container_of(class, struct net_device, class_dev) +#define NETDEV_CLASS_DEV +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5))) +#define vlan_group_get_device(vg, id) (vg->vlan_devices[id]) +#define vlan_group_set_device(vg, id, dev) \ + do { \ + if (vg) vg->vlan_devices[id] = dev; \ + } while (0) +#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)) */ +#define pci_channel_offline(pdev) (pdev->error_state && \ + pdev->error_state != pci_channel_io_normal) +#define pci_request_selected_regions(pdev, bars, name) \ + pci_request_regions(pdev, name) +#define pci_release_selected_regions(pdev, bars) pci_release_regions(pdev); + +#ifndef __aligned +#define __aligned(x) __attribute__((aligned(x))) +#endif + +struct pci_dev *_kc_netdev_to_pdev(struct net_device *netdev); +#define netdev_to_dev(netdev) \ + pci_dev_to_dev(_kc_netdev_to_pdev(netdev)) +#else /* 2.6.21 */ +static inline struct device *netdev_to_dev(struct net_device *netdev) +{ + return &netdev->dev; +} + +#endif /* < 2.6.21 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ) +#define tcp_hdr(skb) (skb->h.th) +#define tcp_hdrlen(skb) (skb->h.th->doff << 2) +#define skb_transport_offset(skb) (skb->h.raw - skb->data) +#define skb_transport_header(skb) (skb->h.raw) +#define ipv6_hdr(skb) (skb->nh.ipv6h) +#define ip_hdr(skb) (skb->nh.iph) +#define skb_network_offset(skb) (skb->nh.raw - skb->data) +#define skb_network_header(skb) (skb->nh.raw) +#define skb_tail_pointer(skb) skb->tail +#define skb_reset_tail_pointer(skb) \ + do { \ + skb->tail = skb->data; \ + } while (0) +#define skb_set_tail_pointer(skb, offset) \ + do { \ + skb->tail = skb->data + offset; \ + } while (0) +#define skb_copy_to_linear_data(skb, from, len) \ + memcpy(skb->data, from, len) +#define skb_copy_to_linear_data_offset(skb, offset, from, len) \ + memcpy(skb->data + offset, from, len) +#define skb_network_header_len(skb) (skb->h.raw - skb->nh.raw) +#define pci_register_driver pci_module_init +#define skb_mac_header(skb) skb->mac.raw + +#ifdef NETIF_F_MULTI_QUEUE +#ifndef alloc_etherdev_mq +#define alloc_etherdev_mq(_a, _b) alloc_etherdev(_a) +#endif +#endif /* NETIF_F_MULTI_QUEUE */ + +#ifndef ETH_FCS_LEN +#define ETH_FCS_LEN 4 +#endif +#define cancel_work_sync(x) flush_scheduled_work() +#ifndef udp_hdr +#define udp_hdr _udp_hdr +static inline struct udphdr *_udp_hdr(const struct sk_buff *skb) +{ + return (struct udphdr *)skb_transport_header(skb); +} +#endif + +#ifdef cpu_to_be16 +#undef cpu_to_be16 +#endif +#define cpu_to_be16(x) __constant_htons(x) + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,1))) +enum { + DUMP_PREFIX_NONE, + DUMP_PREFIX_ADDRESS, + DUMP_PREFIX_OFFSET +}; +#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,1)) */ +#ifndef hex_asc +#define hex_asc(x) "0123456789abcdef"[x] +#endif +#include +void _kc_print_hex_dump(const char *level, const char *prefix_str, + int prefix_type, int rowsize, int groupsize, + const void *buf, size_t len, bool ascii); +#define print_hex_dump(lvl, s, t, r, g, b, l, a) \ + _kc_print_hex_dump(lvl, s, t, r, g, b, l, a) +#ifndef ADVERTISED_2500baseX_Full +#define ADVERTISED_2500baseX_Full BIT(15) +#endif +#ifndef SUPPORTED_2500baseX_Full +#define SUPPORTED_2500baseX_Full BIT(15) +#endif + +#ifndef ETH_P_PAUSE +#define ETH_P_PAUSE 0x8808 +#endif + +static inline int compound_order(struct page *page) +{ + return 0; +} + +#define __must_be_array(a) 0 + +#ifndef SKB_WITH_OVERHEAD +#define SKB_WITH_OVERHEAD(X) \ + ((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) +#endif +#else /* 2.6.22 */ +#define ETH_TYPE_TRANS_SETS_DEV +#define HAVE_NETDEV_STATS_IN_NETDEV +#endif /* < 2.6.22 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) ) +#undef SET_MODULE_OWNER +#define SET_MODULE_OWNER(dev) do { } while (0) +#endif /* > 2.6.22 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) ) +#define netif_subqueue_stopped(_a, _b) 0 +#ifndef PTR_ALIGN +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) +#endif + +#ifndef CONFIG_PM_SLEEP +#define CONFIG_PM_SLEEP CONFIG_PM +#endif + +#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) ) +#define HAVE_ETHTOOL_GET_PERM_ADDR +#endif /* 2.6.14 through 2.6.22 */ + +static inline int __kc_skb_cow_head(struct sk_buff *skb, unsigned int headroom) +{ + int delta = 0; + + if (headroom > (skb->data - skb->head)) + delta = headroom - (skb->data - skb->head); + + if (delta || skb_header_cloned(skb)) + return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0, + GFP_ATOMIC); + return 0; +} +#define skb_cow_head(s, h) __kc_skb_cow_head((s), (h)) +#endif /* < 2.6.23 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) +#ifndef ETH_FLAG_LRO +#define ETH_FLAG_LRO NETIF_F_LRO +#endif + +#ifndef ACCESS_ONCE +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) +#endif + +/* if GRO is supported then the napi struct must already exist */ +#ifndef NETIF_F_GRO +/* NAPI API changes in 2.6.24 break everything */ +struct napi_struct { + /* used to look up the real NAPI polling routine */ + int (*poll)(struct napi_struct *, int); + struct net_device *dev; + int weight; +}; +#endif + +#ifdef NAPI +int __kc_adapter_clean(struct net_device *, int *); +/* The following definitions are multi-queue aware, and thus we have a driver + * define list which determines which drivers support multiple queues, and + * thus need these stronger defines. If a driver does not support multi-queue + * functionality, you don't need to add it to this list. + */ +struct net_device *napi_to_poll_dev(const struct napi_struct *napi); + +static inline void __kc_mq_netif_napi_add(struct net_device *dev, struct napi_struct *napi, + int (*poll)(struct napi_struct *, int), int weight) +{ + struct net_device *poll_dev = napi_to_poll_dev(napi); + poll_dev->poll = __kc_adapter_clean; + poll_dev->priv = napi; + poll_dev->weight = weight; + set_bit(__LINK_STATE_RX_SCHED, &poll_dev->state); + set_bit(__LINK_STATE_START, &poll_dev->state); + dev_hold(poll_dev); + napi->poll = poll; + napi->weight = weight; + napi->dev = dev; +} +#define netif_napi_add __kc_mq_netif_napi_add + +static inline void __kc_mq_netif_napi_del(struct napi_struct *napi) +{ + struct net_device *poll_dev = napi_to_poll_dev(napi); + WARN_ON(!test_bit(__LINK_STATE_RX_SCHED, &poll_dev->state)); + dev_put(poll_dev); + memset(poll_dev, 0, sizeof(struct net_device)); +} + +#define netif_napi_del __kc_mq_netif_napi_del + +static inline bool __kc_mq_napi_schedule_prep(struct napi_struct *napi) +{ + return netif_running(napi->dev) && + netif_rx_schedule_prep(napi_to_poll_dev(napi)); +} +#define napi_schedule_prep __kc_mq_napi_schedule_prep + +static inline void __kc_mq_napi_schedule(struct napi_struct *napi) +{ + if (napi_schedule_prep(napi)) + __netif_rx_schedule(napi_to_poll_dev(napi)); +} +#define napi_schedule __kc_mq_napi_schedule + +#define napi_enable(_napi) netif_poll_enable(napi_to_poll_dev(_napi)) +#define napi_disable(_napi) netif_poll_disable(napi_to_poll_dev(_napi)) +#ifdef CONFIG_SMP +static inline void napi_synchronize(const struct napi_struct *n) +{ + struct net_device *dev = napi_to_poll_dev(n); + + while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { + /* No hurry. */ + msleep(1); + } +} +#else +#define napi_synchronize(n) barrier() +#endif /* CONFIG_SMP */ +#define __napi_schedule(_napi) __netif_rx_schedule(napi_to_poll_dev(_napi)) +static inline void _kc_napi_complete(struct napi_struct *napi) +{ +#ifdef NETIF_F_GRO + napi_gro_flush(napi); +#endif + netif_rx_complete(napi_to_poll_dev(napi)); +} +#define napi_complete _kc_napi_complete +#else /* NAPI */ + +/* The following definitions are only used if we don't support NAPI at all. */ + +static inline __kc_netif_napi_add(struct net_device *dev, struct napi_struct *napi, + int (*poll)(struct napi_struct *, int), int weight) +{ + dev->poll = poll; + dev->weight = weight; + napi->poll = poll; + napi->weight = weight; + napi->dev = dev; +} +#define netif_napi_del(_a) do {} while (0) +#endif /* NAPI */ + +#undef dev_get_by_name +#define dev_get_by_name(_a, _b) dev_get_by_name(_b) +#define __netif_subqueue_stopped(_a, _b) netif_subqueue_stopped(_a, _b) +#ifndef DMA_BIT_MASK +#define DMA_BIT_MASK(n) (((n) == 64) ? DMA_64BIT_MASK : ((1ULL<<(n))-1)) +#endif + +#ifdef NETIF_F_TSO6 +#define skb_is_gso_v6 _kc_skb_is_gso_v6 +static inline int _kc_skb_is_gso_v6(const struct sk_buff *skb) +{ + return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6; +} +#endif /* NETIF_F_TSO6 */ + +#ifndef KERN_CONT +#define KERN_CONT "" +#endif +#ifndef pr_err +#define pr_err(fmt, arg...) \ + printk(KERN_ERR fmt, ##arg) +#endif + +#ifndef rounddown_pow_of_two +#define rounddown_pow_of_two(n) \ + __builtin_constant_p(n) ? ( \ + (n == 1) ? 0 : \ + (1UL << ilog2(n))) : \ + (1UL << (fls_long(n) - 1)) +#endif + +#else /* < 2.6.24 */ +#define HAVE_ETHTOOL_GET_SSET_COUNT +#define HAVE_NETDEV_NAPI_LIST +#endif /* < 2.6.24 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) ) +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ) +#define INCLUDE_PM_QOS_PARAMS_H +#include +#else /* >= 3.2.0 */ +#include +#endif /* else >= 3.2.0 */ +#endif /* > 2.6.24 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) ) +#define PM_QOS_CPU_DMA_LATENCY 1 + +#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ) +#include +#define PM_QOS_DEFAULT_VALUE INFINITE_LATENCY +#define pm_qos_add_requirement(pm_qos_class, name, value) \ + set_acceptable_latency(name, value) +#define pm_qos_remove_requirement(pm_qos_class, name) \ + remove_acceptable_latency(name) +#define pm_qos_update_requirement(pm_qos_class, name, value) \ + modify_acceptable_latency(name, value) +#else +#define PM_QOS_DEFAULT_VALUE -1 +#define pm_qos_add_requirement(pm_qos_class, name, value) +#define pm_qos_remove_requirement(pm_qos_class, name) +#define pm_qos_update_requirement(pm_qos_class, name, value) { \ + if (value != PM_QOS_DEFAULT_VALUE) { \ + printk(KERN_WARNING "%s: unable to set PM QoS requirement\n", \ + pci_name(adapter->pdev)); \ + } \ +} + +#endif /* > 2.6.18 */ + +#define pci_enable_device_mem(pdev) pci_enable_device(pdev) + +#ifndef DEFINE_PCI_DEVICE_TABLE +#define DEFINE_PCI_DEVICE_TABLE(_table) struct pci_device_id _table[] +#endif /* DEFINE_PCI_DEVICE_TABLE */ + +#ifndef strict_strtol +#define strict_strtol(s, b, r) _kc_strict_strtol(s, b, r) +static inline int _kc_strict_strtol(const char *buf, unsigned int base, long *res) +{ + /* adapted from strict_strtoul() in 2.6.25 */ + char *tail; + long val; + size_t len; + + *res = 0; + len = strlen(buf); + if (!len) + return -EINVAL; + val = simple_strtol(buf, &tail, base); + if (tail == buf) + return -EINVAL; + if ((*tail == '\0') || + ((len == (size_t)(tail - buf) + 1) && (*tail == '\n'))) { + *res = val; + return 0; + } + + return -EINVAL; +} +#endif + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) +#ifndef IXGBE_PROCFS +#define IXGBE_PROCFS +#endif /* IXGBE_PROCFS */ +#endif /* >= 2.6.0 */ + +#else /* < 2.6.25 */ + +#if IS_ENABLED(CONFIG_SYSFS) +#ifndef IXGBE_SYSFS +#define IXGBE_SYSFS +#endif /* IXGBE_SYSFS */ +#endif /* CONFIG_SYSFS */ +#if IS_ENABLED(CONFIG_HWMON) +#ifndef IXGBE_HWMON +#define IXGBE_HWMON +#endif /* IXGBE_HWMON */ +#endif /* CONFIG_HWMON */ + +#endif /* < 2.6.25 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ) +#ifndef clamp_t +#define clamp_t(type, val, min, max) ({ \ + type __val = (val); \ + type __min = (min); \ + type __max = (max); \ + __val = __val < __min ? __min : __val; \ + __val > __max ? __max : __val; }) +#endif /* clamp_t */ +#undef kzalloc_node +#define kzalloc_node(_size, _flags, _node) kzalloc(_size, _flags) + +void _kc_pci_disable_link_state(struct pci_dev *dev, int state); +#define pci_disable_link_state(p, s) _kc_pci_disable_link_state(p, s) +#else /* < 2.6.26 */ +#define NETDEV_CAN_SET_GSO_MAX_SIZE +#ifdef HAVE_PCI_ASPM_H +#include +#endif +#define HAVE_NETDEV_VLAN_FEATURES +#ifndef PCI_EXP_LNKCAP_ASPMS +#define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ +#endif /* PCI_EXP_LNKCAP_ASPMS */ +#endif /* < 2.6.26 */ +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) ) +static inline void _kc_ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + ep->speed = (__u16)speed; + /* ep->speed_hi = (__u16)(speed >> 16); */ +} +#define ethtool_cmd_speed_set _kc_ethtool_cmd_speed_set + +static inline __u32 _kc_ethtool_cmd_speed(struct ethtool_cmd *ep) +{ + /* no speed_hi before 2.6.27, and probably no need for it yet */ + return (__u32)ep->speed; +} +#define ethtool_cmd_speed _kc_ethtool_cmd_speed + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) ) +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) && defined(CONFIG_PM)) +#define ANCIENT_PM 1 +#elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) && \ + defined(CONFIG_PM_SLEEP)) +#define NEWER_PM 1 +#endif +#if defined(ANCIENT_PM) || defined(NEWER_PM) +#undef device_set_wakeup_enable +#define device_set_wakeup_enable(dev, val) \ + do { \ + u16 pmc = 0; \ + int pm = pci_find_capability(adapter->pdev, PCI_CAP_ID_PM); \ + if (pm) { \ + pci_read_config_word(adapter->pdev, pm + PCI_PM_PMC, \ + &pmc); \ + } \ + (dev)->power.can_wakeup = !!(pmc >> 11); \ + (dev)->power.should_wakeup = (val && (pmc >> 11)); \ + } while (0) +#endif /* 2.6.15-2.6.22 and CONFIG_PM or 2.6.23-2.6.25 and CONFIG_PM_SLEEP */ +#endif /* 2.6.15 through 2.6.27 */ +#ifndef netif_napi_del +#define netif_napi_del(_a) do {} while (0) +#ifdef NAPI +#ifdef CONFIG_NETPOLL +#undef netif_napi_del +#define netif_napi_del(_a) list_del(&(_a)->dev_list); +#endif +#endif +#endif /* netif_napi_del */ +#ifdef dma_mapping_error +#undef dma_mapping_error +#endif +#define dma_mapping_error(dev, dma_addr) pci_dma_mapping_error(dma_addr) + +#ifdef CONFIG_NETDEVICES_MULTIQUEUE +#define HAVE_TX_MQ +#endif + +#ifndef DMA_ATTR_WEAK_ORDERING +#define DMA_ATTR_WEAK_ORDERING 0 +#endif + +#ifdef HAVE_TX_MQ +void _kc_netif_tx_stop_all_queues(struct net_device *); +void _kc_netif_tx_wake_all_queues(struct net_device *); +void _kc_netif_tx_start_all_queues(struct net_device *); +#define netif_tx_stop_all_queues(a) _kc_netif_tx_stop_all_queues(a) +#define netif_tx_wake_all_queues(a) _kc_netif_tx_wake_all_queues(a) +#define netif_tx_start_all_queues(a) _kc_netif_tx_start_all_queues(a) +#undef netif_stop_subqueue +#define netif_stop_subqueue(_ndev,_qi) do { \ + if (netif_is_multiqueue((_ndev))) \ + netif_stop_subqueue((_ndev), (_qi)); \ + else \ + netif_stop_queue((_ndev)); \ + } while (0) +#undef netif_start_subqueue +#define netif_start_subqueue(_ndev,_qi) do { \ + if (netif_is_multiqueue((_ndev))) \ + netif_start_subqueue((_ndev), (_qi)); \ + else \ + netif_start_queue((_ndev)); \ + } while (0) +#else /* HAVE_TX_MQ */ +#define netif_tx_stop_all_queues(a) netif_stop_queue(a) +#define netif_tx_wake_all_queues(a) netif_wake_queue(a) +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) ) +#define netif_tx_start_all_queues(a) netif_start_queue(a) +#else +#define netif_tx_start_all_queues(a) do {} while (0) +#endif +#define netif_stop_subqueue(_ndev,_qi) netif_stop_queue((_ndev)) +#define netif_start_subqueue(_ndev,_qi) netif_start_queue((_ndev)) +#endif /* HAVE_TX_MQ */ +#ifndef NETIF_F_MULTI_QUEUE +#define NETIF_F_MULTI_QUEUE 0 +#define netif_is_multiqueue(a) 0 +#define netif_wake_subqueue(a, b) +#endif /* NETIF_F_MULTI_QUEUE */ + +#ifndef __WARN_printf +void __kc_warn_slowpath(const char *file, const int line, + const char *fmt, ...) __attribute__((format(printf, 3, 4))); +#define __WARN_printf(arg...) __kc_warn_slowpath(__FILE__, __LINE__, arg) +#endif /* __WARN_printf */ + +#ifndef WARN +#define WARN(condition, format...) ({ \ + int __ret_warn_on = !!(condition); \ + if (unlikely(__ret_warn_on)) \ + __WARN_printf(format); \ + unlikely(__ret_warn_on); \ +}) +#endif /* WARN */ +#undef HAVE_IXGBE_DEBUG_FS +#undef HAVE_IGB_DEBUG_FS +#else /* < 2.6.27 */ +#define ethtool_cmd_speed_set _kc_ethtool_cmd_speed_set +static inline void _kc_ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + ep->speed = (__u16)(speed & 0xFFFF); + ep->speed_hi = (__u16)(speed >> 16); +} +#define HAVE_TX_MQ +#define HAVE_NETDEV_SELECT_QUEUE +#ifdef CONFIG_DEBUG_FS +#define HAVE_IXGBE_DEBUG_FS +#define HAVE_IGB_DEBUG_FS +#endif /* CONFIG_DEBUG_FS */ +#endif /* < 2.6.27 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ) +#define pci_ioremap_bar(pdev, bar) ioremap(pci_resource_start(pdev, bar), \ + pci_resource_len(pdev, bar)) +#define pci_wake_from_d3 _kc_pci_wake_from_d3 +#define pci_prepare_to_sleep _kc_pci_prepare_to_sleep +int _kc_pci_wake_from_d3(struct pci_dev *dev, bool enable); +int _kc_pci_prepare_to_sleep(struct pci_dev *dev); +#define netdev_alloc_page(a) alloc_page(GFP_ATOMIC) +#ifndef __skb_queue_head_init +static inline void __kc_skb_queue_head_init(struct sk_buff_head *list) +{ + list->prev = list->next = (struct sk_buff *)list; + list->qlen = 0; +} +#define __skb_queue_head_init(_q) __kc_skb_queue_head_init(_q) +#endif + +#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ +#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ + +#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ +#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ + +#endif /* < 2.6.28 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ) +#ifndef swap +#define swap(a, b) \ + do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) +#endif +#define pci_request_selected_regions_exclusive(pdev, bars, name) \ + pci_request_selected_regions(pdev, bars, name) +#ifndef CONFIG_NR_CPUS +#define CONFIG_NR_CPUS 1 +#endif /* CONFIG_NR_CPUS */ +#ifndef pcie_aspm_enabled +#define pcie_aspm_enabled() (1) +#endif /* pcie_aspm_enabled */ + +#define PCI_EXP_SLTSTA_PDS 0x0040 /* Presence Detect State */ + +#ifndef PCI_EXP_LNKSTA_CLS +#define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ +#endif +#ifndef PCI_EXP_LNKSTA_NLW +#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Negotiated Link Width */ +#endif + +#ifndef pci_clear_master +void _kc_pci_clear_main(struct pci_dev *dev); +#define pci_clear_master(dev) _kc_pci_clear_main(dev) +#endif + +#ifndef PCI_EXP_LNKCTL_ASPMC +#define PCI_EXP_LNKCTL_ASPMC 0x0003 /* ASPM Control */ +#endif + +#ifndef PCI_EXP_LNKCAP_MLW +#define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ +#endif + +#else /* < 2.6.29 */ +#ifndef HAVE_NET_DEVICE_OPS +#define HAVE_NET_DEVICE_OPS +#endif +#ifdef CONFIG_DCB +#define HAVE_PFC_MODE_ENABLE +#endif /* CONFIG_DCB */ +#endif /* < 2.6.29 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) ) +#define NO_PTP_SUPPORT +#define skb_rx_queue_recorded(a) false +#define skb_get_rx_queue(a) 0 +#define skb_record_rx_queue(a, b) do {} while (0) +#define skb_tx_hash(n, s) ___kc_skb_tx_hash((n), (s), (n)->real_num_tx_queues) +#undef CONFIG_FCOE +#undef CONFIG_FCOE_MODULE +#ifndef CONFIG_PCI_IOV +#undef pci_enable_sriov +#define pci_enable_sriov(a, b) -ENOTSUPP +#undef pci_disable_sriov +#define pci_disable_sriov(a) do {} while (0) +#endif /* CONFIG_PCI_IOV */ +#ifndef pr_cont +#define pr_cont(fmt, ...) \ + printk(KERN_CONT fmt, ##__VA_ARGS__) +#endif /* pr_cont */ +static inline void _kc_synchronize_irq(unsigned int a) +{ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) + synchronize_irq(); +#else /* < 2.5.28 */ + synchronize_irq(a); +#endif /* < 2.5.28 */ +} +#undef synchronize_irq +#define synchronize_irq(a) _kc_synchronize_irq(a) + +#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ + +#ifdef nr_cpus_node +#undef nr_cpus_node +#define nr_cpus_node(node) cpumask_weight(cpumask_of_node(node)) +#endif + +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,5)) +#define HAVE_PCI_DEV_IS_VIRTFN_BIT +#endif /* RHEL >= 5.5 */ + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,5))) +static inline bool pci_is_root_bus(struct pci_bus *pbus) +{ + return !(pbus->parent); +} +#endif + +#else /* < 2.6.30 */ +#define HAVE_ASPM_QUIRKS +#define HAVE_PCI_DEV_IS_VIRTFN_BIT +#endif /* < 2.6.30 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) ) +#define ETH_P_1588 0x88F7 +#define ETH_P_FIP 0x8914 +#ifndef netdev_uc_count +#define netdev_uc_count(dev) ((dev)->uc_count) +#endif +#ifndef netdev_for_each_uc_addr +#define netdev_for_each_uc_addr(uclist, dev) \ + for (uclist = dev->uc_list; uclist; uclist = uclist->next) +#endif +#ifndef PORT_OTHER +#define PORT_OTHER 0xff +#endif +#ifndef MDIO_PHY_ID_PRTAD +#define MDIO_PHY_ID_PRTAD 0x03e0 +#endif +#ifndef MDIO_PHY_ID_DEVAD +#define MDIO_PHY_ID_DEVAD 0x001f +#endif +#ifndef skb_dst +#define skb_dst(s) ((s)->dst) +#endif + +#ifndef SUPPORTED_1000baseKX_Full +#define SUPPORTED_1000baseKX_Full BIT(17) +#endif +#ifndef SUPPORTED_10000baseKX4_Full +#define SUPPORTED_10000baseKX4_Full BIT(18) +#endif +#ifndef SUPPORTED_10000baseKR_Full +#define SUPPORTED_10000baseKR_Full BIT(19) +#endif + +#ifndef ADVERTISED_1000baseKX_Full +#define ADVERTISED_1000baseKX_Full BIT(17) +#endif +#ifndef ADVERTISED_10000baseKX4_Full +#define ADVERTISED_10000baseKX4_Full BIT(18) +#endif +#ifndef ADVERTISED_10000baseKR_Full +#define ADVERTISED_10000baseKR_Full BIT(19) +#endif + +static inline unsigned long dev_trans_start(struct net_device *dev) +{ + return dev->trans_start; +} +#else /* < 2.6.31 */ +#ifndef HAVE_NETDEV_STORAGE_ADDRESS +#define HAVE_NETDEV_STORAGE_ADDRESS +#endif +#ifndef HAVE_NETDEV_HW_ADDR +#define HAVE_NETDEV_HW_ADDR +#endif +#ifndef HAVE_TRANS_START_IN_QUEUE +#define HAVE_TRANS_START_IN_QUEUE +#endif +#ifndef HAVE_INCLUDE_LINUX_MDIO_H +#define HAVE_INCLUDE_LINUX_MDIO_H +#endif +#include +#endif /* < 2.6.31 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) ) +#undef netdev_tx_t +#define netdev_tx_t int +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifndef NETIF_F_FCOE_MTU +#define NETIF_F_FCOE_MTU BIT(26) +#endif +#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */ + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +static inline int _kc_pm_runtime_get_sync() +{ + return 1; +} +#define pm_runtime_get_sync(dev) _kc_pm_runtime_get_sync() +#else /* 2.6.0 => 2.6.32 */ +static inline int _kc_pm_runtime_get_sync(struct device __always_unused *dev) +{ + return 1; +} +#ifndef pm_runtime_get_sync +#define pm_runtime_get_sync(dev) _kc_pm_runtime_get_sync(dev) +#endif +#endif /* 2.6.0 => 2.6.32 */ +#ifndef pm_runtime_put +#define pm_runtime_put(dev) do {} while (0) +#endif +#ifndef pm_runtime_put_sync +#define pm_runtime_put_sync(dev) do {} while (0) +#endif +#ifndef pm_runtime_resume +#define pm_runtime_resume(dev) do {} while (0) +#endif +#ifndef pm_schedule_suspend +#define pm_schedule_suspend(dev, t) do {} while (0) +#endif +#ifndef pm_runtime_set_suspended +#define pm_runtime_set_suspended(dev) do {} while (0) +#endif +#ifndef pm_runtime_disable +#define pm_runtime_disable(dev) do {} while (0) +#endif +#ifndef pm_runtime_put_noidle +#define pm_runtime_put_noidle(dev) do {} while (0) +#endif +#ifndef pm_runtime_set_active +#define pm_runtime_set_active(dev) do {} while (0) +#endif +#ifndef pm_runtime_enable +#define pm_runtime_enable(dev) do {} while (0) +#endif +#ifndef pm_runtime_get_noresume +#define pm_runtime_get_noresume(dev) do {} while (0) +#endif +#else /* < 2.6.32 */ +#if (RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))) +#define HAVE_RHEL6_NET_DEVICE_EXTENDED +#endif /* RHEL >= 6.2 && RHEL < 7.0 */ +#if (RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,6)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))) +#define HAVE_RHEL6_NET_DEVICE_OPS_EXT +#define HAVE_NDO_SET_FEATURES +#endif /* RHEL >= 6.6 && RHEL < 7.0 */ +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE +#define HAVE_NETDEV_OPS_FCOE_ENABLE +#endif +#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */ +#ifdef CONFIG_DCB +#ifndef HAVE_DCBNL_OPS_GETAPP +#define HAVE_DCBNL_OPS_GETAPP +#endif +#endif /* CONFIG_DCB */ +#include +/* IOV bad DMA target work arounds require at least this kernel rev support */ +#define HAVE_PCIE_TYPE +#endif /* < 2.6.32 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) ) +#ifndef pci_pcie_cap +#define pci_pcie_cap(pdev) pci_find_capability(pdev, PCI_CAP_ID_EXP) +#endif +#ifndef IPV4_FLOW +#define IPV4_FLOW 0x10 +#endif /* IPV4_FLOW */ +#ifndef IPV6_FLOW +#define IPV6_FLOW 0x11 +#endif /* IPV6_FLOW */ +/* Features back-ported to RHEL6 or SLES11 SP1 after 2.6.32 */ +#if ( (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) || \ + (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,1,0)) ) +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifndef HAVE_NETDEV_OPS_FCOE_GETWWN +#define HAVE_NETDEV_OPS_FCOE_GETWWN +#endif +#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */ +#endif /* RHEL6 or SLES11 SP1 */ +#ifndef __percpu +#define __percpu +#endif /* __percpu */ + +#ifndef PORT_DA +#define PORT_DA PORT_OTHER +#endif /* PORT_DA */ +#ifndef PORT_NONE +#define PORT_NONE PORT_OTHER +#endif + +#if ((RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,3)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)))) +#if !defined(CONFIG_X86_32) && !defined(CONFIG_NEED_DMA_MAP_STATE) +#undef DEFINE_DMA_UNMAP_ADDR +#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME +#undef DEFINE_DMA_UNMAP_LEN +#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME +#undef dma_unmap_addr +#define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) +#undef dma_unmap_addr_set +#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) +#undef dma_unmap_len +#define dma_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) +#undef dma_unmap_len_set +#define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) +#endif /* CONFIG_X86_64 && !CONFIG_NEED_DMA_MAP_STATE */ +#endif /* RHEL_RELEASE_CODE */ + +#if (!(RHEL_RELEASE_CODE && \ + (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,8)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0))) || \ + ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,1)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)))))) +static inline bool pci_is_pcie(struct pci_dev *dev) +{ + return !!pci_pcie_cap(dev); +} +#endif /* RHEL_RELEASE_CODE */ + +#if (!(RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2)))) +#define sk_tx_queue_get(_sk) (-1) +#define sk_tx_queue_set(_sk, _tx_queue) do {} while(0) +#endif /* !(RHEL >= 6.2) */ + +#if (RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))) +#define HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +#define HAVE_ETHTOOL_GRXFHINDIR_SIZE +#define HAVE_ETHTOOL_SET_PHYS_ID +#define HAVE_ETHTOOL_GET_TS_INFO +#if (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,5)) +#define HAVE_ETHTOOL_GSRSSH +#define HAVE_RHEL6_SRIOV_CONFIGURE +#define HAVE_RXFH_NONCONST +#endif /* RHEL > 6.5 */ +#endif /* RHEL >= 6.4 && RHEL < 7.0 */ + +#else /* < 2.6.33 */ +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifndef HAVE_NETDEV_OPS_FCOE_GETWWN +#define HAVE_NETDEV_OPS_FCOE_GETWWN +#endif +#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */ +#endif /* < 2.6.33 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) ) +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0)) +#ifndef pci_num_vf +#define pci_num_vf(pdev) _kc_pci_num_vf(pdev) +int _kc_pci_num_vf(struct pci_dev *dev); +#endif +#endif /* RHEL_RELEASE_CODE */ + +#ifndef dev_is_pci +#define dev_is_pci(d) ((d)->bus == &pci_bus_type) +#endif + +#ifndef ETH_FLAG_NTUPLE +#define ETH_FLAG_NTUPLE NETIF_F_NTUPLE +#endif + +#ifndef netdev_mc_count +#define netdev_mc_count(dev) ((dev)->mc_count) +#endif +#ifndef netdev_mc_empty +#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) +#endif +#ifndef netdev_for_each_mc_addr +#define netdev_for_each_mc_addr(mclist, dev) \ + for (mclist = dev->mc_list; mclist; mclist = mclist->next) +#endif +#ifndef netdev_uc_count +#define netdev_uc_count(dev) ((dev)->uc.count) +#endif +#ifndef netdev_uc_empty +#define netdev_uc_empty(dev) (netdev_uc_count(dev) == 0) +#endif +#ifndef netdev_for_each_uc_addr +#define netdev_for_each_uc_addr(ha, dev) \ + list_for_each_entry(ha, &dev->uc.list, list) +#endif +#ifndef dma_set_coherent_mask +#define dma_set_coherent_mask(dev,mask) \ + pci_set_consistent_dma_mask(to_pci_dev(dev),(mask)) +#endif +#ifndef pci_dev_run_wake +#define pci_dev_run_wake(pdev) (0) +#endif + +/* netdev logging taken from include/linux/netdevice.h */ +#ifndef netdev_name +static inline const char *_kc_netdev_name(const struct net_device *dev) +{ + if (dev->reg_state != NETREG_REGISTERED) + return "(unregistered net_device)"; + return dev->name; +} +#define netdev_name(netdev) _kc_netdev_name(netdev) +#endif /* netdev_name */ + +#undef netdev_printk +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#define netdev_printk(level, netdev, format, args...) \ +do { \ + struct pci_dev *pdev = _kc_netdev_to_pdev(netdev); \ + printk(level "%s: " format, pci_name(pdev), ##args); \ +} while(0) +#elif ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ) +#define netdev_printk(level, netdev, format, args...) \ +do { \ + struct pci_dev *pdev = _kc_netdev_to_pdev(netdev); \ + struct device *dev = pci_dev_to_dev(pdev); \ + dev_printk(level, dev, "%s: " format, \ + netdev_name(netdev), ##args); \ +} while(0) +#else /* 2.6.21 => 2.6.34 */ +#define netdev_printk(level, netdev, format, args...) \ + dev_printk(level, (netdev)->dev.parent, \ + "%s: " format, \ + netdev_name(netdev), ##args) +#endif /* <2.6.0 <2.6.21 <2.6.34 */ +#undef netdev_emerg +#define netdev_emerg(dev, format, args...) \ + netdev_printk(KERN_EMERG, dev, format, ##args) +#undef netdev_alert +#define netdev_alert(dev, format, args...) \ + netdev_printk(KERN_ALERT, dev, format, ##args) +#undef netdev_crit +#define netdev_crit(dev, format, args...) \ + netdev_printk(KERN_CRIT, dev, format, ##args) +#undef netdev_err +#define netdev_err(dev, format, args...) \ + netdev_printk(KERN_ERR, dev, format, ##args) +#undef netdev_warn +#define netdev_warn(dev, format, args...) \ + netdev_printk(KERN_WARNING, dev, format, ##args) +#undef netdev_notice +#define netdev_notice(dev, format, args...) \ + netdev_printk(KERN_NOTICE, dev, format, ##args) +#undef netdev_info +#define netdev_info(dev, format, args...) \ + netdev_printk(KERN_INFO, dev, format, ##args) +#undef netdev_dbg +#if defined(DEBUG) +#define netdev_dbg(__dev, format, args...) \ + netdev_printk(KERN_DEBUG, __dev, format, ##args) +#elif defined(CONFIG_DYNAMIC_DEBUG) +#define netdev_dbg(__dev, format, args...) \ +do { \ + dynamic_dev_dbg((__dev)->dev.parent, "%s: " format, \ + netdev_name(__dev), ##args); \ +} while (0) +#else /* DEBUG */ +#define netdev_dbg(__dev, format, args...) \ +({ \ + if (0) \ + netdev_printk(KERN_DEBUG, __dev, format, ##args); \ + 0; \ +}) +#endif /* DEBUG */ + +#undef netif_printk +#define netif_printk(priv, type, level, dev, fmt, args...) \ +do { \ + if (netif_msg_##type(priv)) \ + netdev_printk(level, (dev), fmt, ##args); \ +} while (0) + +#undef netif_emerg +#define netif_emerg(priv, type, dev, fmt, args...) \ + netif_level(emerg, priv, type, dev, fmt, ##args) +#undef netif_alert +#define netif_alert(priv, type, dev, fmt, args...) \ + netif_level(alert, priv, type, dev, fmt, ##args) +#undef netif_crit +#define netif_crit(priv, type, dev, fmt, args...) \ + netif_level(crit, priv, type, dev, fmt, ##args) +#undef netif_err +#define netif_err(priv, type, dev, fmt, args...) \ + netif_level(err, priv, type, dev, fmt, ##args) +#undef netif_warn +#define netif_warn(priv, type, dev, fmt, args...) \ + netif_level(warn, priv, type, dev, fmt, ##args) +#undef netif_notice +#define netif_notice(priv, type, dev, fmt, args...) \ + netif_level(notice, priv, type, dev, fmt, ##args) +#undef netif_info +#define netif_info(priv, type, dev, fmt, args...) \ + netif_level(info, priv, type, dev, fmt, ##args) +#undef netif_dbg +#define netif_dbg(priv, type, dev, fmt, args...) \ + netif_level(dbg, priv, type, dev, fmt, ##args) + +#ifdef SET_SYSTEM_SLEEP_PM_OPS +#define HAVE_SYSTEM_SLEEP_PM_OPS +#endif + +#ifndef for_each_set_bit +#define for_each_set_bit(bit, addr, size) \ + for ((bit) = find_first_bit((addr), (size)); \ + (bit) < (size); \ + (bit) = find_next_bit((addr), (size), (bit) + 1)) +#endif /* for_each_set_bit */ + +#ifndef DEFINE_DMA_UNMAP_ADDR +#define DEFINE_DMA_UNMAP_ADDR DECLARE_PCI_UNMAP_ADDR +#define DEFINE_DMA_UNMAP_LEN DECLARE_PCI_UNMAP_LEN +#define dma_unmap_addr pci_unmap_addr +#define dma_unmap_addr_set pci_unmap_addr_set +#define dma_unmap_len pci_unmap_len +#define dma_unmap_len_set pci_unmap_len_set +#endif /* DEFINE_DMA_UNMAP_ADDR */ + +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,3)) +#ifdef IGB_HWMON +#ifdef CONFIG_DEBUG_LOCK_ALLOC +#define sysfs_attr_init(attr) \ + do { \ + static struct lock_class_key __key; \ + (attr)->key = &__key; \ + } while (0) +#else +#define sysfs_attr_init(attr) do {} while (0) +#endif /* CONFIG_DEBUG_LOCK_ALLOC */ +#endif /* IGB_HWMON */ +#endif /* RHEL_RELEASE_CODE */ + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +static inline bool _kc_pm_runtime_suspended() +{ + return false; +} +#define pm_runtime_suspended(dev) _kc_pm_runtime_suspended() +#else /* 2.6.0 => 2.6.34 */ +static inline bool _kc_pm_runtime_suspended(struct device __always_unused *dev) +{ + return false; +} +#ifndef pm_runtime_suspended +#define pm_runtime_suspended(dev) _kc_pm_runtime_suspended(dev) +#endif +#endif /* 2.6.0 => 2.6.34 */ + +#ifndef pci_bus_speed +/* override pci_bus_speed introduced in 2.6.19 with an expanded enum type */ +enum _kc_pci_bus_speed { + _KC_PCIE_SPEED_2_5GT = 0x14, + _KC_PCIE_SPEED_5_0GT = 0x15, + _KC_PCIE_SPEED_8_0GT = 0x16, + _KC_PCI_SPEED_UNKNOWN = 0xff, +}; +#define pci_bus_speed _kc_pci_bus_speed +#define PCIE_SPEED_2_5GT _KC_PCIE_SPEED_2_5GT +#define PCIE_SPEED_5_0GT _KC_PCIE_SPEED_5_0GT +#define PCIE_SPEED_8_0GT _KC_PCIE_SPEED_8_0GT +#define PCI_SPEED_UNKNOWN _KC_PCI_SPEED_UNKNOWN +#endif /* pci_bus_speed */ + +#else /* < 2.6.34 */ +#define HAVE_SYSTEM_SLEEP_PM_OPS +#ifndef HAVE_SET_RX_MODE +#define HAVE_SET_RX_MODE +#endif + +#endif /* < 2.6.34 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) +ssize_t _kc_simple_write_to_buffer(void *to, size_t available, loff_t *ppos, + const void __user *from, size_t count); +#define simple_write_to_buffer _kc_simple_write_to_buffer + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4))) +static inline struct pci_dev *pci_physfn(struct pci_dev *dev) +{ +#ifdef HAVE_PCI_DEV_IS_VIRTFN_BIT +#ifdef CONFIG_PCI_IOV + if (dev->is_virtfn) + dev = dev->physfn; +#endif /* CONFIG_PCI_IOV */ +#endif /* HAVE_PCI_DEV_IS_VIRTFN_BIT */ + return dev; +} +#endif /* ! RHEL >= 6.4 */ + +#ifndef PCI_EXP_LNKSTA_NLW_SHIFT +#define PCI_EXP_LNKSTA_NLW_SHIFT 4 +#endif + +#ifndef numa_node_id +#define numa_node_id() 0 +#endif +#ifndef numa_mem_id +#define numa_mem_id numa_node_id +#endif +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0))) +#ifdef HAVE_TX_MQ +#include +#ifndef CONFIG_NETDEVICES_MULTIQUEUE +int _kc_netif_set_real_num_tx_queues(struct net_device *, unsigned int); +#else /* CONFIG_NETDEVICES_MULTI_QUEUE */ +static inline int _kc_netif_set_real_num_tx_queues(struct net_device *dev, + unsigned int txq) +{ + dev->egress_subqueue_count = txq; + return 0; +} +#endif /* CONFIG_NETDEVICES_MULTI_QUEUE */ +#else /* HAVE_TX_MQ */ +static inline int _kc_netif_set_real_num_tx_queues(struct net_device __always_unused *dev, + unsigned int __always_unused txq) +{ + return 0; +} +#endif /* HAVE_TX_MQ */ +#define netif_set_real_num_tx_queues(dev, txq) \ + _kc_netif_set_real_num_tx_queues(dev, txq) +#endif /* !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) */ +#ifndef ETH_FLAG_RXHASH +#define ETH_FLAG_RXHASH (1<<28) +#endif /* ETH_FLAG_RXHASH */ +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) +#define HAVE_IRQ_AFFINITY_HINT +#endif +struct device_node; +#else /* < 2.6.35 */ +#define HAVE_STRUCT_DEVICE_OF_NODE +#define HAVE_PM_QOS_REQUEST_LIST +#define HAVE_IRQ_AFFINITY_HINT +#include +#endif /* < 2.6.35 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ) +int _kc_ethtool_op_set_flags(struct net_device *, u32, u32); +#define ethtool_op_set_flags _kc_ethtool_op_set_flags +u32 _kc_ethtool_op_get_flags(struct net_device *); +#define ethtool_op_get_flags _kc_ethtool_op_get_flags + +enum { + WQ_UNBOUND = 0, + WQ_RESCUER = 0, +}; + +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +#ifdef NET_IP_ALIGN +#undef NET_IP_ALIGN +#endif +#define NET_IP_ALIGN 0 +#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */ + +#ifdef NET_SKB_PAD +#undef NET_SKB_PAD +#endif + +#if (L1_CACHE_BYTES > 32) +#define NET_SKB_PAD L1_CACHE_BYTES +#else +#define NET_SKB_PAD 32 +#endif + +static inline struct sk_buff *_kc_netdev_alloc_skb_ip_align(struct net_device *dev, + unsigned int length) +{ + struct sk_buff *skb; + + skb = alloc_skb(length + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC); + if (skb) { +#if (NET_IP_ALIGN + NET_SKB_PAD) + skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD); +#endif + skb->dev = dev; + } + return skb; +} + +#ifdef netdev_alloc_skb_ip_align +#undef netdev_alloc_skb_ip_align +#endif +#define netdev_alloc_skb_ip_align(n, l) _kc_netdev_alloc_skb_ip_align(n, l) + +#undef netif_level +#define netif_level(level, priv, type, dev, fmt, args...) \ +do { \ + if (netif_msg_##type(priv)) \ + netdev_##level(dev, fmt, ##args); \ +} while (0) + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,3))) +#undef usleep_range +#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000)) +#endif + +#define u64_stats_update_begin(a) do { } while(0) +#define u64_stats_update_end(a) do { } while(0) +#define u64_stats_fetch_begin(a) do { } while(0) +#define u64_stats_fetch_retry_bh(a,b) (0) +#define u64_stats_fetch_begin_bh(a) (0) + +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,1)) +#define HAVE_8021P_SUPPORT +#endif + +/* RHEL6.4 and SLES11sp2 backported skb_tx_timestamp */ +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(11,2,0))) +static inline void skb_tx_timestamp(struct sk_buff __always_unused *skb) +{ + return; +} +#endif + +#else /* < 2.6.36 */ + +#define msleep(x) do { if (x > 20) \ + msleep(x); \ + else \ + usleep_range(1000 * x, 2000 * x); \ + } while (0) + +#define HAVE_PM_QOS_REQUEST_ACTIVE +#define HAVE_8021P_SUPPORT +#define HAVE_NDO_GET_STATS64 +#endif /* < 2.6.36 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) ) +#define HAVE_NON_CONST_PCI_DRIVER_NAME +#ifndef netif_set_real_num_tx_queues +static inline int _kc_netif_set_real_num_tx_queues(struct net_device *dev, + unsigned int txq) +{ + netif_set_real_num_tx_queues(dev, txq); + return 0; +} +#define netif_set_real_num_tx_queues(dev, txq) \ + _kc_netif_set_real_num_tx_queues(dev, txq) +#endif +#ifndef netif_set_real_num_rx_queues +static inline int __kc_netif_set_real_num_rx_queues(struct net_device __always_unused *dev, + unsigned int __always_unused rxq) +{ + return 0; +} +#define netif_set_real_num_rx_queues(dev, rxq) \ + __kc_netif_set_real_num_rx_queues((dev), (rxq)) +#endif +#ifndef ETHTOOL_RXNTUPLE_ACTION_CLEAR +#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) +#endif +#ifndef VLAN_N_VID +#define VLAN_N_VID VLAN_GROUP_ARRAY_LEN +#endif /* VLAN_N_VID */ +#ifndef ETH_FLAG_TXVLAN +#define ETH_FLAG_TXVLAN BIT(7) +#endif /* ETH_FLAG_TXVLAN */ +#ifndef ETH_FLAG_RXVLAN +#define ETH_FLAG_RXVLAN BIT(8) +#endif /* ETH_FLAG_RXVLAN */ + +#define WQ_MEM_RECLAIM WQ_RESCUER + +static inline void _kc_skb_checksum_none_assert(struct sk_buff *skb) +{ + WARN_ON(skb->ip_summed != CHECKSUM_NONE); +} +#define skb_checksum_none_assert(skb) _kc_skb_checksum_none_assert(skb) + +static inline void *_kc_vzalloc_node(unsigned long size, int node) +{ + void *addr = vmalloc_node(size, node); + if (addr) + memset(addr, 0, size); + return addr; +} +#define vzalloc_node(_size, _node) _kc_vzalloc_node(_size, _node) + +static inline void *_kc_vzalloc(unsigned long size) +{ + void *addr = vmalloc(size); + if (addr) + memset(addr, 0, size); + return addr; +} +#define vzalloc(_size) _kc_vzalloc(_size) + +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,7)) || \ + (RHEL_RELEASE_CODE == RHEL_RELEASE_VERSION(6,0))) +static inline __be16 vlan_get_protocol(const struct sk_buff *skb) +{ + if (vlan_tx_tag_present(skb) || + skb->protocol != cpu_to_be16(ETH_P_8021Q)) + return skb->protocol; + + if (skb_headlen(skb) < sizeof(struct vlan_ethhdr)) + return 0; + + return ((struct vlan_ethhdr*)skb->data)->h_vlan_encapsulated_proto; +} +#endif /* !RHEL5.7+ || RHEL6.0 */ + +#ifdef HAVE_HW_TIME_STAMP +#define SKBTX_HW_TSTAMP BIT(0) +#define SKBTX_IN_PROGRESS BIT(2) +#define SKB_SHARED_TX_IS_UNION +#endif + +#ifndef device_wakeup_enable +#define device_wakeup_enable(dev) device_set_wakeup_enable(dev, true) +#endif + +#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,18) ) +#ifndef HAVE_VLAN_RX_REGISTER +#define HAVE_VLAN_RX_REGISTER +#endif +#endif /* > 2.4.18 */ +#endif /* < 2.6.37 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) ) +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ) +#define skb_checksum_start_offset(skb) skb_transport_offset(skb) +#else /* 2.6.22 -> 2.6.37 */ +static inline int _kc_skb_checksum_start_offset(const struct sk_buff *skb) +{ + return skb->csum_start - skb_headroom(skb); +} +#define skb_checksum_start_offset(skb) _kc_skb_checksum_start_offset(skb) +#endif /* 2.6.22 -> 2.6.37 */ +#if IS_ENABLED(CONFIG_DCB) +#ifndef IEEE_8021QAZ_MAX_TCS +#define IEEE_8021QAZ_MAX_TCS 8 +#endif +#ifndef DCB_CAP_DCBX_HOST +#define DCB_CAP_DCBX_HOST 0x01 +#endif +#ifndef DCB_CAP_DCBX_LLD_MANAGED +#define DCB_CAP_DCBX_LLD_MANAGED 0x02 +#endif +#ifndef DCB_CAP_DCBX_VER_CEE +#define DCB_CAP_DCBX_VER_CEE 0x04 +#endif +#ifndef DCB_CAP_DCBX_VER_IEEE +#define DCB_CAP_DCBX_VER_IEEE 0x08 +#endif +#ifndef DCB_CAP_DCBX_STATIC +#define DCB_CAP_DCBX_STATIC 0x10 +#endif +#endif /* CONFIG_DCB */ +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2)) +#define CONFIG_XPS +#endif /* RHEL_RELEASE_VERSION(6,2) */ +#endif /* < 2.6.38 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) ) +#ifndef TC_BITMASK +#define TC_BITMASK 15 +#endif +#ifndef NETIF_F_RXCSUM +#define NETIF_F_RXCSUM BIT(29) +#endif +#ifndef skb_queue_reverse_walk_safe +#define skb_queue_reverse_walk_safe(queue, skb, tmp) \ + for (skb = (queue)->prev, tmp = skb->prev; \ + skb != (struct sk_buff *)(queue); \ + skb = tmp, tmp = skb->prev) +#endif +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifndef FCOE_MTU +#define FCOE_MTU 2158 +#endif +#endif +#if IS_ENABLED(CONFIG_DCB) +#ifndef IEEE_8021QAZ_APP_SEL_ETHERTYPE +#define IEEE_8021QAZ_APP_SEL_ETHERTYPE 1 +#endif +#endif +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4))) +#define kstrtoul(a, b, c) ((*(c)) = simple_strtoul((a), NULL, (b)), 0) +#define kstrtouint(a, b, c) ((*(c)) = simple_strtoul((a), NULL, (b)), 0) +#define kstrtou32(a, b, c) ((*(c)) = simple_strtoul((a), NULL, (b)), 0) +#endif /* !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4)) */ +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0))) +u16 ___kc_skb_tx_hash(struct net_device *, const struct sk_buff *, u16); +#define __skb_tx_hash(n, s, q) ___kc_skb_tx_hash((n), (s), (q)) +u8 _kc_netdev_get_num_tc(struct net_device *dev); +#define netdev_get_num_tc(dev) _kc_netdev_get_num_tc(dev) +int _kc_netdev_set_num_tc(struct net_device *dev, u8 num_tc); +#define netdev_set_num_tc(dev, tc) _kc_netdev_set_num_tc((dev), (tc)) +#define netdev_reset_tc(dev) _kc_netdev_set_num_tc((dev), 0) +#define netdev_set_tc_queue(dev, tc, cnt, off) do {} while (0) +u8 _kc_netdev_get_prio_tc_map(struct net_device *dev, u8 up); +#define netdev_get_prio_tc_map(dev, up) _kc_netdev_get_prio_tc_map(dev, up) +#define netdev_set_prio_tc_map(dev, up, tc) do {} while (0) +#else /* RHEL6.1 or greater */ +#ifndef HAVE_MQPRIO +#define HAVE_MQPRIO +#endif /* HAVE_MQPRIO */ +#if IS_ENABLED(CONFIG_DCB) +#ifndef HAVE_DCBNL_IEEE +#define HAVE_DCBNL_IEEE +#ifndef IEEE_8021QAZ_TSA_STRICT +#define IEEE_8021QAZ_TSA_STRICT 0 +#endif +#ifndef IEEE_8021QAZ_TSA_ETS +#define IEEE_8021QAZ_TSA_ETS 2 +#endif +#ifndef IEEE_8021QAZ_APP_SEL_ETHERTYPE +#define IEEE_8021QAZ_APP_SEL_ETHERTYPE 1 +#endif +#endif +#endif /* CONFIG_DCB */ +#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */ + +#ifndef udp_csum +#define udp_csum __kc_udp_csum +static inline __wsum __kc_udp_csum(struct sk_buff *skb) +{ + __wsum csum = csum_partial(skb_transport_header(skb), + sizeof(struct udphdr), skb->csum); + + for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) { + csum = csum_add(csum, skb->csum); + } + return csum; +} +#endif /* udp_csum */ +#else /* < 2.6.39 */ +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#ifndef HAVE_NETDEV_OPS_FCOE_DDP_TARGET +#define HAVE_NETDEV_OPS_FCOE_DDP_TARGET +#endif +#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */ +#ifndef HAVE_MQPRIO +#define HAVE_MQPRIO +#endif +#ifndef HAVE_SETUP_TC +#define HAVE_SETUP_TC +#endif +#ifdef CONFIG_DCB +#ifndef HAVE_DCBNL_IEEE +#define HAVE_DCBNL_IEEE +#endif +#endif /* CONFIG_DCB */ +#ifndef HAVE_NDO_SET_FEATURES +#define HAVE_NDO_SET_FEATURES +#endif +#define HAVE_IRQ_AFFINITY_NOTIFY +#endif /* < 2.6.39 */ + +/*****************************************************************************/ +/* use < 2.6.40 because of a Fedora 15 kernel update where they + * updated the kernel version to 2.6.40.x and they back-ported 3.0 features + * like set_phys_id for ethtool. + */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40) ) +#ifdef ETHTOOL_GRXRINGS +#ifndef FLOW_EXT +#define FLOW_EXT 0x80000000 +union _kc_ethtool_flow_union { + struct ethtool_tcpip4_spec tcp_ip4_spec; + struct ethtool_usrip4_spec usr_ip4_spec; + __u8 hdata[60]; +}; +struct _kc_ethtool_flow_ext { + __be16 vlan_etype; + __be16 vlan_tci; + __be32 data[2]; +}; +struct _kc_ethtool_rx_flow_spec { + __u32 flow_type; + union _kc_ethtool_flow_union h_u; + struct _kc_ethtool_flow_ext h_ext; + union _kc_ethtool_flow_union m_u; + struct _kc_ethtool_flow_ext m_ext; + __u64 ring_cookie; + __u32 location; +}; +#define ethtool_rx_flow_spec _kc_ethtool_rx_flow_spec +#endif /* FLOW_EXT */ +#endif + +#define pci_disable_link_state_locked pci_disable_link_state + +#ifndef PCI_LTR_VALUE_MASK +#define PCI_LTR_VALUE_MASK 0x000003ff +#endif +#ifndef PCI_LTR_SCALE_MASK +#define PCI_LTR_SCALE_MASK 0x00001c00 +#endif +#ifndef PCI_LTR_SCALE_SHIFT +#define PCI_LTR_SCALE_SHIFT 10 +#endif + +#else /* < 2.6.40 */ +#define HAVE_ETHTOOL_SET_PHYS_ID +#endif /* < 2.6.40 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ) +#define USE_LEGACY_PM_SUPPORT +#ifndef kfree_rcu +#define kfree_rcu(_ptr, _rcu_head) kfree(_ptr) +#endif /* kfree_rcu */ +#ifndef kstrtol_from_user +#define kstrtol_from_user(s, c, b, r) _kc_kstrtol_from_user(s, c, b, r) +static inline int _kc_kstrtol_from_user(const char __user *s, size_t count, + unsigned int base, long *res) +{ + /* sign, base 2 representation, newline, terminator */ + char buf[1 + sizeof(long) * 8 + 1 + 1]; + + count = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, s, count)) + return -EFAULT; + buf[count] = '\0'; + return strict_strtol(buf, base, res); +} +#endif + +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,0) || \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,7))) +/* 20000base_blah_full Supported and Advertised Registers */ +#define SUPPORTED_20000baseMLD2_Full BIT(21) +#define SUPPORTED_20000baseKR2_Full BIT(22) +#define ADVERTISED_20000baseMLD2_Full BIT(21) +#define ADVERTISED_20000baseKR2_Full BIT(22) +#endif /* RHEL_RELEASE_CODE */ +#endif /* < 3.0.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) ) +#ifndef __netdev_alloc_skb_ip_align +#define __netdev_alloc_skb_ip_align(d,l,_g) netdev_alloc_skb_ip_align(d,l) +#endif /* __netdev_alloc_skb_ip_align */ +#define dcb_ieee_setapp(dev, app) dcb_setapp(dev, app) +#define dcb_ieee_delapp(dev, app) 0 +#define dcb_ieee_getapp_mask(dev, app) (1 << app->priority) + +/* 1000BASE-T Control register */ +#define CTL1000_AS_MASTER 0x0800 +#define CTL1000_ENABLE_MASTER 0x1000 + +/* kernels less than 3.0.0 don't have this */ +#ifndef ETH_P_8021AD +#define ETH_P_8021AD 0x88A8 +#endif + +/* Stub definition for !CONFIG_OF is introduced later */ +#ifdef CONFIG_OF +static inline struct device_node * +pci_device_to_OF_node(struct pci_dev __maybe_unused *pdev) +{ +#ifdef HAVE_STRUCT_DEVICE_OF_NODE + return pdev ? pdev->dev.of_node : NULL; +#else + return NULL; +#endif /* !HAVE_STRUCT_DEVICE_OF_NODE */ +} +#endif /* CONFIG_OF */ +#else /* < 3.1.0 */ +#ifndef HAVE_DCBNL_IEEE_DELAPP +#define HAVE_DCBNL_IEEE_DELAPP +#endif +#endif /* < 3.1.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ) +#ifndef dma_zalloc_coherent +#define dma_zalloc_coherent(d, s, h, f) _kc_dma_zalloc_coherent(d, s, h, f) +static inline void *_kc_dma_zalloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + void *ret = dma_alloc_coherent(dev, size, dma_handle, flag); + if (ret) + memset(ret, 0, size); + return ret; +} +#endif +#ifdef ETHTOOL_GRXRINGS +#define HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS +#endif /* ETHTOOL_GRXRINGS */ + +#ifndef skb_frag_size +#define skb_frag_size(frag) _kc_skb_frag_size(frag) +static inline unsigned int _kc_skb_frag_size(const skb_frag_t *frag) +{ + return frag->size; +} +#endif /* skb_frag_size */ + +#ifndef skb_frag_size_sub +#define skb_frag_size_sub(frag, delta) _kc_skb_frag_size_sub(frag, delta) +static inline void _kc_skb_frag_size_sub(skb_frag_t *frag, int delta) +{ + frag->size -= delta; +} +#endif /* skb_frag_size_sub */ + +#ifndef skb_frag_page +#define skb_frag_page(frag) _kc_skb_frag_page(frag) +static inline struct page *_kc_skb_frag_page(const skb_frag_t *frag) +{ + return frag->page; +} +#endif /* skb_frag_page */ + +#ifndef skb_frag_address +#define skb_frag_address(frag) _kc_skb_frag_address(frag) +static inline void *_kc_skb_frag_address(const skb_frag_t *frag) +{ + return page_address(skb_frag_page(frag)) + frag->page_offset; +} +#endif /* skb_frag_address */ + +#ifndef skb_frag_dma_map +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) +#include +#endif +#define skb_frag_dma_map(dev,frag,offset,size,dir) \ + _kc_skb_frag_dma_map(dev,frag,offset,size,dir) +static inline dma_addr_t _kc_skb_frag_dma_map(struct device *dev, + const skb_frag_t *frag, + size_t offset, size_t size, + enum dma_data_direction dir) +{ + return dma_map_page(dev, skb_frag_page(frag), + frag->page_offset + offset, size, dir); +} +#endif /* skb_frag_dma_map */ + +#ifndef __skb_frag_unref +#define __skb_frag_unref(frag) __kc_skb_frag_unref(frag) +static inline void __kc_skb_frag_unref(skb_frag_t *frag) +{ + put_page(skb_frag_page(frag)); +} +#endif /* __skb_frag_unref */ + +#ifndef SPEED_UNKNOWN +#define SPEED_UNKNOWN -1 +#endif +#ifndef DUPLEX_UNKNOWN +#define DUPLEX_UNKNOWN 0xff +#endif +#if ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,3)) ||\ + (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0))) +#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED +#define HAVE_PCI_DEV_FLAGS_ASSIGNED +#endif +#endif +#else /* < 3.2.0 */ +#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED +#define HAVE_PCI_DEV_FLAGS_ASSIGNED +#define HAVE_VF_SPOOFCHK_CONFIGURE +#endif +#ifndef HAVE_SKB_L4_RXHASH +#define HAVE_SKB_L4_RXHASH +#endif +#define HAVE_IOMMU_PRESENT +#define HAVE_PM_QOS_REQUEST_LIST_NEW +#endif /* < 3.2.0 */ + +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE == RHEL_RELEASE_VERSION(6,2)) +#undef ixgbe_get_netdev_tc_txq +#define ixgbe_get_netdev_tc_txq(dev, tc) (&netdev_extended(dev)->qos_data.tc_to_txq[tc]) +#endif +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) ) +/* NOTE: the order of parameters to _kc_alloc_workqueue() is different than + * alloc_workqueue() to avoid compiler warning from -Wvarargs + */ +static inline struct workqueue_struct * __attribute__ ((format(printf, 3, 4))) +_kc_alloc_workqueue(__maybe_unused int flags, __maybe_unused int max_active, + const char *fmt, ...) +{ + struct workqueue_struct *wq; + va_list args, temp; + unsigned int len; + char *p; + + va_start(args, fmt); + va_copy(temp, args); + len = vsnprintf(NULL, 0, fmt, temp); + va_end(temp); + + p = kmalloc(len + 1, GFP_KERNEL); + if (!p) { + va_end(args); + return NULL; + } + + vsnprintf(p, len + 1, fmt, args); + va_end(args); +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ) + wq = create_workqueue(p); +#else + wq = alloc_workqueue(p, flags, max_active); +#endif + kfree(p); + + return wq; +} +#ifdef alloc_workqueue +#undef alloc_workqueue +#endif +#define alloc_workqueue(fmt, flags, max_active, args...) \ + _kc_alloc_workqueue(flags, max_active, fmt, ##args) + +#if !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,5)) +typedef u32 netdev_features_t; +#endif +#undef PCI_EXP_TYPE_RC_EC +#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ +#ifndef CONFIG_BQL +#define netdev_tx_completed_queue(_q, _p, _b) do {} while (0) +#define netdev_completed_queue(_n, _p, _b) do {} while (0) +#define netdev_tx_sent_queue(_q, _b) do {} while (0) +#define netdev_sent_queue(_n, _b) do {} while (0) +#define netdev_tx_reset_queue(_q) do {} while (0) +#define netdev_reset_queue(_n) do {} while (0) +#endif +#if (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) +#define HAVE_ETHTOOL_GRXFHINDIR_SIZE +#endif /* SLE_VERSION(11,3,0) */ +#define netif_xmit_stopped(_q) netif_tx_queue_stopped(_q) +#if !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,4,0)) +static inline int __kc_ipv6_skip_exthdr(const struct sk_buff *skb, int start, + u8 *nexthdrp, + __be16 __always_unused *frag_offp) +{ + return ipv6_skip_exthdr(skb, start, nexthdrp); +} +#undef ipv6_skip_exthdr +#define ipv6_skip_exthdr(a,b,c,d) __kc_ipv6_skip_exthdr((a), (b), (c), (d)) +#endif /* !SLES11sp4 or greater */ + +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(11,3,0))) +static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) +{ + return index % n_rx_rings; +} +#endif + +#else /* ! < 3.3.0 */ +#define HAVE_ETHTOOL_GRXFHINDIR_SIZE +#define HAVE_INT_NDO_VLAN_RX_ADD_VID +#ifdef ETHTOOL_SRXNTUPLE +#undef ETHTOOL_SRXNTUPLE +#endif +#endif /* < 3.3.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) ) +#ifndef NETIF_F_RXFCS +#define NETIF_F_RXFCS 0 +#endif /* NETIF_F_RXFCS */ +#ifndef NETIF_F_RXALL +#define NETIF_F_RXALL 0 +#endif /* NETIF_F_RXALL */ + +#if !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) +#define NUMTCS_RETURNS_U8 + +int _kc_simple_open(struct inode *inode, struct file *file); +#define simple_open _kc_simple_open +#endif /* !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) */ + +#ifndef skb_add_rx_frag +#define skb_add_rx_frag _kc_skb_add_rx_frag +void _kc_skb_add_rx_frag(struct sk_buff * skb, int i, struct page *page, + int off, int size, unsigned int truesize); +#endif +#ifdef NET_ADDR_RANDOM +#define eth_hw_addr_random(N) do { \ + eth_random_addr(N->dev_addr); \ + N->addr_assign_type |= NET_ADDR_RANDOM; \ + } while (0) +#else /* NET_ADDR_RANDOM */ +#define eth_hw_addr_random(N) eth_random_addr(N->dev_addr) +#endif /* NET_ADDR_RANDOM */ + +#ifndef for_each_set_bit_from +#define for_each_set_bit_from(bit, addr, size) \ + for ((bit) = find_next_bit((addr), (size), (bit)); \ + (bit) < (size); \ + (bit) = find_next_bit((addr), (size), (bit) + 1)) +#endif /* for_each_set_bit_from */ + +#else /* < 3.4.0 */ +#include +#endif /* >= 3.4.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ) || \ + ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4) ) +#ifndef NO_PTP_SUPPORT +#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) +#define HAVE_PTP_1588_CLOCK +#endif /* CONFIG_PTP_1588_CLOCK */ +#endif /* !NO_PTP_SUPPORT */ +#endif /* >= 3.0.0 || RHEL_RELEASE > 6.4 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) ) + +#ifndef BITS_PER_LONG_LONG +#define BITS_PER_LONG_LONG 64 +#endif + +#ifndef ether_addr_equal +static inline bool __kc_ether_addr_equal(const u8 *addr1, const u8 *addr2) +{ + return !compare_ether_addr(addr1, addr2); +} +#define ether_addr_equal(_addr1, _addr2) __kc_ether_addr_equal((_addr1),(_addr2)) +#endif + +/* Definitions for !CONFIG_OF_NET are introduced in 3.10 */ +#ifdef CONFIG_OF_NET +static inline int of_get_phy_mode(struct device_node __always_unused *np) +{ + return -ENODEV; +} + +static inline const void * +of_get_mac_address(struct device_node __always_unused *np) +{ + return NULL; +} +#endif +#else +#include +#define HAVE_FDB_OPS +#define HAVE_ETHTOOL_GET_TS_INFO +#endif /* < 3.5.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) ) +#define PCI_EXP_LNKCAP2 44 /* Link Capability 2 */ + +#ifndef MDIO_EEE_100TX +#define MDIO_EEE_100TX 0x0002 /* 100TX EEE cap */ +#endif +#ifndef MDIO_EEE_1000T +#define MDIO_EEE_1000T 0x0004 /* 1000T EEE cap */ +#endif +#ifndef MDIO_EEE_10GT +#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ +#endif +#ifndef MDIO_EEE_1000KX +#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ +#endif +#ifndef MDIO_EEE_10GKX4 +#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ +#endif +#ifndef MDIO_EEE_10GKR +#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ +#endif + +#ifndef __GFP_MEMALLOC +#define __GFP_MEMALLOC 0 +#endif + +#ifndef eth_broadcast_addr +#define eth_broadcast_addr _kc_eth_broadcast_addr +static inline void _kc_eth_broadcast_addr(u8 *addr) +{ + memset(addr, 0xff, ETH_ALEN); +} +#endif + +#ifndef eth_random_addr +#define eth_random_addr _kc_eth_random_addr +static inline void _kc_eth_random_addr(u8 *addr) +{ + get_random_bytes(addr, ETH_ALEN); + addr[0] &= 0xfe; /* clear multicast */ + addr[0] |= 0x02; /* set local assignment */ +} +#endif /* eth_random_addr */ + +#ifndef DMA_ATTR_SKIP_CPU_SYNC +#define DMA_ATTR_SKIP_CPU_SYNC 0 +#endif +#else /* < 3.6.0 */ +#define HAVE_STRUCT_PAGE_PFMEMALLOC +#endif /* < 3.6.0 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) ) +#include +#ifndef ADVERTISED_40000baseKR4_Full +/* these defines were all added in one commit, so should be safe + * to trigger activiation on one define + */ +#define SUPPORTED_40000baseKR4_Full BIT(23) +#define SUPPORTED_40000baseCR4_Full BIT(24) +#define SUPPORTED_40000baseSR4_Full BIT(25) +#define SUPPORTED_40000baseLR4_Full BIT(26) +#define ADVERTISED_40000baseKR4_Full BIT(23) +#define ADVERTISED_40000baseCR4_Full BIT(24) +#define ADVERTISED_40000baseSR4_Full BIT(25) +#define ADVERTISED_40000baseLR4_Full BIT(26) +#endif + +#ifndef mmd_eee_cap_to_ethtool_sup_t +/** + * mmd_eee_cap_to_ethtool_sup_t + * @eee_cap: value of the MMD EEE Capability register + * + * A small helper function that translates MMD EEE Capability (3.20) bits + * to ethtool supported settings. + */ +static inline u32 __kc_mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap) +{ + u32 supported = 0; + + if (eee_cap & MDIO_EEE_100TX) + supported |= SUPPORTED_100baseT_Full; + if (eee_cap & MDIO_EEE_1000T) + supported |= SUPPORTED_1000baseT_Full; + if (eee_cap & MDIO_EEE_10GT) + supported |= SUPPORTED_10000baseT_Full; + if (eee_cap & MDIO_EEE_1000KX) + supported |= SUPPORTED_1000baseKX_Full; + if (eee_cap & MDIO_EEE_10GKX4) + supported |= SUPPORTED_10000baseKX4_Full; + if (eee_cap & MDIO_EEE_10GKR) + supported |= SUPPORTED_10000baseKR_Full; + + return supported; +} +#define mmd_eee_cap_to_ethtool_sup_t(eee_cap) \ + __kc_mmd_eee_cap_to_ethtool_sup_t(eee_cap) +#endif /* mmd_eee_cap_to_ethtool_sup_t */ + +#ifndef mmd_eee_adv_to_ethtool_adv_t +/** + * mmd_eee_adv_to_ethtool_adv_t + * @eee_adv: value of the MMD EEE Advertisement/Link Partner Ability registers + * + * A small helper function that translates the MMD EEE Advertisement (7.60) + * and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement + * settings. + */ +static inline u32 __kc_mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) +{ + u32 adv = 0; + + if (eee_adv & MDIO_EEE_100TX) + adv |= ADVERTISED_100baseT_Full; + if (eee_adv & MDIO_EEE_1000T) + adv |= ADVERTISED_1000baseT_Full; + if (eee_adv & MDIO_EEE_10GT) + adv |= ADVERTISED_10000baseT_Full; + if (eee_adv & MDIO_EEE_1000KX) + adv |= ADVERTISED_1000baseKX_Full; + if (eee_adv & MDIO_EEE_10GKX4) + adv |= ADVERTISED_10000baseKX4_Full; + if (eee_adv & MDIO_EEE_10GKR) + adv |= ADVERTISED_10000baseKR_Full; + + return adv; +} + +#define mmd_eee_adv_to_ethtool_adv_t(eee_adv) \ + __kc_mmd_eee_adv_to_ethtool_adv_t(eee_adv) +#endif /* mmd_eee_adv_to_ethtool_adv_t */ + +#ifndef ethtool_adv_to_mmd_eee_adv_t +/** + * ethtool_adv_to_mmd_eee_adv_t + * @adv: the ethtool advertisement settings + * + * A small helper function that translates ethtool advertisement settings + * to EEE advertisements for the MMD EEE Advertisement (7.60) and + * MMD EEE Link Partner Ability (7.61) registers. + */ +static inline u16 __kc_ethtool_adv_to_mmd_eee_adv_t(u32 adv) +{ + u16 reg = 0; + + if (adv & ADVERTISED_100baseT_Full) + reg |= MDIO_EEE_100TX; + if (adv & ADVERTISED_1000baseT_Full) + reg |= MDIO_EEE_1000T; + if (adv & ADVERTISED_10000baseT_Full) + reg |= MDIO_EEE_10GT; + if (adv & ADVERTISED_1000baseKX_Full) + reg |= MDIO_EEE_1000KX; + if (adv & ADVERTISED_10000baseKX4_Full) + reg |= MDIO_EEE_10GKX4; + if (adv & ADVERTISED_10000baseKR_Full) + reg |= MDIO_EEE_10GKR; + + return reg; +} +#define ethtool_adv_to_mmd_eee_adv_t(adv) __kc_ethtool_adv_to_mmd_eee_adv_t(adv) +#endif /* ethtool_adv_to_mmd_eee_adv_t */ + +#ifndef pci_pcie_type +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) +static inline u8 pci_pcie_type(struct pci_dev *pdev) +{ + int pos; + u16 reg16; + + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + BUG_ON(!pos); + pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); + return (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; +} +#else /* < 2.6.24 */ +#define pci_pcie_type(x) (x)->pcie_type +#endif /* < 2.6.24 */ +#endif /* pci_pcie_type */ + +#if ( ! ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4) ) ) && \ + ( ! ( SLE_VERSION_CODE >= SLE_VERSION(11,3,0) ) ) && \ + ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ) +#define ptp_clock_register(caps, args...) ptp_clock_register(caps) +#endif + +#ifndef pcie_capability_read_word +int __kc_pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val); +#define pcie_capability_read_word(d,p,v) __kc_pcie_capability_read_word(d,p,v) +#endif /* pcie_capability_read_word */ + +#ifndef pcie_capability_read_dword +int __kc_pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val); +#define pcie_capability_read_dword(d,p,v) __kc_pcie_capability_read_dword(d,p,v) +#endif + +#ifndef pcie_capability_write_word +int __kc_pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); +#define pcie_capability_write_word(d,p,v) __kc_pcie_capability_write_word(d,p,v) +#endif /* pcie_capability_write_word */ + +#ifndef pcie_capability_clear_and_set_word +int __kc_pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, + u16 clear, u16 set); +#define pcie_capability_clear_and_set_word(d,p,c,s) \ + __kc_pcie_capability_clear_and_set_word(d,p,c,s) +#endif /* pcie_capability_clear_and_set_word */ + +#ifndef pcie_capability_clear_word +int __kc_pcie_capability_clear_word(struct pci_dev *dev, int pos, + u16 clear); +#define pcie_capability_clear_word(d, p, c) \ + __kc_pcie_capability_clear_word(d, p, c) +#endif /* pcie_capability_clear_word */ + +#ifndef PCI_EXP_LNKSTA2 +#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ +#endif + +#if (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) +#define USE_CONST_DEV_UC_CHAR +#define HAVE_NDO_FDB_ADD_NLATTR +#endif + +#if !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,8)) +#define napi_gro_flush(_napi, _flush_old) napi_gro_flush(_napi) +#endif /* !RHEL6.8+ */ + +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,6)) +#include +#else + +#define DEFINE_HASHTABLE(name, bits) \ + struct hlist_head name[1 << (bits)] = \ + { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } + +#define DEFINE_READ_MOSTLY_HASHTABLE(name, bits) \ + struct hlist_head name[1 << (bits)] __read_mostly = \ + { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } + +#define DECLARE_HASHTABLE(name, bits) \ + struct hlist_head name[1 << (bits)] + +#define HASH_SIZE(name) (ARRAY_SIZE(name)) +#define HASH_BITS(name) ilog2(HASH_SIZE(name)) + +/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ +#define hash_min(val, bits) \ + (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) + +static inline void __hash_init(struct hlist_head *ht, unsigned int sz) +{ + unsigned int i; + + for (i = 0; i < sz; i++) + INIT_HLIST_HEAD(&ht[i]); +} + +#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) + +#define hash_add(hashtable, node, key) \ + hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) + +static inline bool hash_hashed(struct hlist_node *node) +{ + return !hlist_unhashed(node); +} + +static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz) +{ + unsigned int i; + + for (i = 0; i < sz; i++) + if (!hlist_empty(&ht[i])) + return false; + + return true; +} + +#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) + +static inline void hash_del(struct hlist_node *node) +{ + hlist_del_init(node); +} +#endif /* RHEL >= 6.6 */ + +/* We don't have @flags support prior to 3.7, so we'll simply ignore the flags + * parameter on these older kernels. + */ +#define __setup_timer(_timer, _fn, _data, _flags) \ + setup_timer((_timer), (_fn), (_data)) \ + +#if ( ! ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,7) ) ) && \ + ( ! ( SLE_VERSION_CODE >= SLE_VERSION(12,0,0) ) ) + +#ifndef mod_delayed_work +/** + * __mod_delayed_work - modify delay or queue delayed work + * @wq: workqueue to use + * @dwork: delayed work to queue + * @delay: number of jiffies to wait before queueing + * + * Return: %true if @dwork was pending and was rescheduled; + * %false if it wasn't pending + * + * Note: the dwork parameter was declared as a void* + * to avoid comptibility problems with early 2.6 kernels + * where struct delayed_work is not declared. Unlike the original + * implementation flags are not preserved and it shouldn't be + * used in the interrupt context. + */ +static inline bool __mod_delayed_work(struct workqueue_struct *wq, + void *dwork, + unsigned long delay) +{ + bool ret = cancel_delayed_work(dwork); + queue_delayed_work(wq, dwork, delay); + return ret; +} +#define mod_delayed_work(wq, dwork, delay) __mod_delayed_work(wq, dwork, delay) +#endif /* mod_delayed_work */ + +#endif /* !(RHEL >= 6.7) && !(SLE >= 12.0) */ +#else /* >= 3.7.0 */ +#include +#define HAVE_CONST_STRUCT_PCI_ERROR_HANDLERS +#define USE_CONST_DEV_UC_CHAR +#define HAVE_NDO_FDB_ADD_NLATTR +#endif /* >= 3.7.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) ) +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,5)) && \ + !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,4,0))) +#ifndef pci_sriov_set_totalvfs +static inline int __kc_pci_sriov_set_totalvfs(struct pci_dev __always_unused *dev, u16 __always_unused numvfs) +{ + return 0; +} +#define pci_sriov_set_totalvfs(a, b) __kc_pci_sriov_set_totalvfs((a), (b)) +#endif +#endif /* !(RHEL_RELEASE_CODE >= 6.5 && SLE_VERSION_CODE >= 11.4) */ +#ifndef PCI_EXP_LNKCTL_ASPM_L0S +#define PCI_EXP_LNKCTL_ASPM_L0S 0x01 /* L0s Enable */ +#endif +#ifndef PCI_EXP_LNKCTL_ASPM_L1 +#define PCI_EXP_LNKCTL_ASPM_L1 0x02 /* L1 Enable */ +#endif +#define HAVE_CONFIG_HOTPLUG +/* Reserved Ethernet Addresses per IEEE 802.1Q */ +static const u8 eth_reserved_addr_base[ETH_ALEN] __aligned(2) = { + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; + +#ifndef is_link_local_ether_addr +static inline bool __kc_is_link_local_ether_addr(const u8 *addr) +{ + __be16 *a = (__be16 *)addr; + static const __be16 *b = (const __be16 *)eth_reserved_addr_base; + static const __be16 m = cpu_to_be16(0xfff0); + + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; +} +#define is_link_local_ether_addr(addr) __kc_is_link_local_ether_addr(addr) +#endif /* is_link_local_ether_addr */ + +#ifndef FLOW_MAC_EXT +#define FLOW_MAC_EXT 0x40000000 +#endif /* FLOW_MAC_EXT */ + +#if (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,4,0)) +#define HAVE_SRIOV_CONFIGURE +#endif + +#ifndef PCI_EXP_LNKCAP_SLS_2_5GB +#define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ +#endif + +#ifndef PCI_EXP_LNKCAP_SLS_5_0GB +#define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */ +#endif + +#undef PCI_EXP_LNKCAP2_SLS_2_5GB +#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ + +#undef PCI_EXP_LNKCAP2_SLS_5_0GB +#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ + +#undef PCI_EXP_LNKCAP2_SLS_8_0GB +#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ + +#else /* >= 3.8.0 */ +#ifndef __devinit +#define __devinit +#endif + +#ifndef __devinitdata +#define __devinitdata +#endif + +#ifndef __devinitconst +#define __devinitconst +#endif + +#ifndef __devexit +#define __devexit +#endif + +#ifndef __devexit_p +#define __devexit_p +#endif + +#ifndef HAVE_ENCAP_CSUM_OFFLOAD +#define HAVE_ENCAP_CSUM_OFFLOAD +#endif + +#ifndef HAVE_GRE_ENCAP_OFFLOAD +#define HAVE_GRE_ENCAP_OFFLOAD +#endif + +#ifndef HAVE_SRIOV_CONFIGURE +#define HAVE_SRIOV_CONFIGURE +#endif + +#define HAVE_BRIDGE_ATTRIBS +#ifndef BRIDGE_MODE_VEB +#define BRIDGE_MODE_VEB 0 /* Default loopback mode */ +#endif /* BRIDGE_MODE_VEB */ +#ifndef BRIDGE_MODE_VEPA +#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */ +#endif /* BRIDGE_MODE_VEPA */ +#endif /* >= 3.8.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) + +#undef BUILD_BUG_ON +#ifdef __CHECKER__ +#define BUILD_BUG_ON(condition) (0) +#else /* __CHECKER__ */ +#ifndef __compiletime_warning +#if defined(__GNUC__) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40400) +#define __compiletime_warning(message) __attribute__((warning(message))) +#else /* __GNUC__ */ +#define __compiletime_warning(message) +#endif /* __GNUC__ */ +#endif /* __compiletime_warning */ +#ifndef __compiletime_error +#if defined(__GNUC__) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40400) +#define __compiletime_error(message) __attribute__((error(message))) +#define __compiletime_error_fallback(condition) do { } while (0) +#else /* __GNUC__ */ +#define __compiletime_error(message) +#define __compiletime_error_fallback(condition) \ + do { ((void)sizeof(char[1 - 2 * condition])); } while (0) +#endif /* __GNUC__ */ +#else /* __compiletime_error */ +#define __compiletime_error_fallback(condition) do { } while (0) +#endif /* __compiletime_error */ +#define __compiletime_assert(condition, msg, prefix, suffix) \ + do { \ + bool __cond = !(condition); \ + extern void prefix ## suffix(void) __compiletime_error(msg); \ + if (__cond) \ + prefix ## suffix(); \ + __compiletime_error_fallback(__cond); \ + } while (0) + +#define _compiletime_assert(condition, msg, prefix, suffix) \ + __compiletime_assert(condition, msg, prefix, suffix) +#define compiletime_assert(condition, msg) \ + _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) +#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) +#ifndef __OPTIMIZE__ +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) +#else /* __OPTIMIZE__ */ +#define BUILD_BUG_ON(condition) \ + BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) +#endif /* __OPTIMIZE__ */ +#endif /* __CHECKER__ */ + +#undef hlist_entry +#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + +#undef hlist_entry_safe +#define hlist_entry_safe(ptr, type, member) \ + ({ typeof(ptr) ____ptr = (ptr); \ + ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ + }) + +#undef hlist_for_each_entry +#define hlist_for_each_entry(pos, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +#undef hlist_for_each_entry_safe +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \ + pos && ({ n = pos->member.next; 1; }); \ + pos = hlist_entry_safe(n, typeof(*pos), member)) + +#undef hlist_for_each_entry_continue +#define hlist_for_each_entry_continue(pos, member) \ + for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +#undef hlist_for_each_entry_from +#define hlist_for_each_entry_from(pos, member) \ + for (; pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) + +#undef hash_for_each +#define hash_for_each(name, bkt, obj, member) \ + for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ + (bkt)++)\ + hlist_for_each_entry(obj, &name[bkt], member) + +#undef hash_for_each_safe +#define hash_for_each_safe(name, bkt, tmp, obj, member) \ + for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ + (bkt)++)\ + hlist_for_each_entry_safe(obj, tmp, &name[bkt], member) + +#undef hash_for_each_possible +#define hash_for_each_possible(name, obj, member, key) \ + hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member) + +#undef hash_for_each_possible_safe +#define hash_for_each_possible_safe(name, obj, tmp, member, key) \ + hlist_for_each_entry_safe(obj, tmp,\ + &name[hash_min(key, HASH_BITS(name))], member) + +#ifdef CONFIG_XPS +int __kc_netif_set_xps_queue(struct net_device *, const struct cpumask *, u16); +#define netif_set_xps_queue(_dev, _mask, _idx) __kc_netif_set_xps_queue((_dev), (_mask), (_idx)) +#else /* CONFIG_XPS */ +#define netif_set_xps_queue(_dev, _mask, _idx) do {} while (0) +#endif /* CONFIG_XPS */ + +#ifdef HAVE_NETDEV_SELECT_QUEUE +#define _kc_hashrnd 0xd631614b /* not so random hash salt */ +u16 __kc_netdev_pick_tx(struct net_device *dev, struct sk_buff *skb); +#define __netdev_pick_tx __kc_netdev_pick_tx +#endif /* HAVE_NETDEV_SELECT_QUEUE */ +#else +#define HAVE_BRIDGE_FILTER +#define HAVE_FDB_DEL_NLATTR +#endif /* < 3.9.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ) +#ifndef NAPI_POLL_WEIGHT +#define NAPI_POLL_WEIGHT 64 +#endif +#ifdef CONFIG_PCI_IOV +int __kc_pci_vfs_assigned(struct pci_dev *dev); +#else +static inline int __kc_pci_vfs_assigned(struct pci_dev __always_unused *dev) +{ + return 0; +} +#endif +#define pci_vfs_assigned(dev) __kc_pci_vfs_assigned(dev) + +#ifndef list_first_entry_or_null +#define list_first_entry_or_null(ptr, type, member) \ + (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) +#endif + +#ifndef VLAN_TX_COOKIE_MAGIC +static inline struct sk_buff *__kc__vlan_hwaccel_put_tag(struct sk_buff *skb, + u16 vlan_tci) +{ +#ifdef VLAN_TAG_PRESENT + vlan_tci |= VLAN_TAG_PRESENT; +#endif + skb->vlan_tci = vlan_tci; + return skb; +} +#define __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci) \ + __kc__vlan_hwaccel_put_tag(skb, vlan_tci) +#endif + +#ifndef PCI_DEVID +#define PCI_DEVID(bus, devfn) ((((u16)(bus)) << 8) | (devfn)) +#endif + +/* The definitions for these functions when CONFIG_OF_NET is defined are + * pulled in from . For kernels older than 3.5 we already have + * backports for when CONFIG_OF_NET is true. These are separated and + * duplicated in order to cover all cases so that all kernels get either the + * real definitions (when CONFIG_OF_NET is defined) or the stub definitions + * (when CONFIG_OF_NET is not defined, or the kernel is too old to have real + * definitions). + */ +#ifndef CONFIG_OF_NET +static inline int of_get_phy_mode(struct device_node __always_unused *np) +{ + return -ENODEV; +} + +static inline const void * +of_get_mac_address(struct device_node __always_unused *np) +{ + return NULL; +} +#endif + +#else /* >= 3.10.0 */ +#define HAVE_ENCAP_TSO_OFFLOAD +#define USE_DEFAULT_FDB_DEL_DUMP +#define HAVE_SKB_INNER_NETWORK_HEADER + +#if (RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,0))) +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)) +#define HAVE_RHEL7_PCI_DRIVER_RH +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2)) +#define HAVE_RHEL7_PCI_RESET_NOTIFY +#endif /* RHEL >= 7.2 */ +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5)) +#define HAVE_GENEVE_RX_OFFLOAD +#endif /* RHEL < 7.5 */ +#define HAVE_ETHTOOL_FLOW_UNION_IP6_SPEC +#define HAVE_RHEL7_NET_DEVICE_OPS_EXT +#if !defined(HAVE_UDP_ENC_TUNNEL) && IS_ENABLED(CONFIG_GENEVE) +#define HAVE_UDP_ENC_TUNNEL +#endif /* !HAVE_UDP_ENC_TUNNEL && CONFIG_GENEVE */ +#endif /* RHEL >= 7.3 */ + +/* new hooks added to net_device_ops_extended in RHEL7.4 */ +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +#define HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SET_VF_VLAN +#define HAVE_RHEL7_NETDEV_OPS_EXT_NDO_UDP_TUNNEL +#define HAVE_UDP_ENC_RX_OFFLOAD +#endif /* RHEL >= 7.4 */ +#else /* RHEL >= 8.0 */ +#define NO_NETDEV_BPF_PROG_ATTACHED +#define HAVE_NDO_SELECT_QUEUE_SB_DEV +#endif /* RHEL >= 8.0 */ +#endif /* RHEL >= 7.0 */ +#endif /* >= 3.10.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) ) +#define netdev_notifier_info_to_dev(ptr) ptr +#ifndef time_in_range64 +#define time_in_range64(a, b, c) \ + (time_after_eq64(a, b) && \ + time_before_eq64(a, c)) +#endif /* time_in_range64 */ +#if ((RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,6)) ||\ + (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,4,0))) +#define HAVE_NDO_SET_VF_LINK_STATE +#endif +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) +#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK +#endif +#else /* >= 3.11.0 */ +#define HAVE_NDO_SET_VF_LINK_STATE +#define HAVE_SKB_INNER_PROTOCOL +#define HAVE_MPLS_FEATURES +#endif /* >= 3.11.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) ) +int __kc_pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, + enum pcie_link_width *width); +#ifndef pcie_get_minimum_link +#define pcie_get_minimum_link(_p, _s, _w) __kc_pcie_get_minimum_link(_p, _s, _w) +#endif + +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,7)) +int _kc_pci_wait_for_pending_transaction(struct pci_dev *dev); +#define pci_wait_for_pending_transaction _kc_pci_wait_for_pending_transaction +#endif /* = 3.12.0 */ +#if ( SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,0,0)) +#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK +#endif +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) ) +#define HAVE_VXLAN_RX_OFFLOAD +#if !defined(HAVE_UDP_ENC_TUNNEL) && IS_ENABLED(CONFIG_VXLAN) +#define HAVE_UDP_ENC_TUNNEL +#endif +#endif /* < 4.8.0 */ +#define HAVE_NDO_GET_PHYS_PORT_ID +#define HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK +#endif /* >= 3.12.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) ) +#define dma_set_mask_and_coherent(_p, _m) __kc_dma_set_mask_and_coherent(_p, _m) +int __kc_dma_set_mask_and_coherent(struct device *dev, u64 mask); +#ifndef u64_stats_init +#define u64_stats_init(a) do { } while(0) +#endif +#undef BIT_ULL +#define BIT_ULL(n) (1ULL << (n)) + +#if (!(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,0,0)) && \ + !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,0))) +static inline struct pci_dev *pci_upstream_bridge(struct pci_dev *dev) +{ + dev = pci_physfn(dev); + if (pci_is_root_bus(dev->bus)) + return NULL; + + return dev->bus->self; +} +#endif + +#if (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,1,0)) +#undef HAVE_STRUCT_PAGE_PFMEMALLOC +#define HAVE_DCBNL_OPS_SETAPP_RETURN_INT +#endif +#ifndef list_next_entry +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) +#endif +#ifndef list_prev_entry +#define list_prev_entry(pos, member) \ + list_entry((pos)->member.prev, typeof(*(pos)), member) +#endif + +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2))) +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member) +#endif + +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) +bool _kc_pci_device_is_present(struct pci_dev *pdev); +#define pci_device_is_present _kc_pci_device_is_present +#endif /* = 3.13.0 */ +#define HAVE_VXLAN_CHECKS +#if (UBUNTU_VERSION_CODE && UBUNTU_VERSION_CODE >= UBUNTU_VERSION(3,13,0,24)) +#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK +#else +#define HAVE_NDO_SELECT_QUEUE_ACCEL +#endif +#define HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS +#endif + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) ) + +#ifndef U16_MAX +#define U16_MAX ((u16)~0U) +#endif + +#ifndef U32_MAX +#define U32_MAX ((u32)~0U) +#endif + +#ifndef U64_MAX +#define U64_MAX ((u64)~0ULL) +#endif + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2))) +#define dev_consume_skb_any(x) dev_kfree_skb_any(x) +#define dev_consume_skb_irq(x) dev_kfree_skb_irq(x) +#endif + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,0)) && \ + !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,0,0))) + +/* it isn't expected that this would be a #define unless we made it so */ +#ifndef skb_set_hash + +#define PKT_HASH_TYPE_NONE 0 +#define PKT_HASH_TYPE_L2 1 +#define PKT_HASH_TYPE_L3 2 +#define PKT_HASH_TYPE_L4 3 + +enum _kc_pkt_hash_types { + _KC_PKT_HASH_TYPE_NONE = PKT_HASH_TYPE_NONE, + _KC_PKT_HASH_TYPE_L2 = PKT_HASH_TYPE_L2, + _KC_PKT_HASH_TYPE_L3 = PKT_HASH_TYPE_L3, + _KC_PKT_HASH_TYPE_L4 = PKT_HASH_TYPE_L4, +}; +#define pkt_hash_types _kc_pkt_hash_types + +#define skb_set_hash __kc_skb_set_hash +static inline void __kc_skb_set_hash(struct sk_buff __maybe_unused *skb, + u32 __maybe_unused hash, + int __maybe_unused type) +{ +#ifdef HAVE_SKB_L4_RXHASH + skb->l4_rxhash = (type == PKT_HASH_TYPE_L4); +#endif +#ifdef NETIF_F_RXHASH + skb->rxhash = hash; +#endif +} +#endif /* !skb_set_hash */ + +#else /* RHEL_RELEASE_CODE >= 7.0 || SLE_VERSION_CODE >= 12.0 */ + +#if ((RHEL_RELEASE_CODE && RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7,0)) ||\ + (SLE_VERSION_CODE && SLE_VERSION_CODE <= SLE_VERSION(12,1,0))) +/* GPLv2 code taken from 5.10-rc2 kernel source include/linux/pci.h, Copyright + * original authors. + */ +static inline int pci_enable_msix_exact(struct pci_dev *dev, + struct msix_entry *entries, int nvec) +{ + int rc = pci_enable_msix_range(dev, entries, nvec, nvec); + if (rc < 0) + return rc; + return 0; +} +#endif /* <=EL7.0 || <=SLES 12.1 */ +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))) +#ifndef HAVE_VXLAN_RX_OFFLOAD +#define HAVE_VXLAN_RX_OFFLOAD +#endif /* HAVE_VXLAN_RX_OFFLOAD */ +#endif + +#if !defined(HAVE_UDP_ENC_TUNNEL) && IS_ENABLED(CONFIG_VXLAN) +#define HAVE_UDP_ENC_TUNNEL +#endif + +#ifndef HAVE_VXLAN_CHECKS +#define HAVE_VXLAN_CHECKS +#endif /* HAVE_VXLAN_CHECKS */ +#endif /* !(RHEL_RELEASE_CODE >= 7.0 && SLE_VERSION_CODE >= 12.0) */ + +#if ((RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) ||\ + (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,0,0))) +#define HAVE_NDO_DFWD_OPS +#endif + +#ifndef pci_enable_msix_range +int __kc_pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, + int minvec, int maxvec); +#define pci_enable_msix_range __kc_pci_enable_msix_range +#endif + +#ifndef ether_addr_copy +#define ether_addr_copy __kc_ether_addr_copy +static inline void __kc_ether_addr_copy(u8 *dst, const u8 *src) +{ +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) + *(u32 *)dst = *(const u32 *)src; + *(u16 *)(dst + 4) = *(const u16 *)(src + 4); +#else + u16 *a = (u16 *)dst; + const u16 *b = (const u16 *)src; + + a[0] = b[0]; + a[1] = b[1]; + a[2] = b[2]; +#endif +} +#endif /* ether_addr_copy */ +int __kc_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, + int target, unsigned short *fragoff, int *flags); +#define ipv6_find_hdr(a, b, c, d, e) __kc_ipv6_find_hdr((a), (b), (c), (d), (e)) + +#ifndef OPTIMIZE_HIDE_VAR +#ifdef __GNUC__ +#define OPTIMIZER_HIDE_VAR(var) __asm__ ("" : "=r" (var) : "0" (var)) +#else +#include +#define OPTIMIZE_HIDE_VAR(var) barrier() +#endif +#endif + +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,0)) && \ + !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,4,0))) +static inline __u32 skb_get_hash_raw(const struct sk_buff *skb) +{ +#ifdef NETIF_F_RXHASH + return skb->rxhash; +#else + return 0; +#endif /* NETIF_F_RXHASH */ +} +#endif /* !RHEL > 5.9 && !SLES >= 10.4 */ + +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5)) +#define request_firmware_direct request_firmware +#endif /* !RHEL || RHEL < 7.5 */ + +#else /* >= 3.14.0 */ + +/* for ndo_dfwd_ ops add_station, del_station and _start_xmit */ +#ifndef HAVE_NDO_DFWD_OPS +#define HAVE_NDO_DFWD_OPS +#endif +#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK +#endif /* 3.14.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) ) +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) +#define HAVE_SKBUFF_RXHASH +#endif /* >= 2.6.35 */ +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,1)) && \ + !(UBUNTU_VERSION_CODE && UBUNTU_VERSION_CODE >= UBUNTU_VERSION(3,13,0,30))) +#define u64_stats_fetch_begin_irq u64_stats_fetch_begin_bh +#define u64_stats_fetch_retry_irq u64_stats_fetch_retry_bh +#endif + +#else /* >= 3.15.0 */ +#define HAVE_NET_GET_RANDOM_ONCE +#define HAVE_PTP_1588_CLOCK_PINS +#define HAVE_NETDEV_PORT +#endif /* 3.15.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0) ) +#ifndef smp_mb__before_atomic +#define smp_mb__before_atomic() smp_mb() +#define smp_mb__after_atomic() smp_mb() +#endif +#ifndef __dev_uc_sync +#ifdef HAVE_SET_RX_MODE +#ifdef NETDEV_HW_ADDR_T_UNICAST +int __kc_hw_addr_sync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*sync)(struct net_device *, const unsigned char *), + int (*unsync)(struct net_device *, const unsigned char *)); +void __kc_hw_addr_unsync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*unsync)(struct net_device *, const unsigned char *)); +#endif +#ifndef NETDEV_HW_ADDR_T_MULTICAST +int __kc_dev_addr_sync_dev(struct dev_addr_list **list, int *count, + struct net_device *dev, + int (*sync)(struct net_device *, const unsigned char *), + int (*unsync)(struct net_device *, const unsigned char *)); +void __kc_dev_addr_unsync_dev(struct dev_addr_list **list, int *count, + struct net_device *dev, + int (*unsync)(struct net_device *, const unsigned char *)); +#endif +#endif /* HAVE_SET_RX_MODE */ + +static inline int __kc_dev_uc_sync(struct net_device __maybe_unused *dev, + int __maybe_unused (*sync)(struct net_device *, const unsigned char *), + int __maybe_unused (*unsync)(struct net_device *, const unsigned char *)) +{ +#ifdef NETDEV_HW_ADDR_T_UNICAST + return __kc_hw_addr_sync_dev(&dev->uc, dev, sync, unsync); +#elif defined(HAVE_SET_RX_MODE) + return __kc_dev_addr_sync_dev(&dev->uc_list, &dev->uc_count, + dev, sync, unsync); +#else + return 0; +#endif +} +#define __dev_uc_sync __kc_dev_uc_sync + +static inline void __kc_dev_uc_unsync(struct net_device __maybe_unused *dev, + int __maybe_unused (*unsync)(struct net_device *, const unsigned char *)) +{ +#ifdef HAVE_SET_RX_MODE +#ifdef NETDEV_HW_ADDR_T_UNICAST + __kc_hw_addr_unsync_dev(&dev->uc, dev, unsync); +#else /* NETDEV_HW_ADDR_T_MULTICAST */ + __kc_dev_addr_unsync_dev(&dev->uc_list, &dev->uc_count, dev, unsync); +#endif /* NETDEV_HW_ADDR_T_UNICAST */ +#endif /* HAVE_SET_RX_MODE */ +} +#define __dev_uc_unsync __kc_dev_uc_unsync + +static inline int __kc_dev_mc_sync(struct net_device __maybe_unused *dev, + int __maybe_unused (*sync)(struct net_device *, const unsigned char *), + int __maybe_unused (*unsync)(struct net_device *, const unsigned char *)) +{ +#ifdef NETDEV_HW_ADDR_T_MULTICAST + return __kc_hw_addr_sync_dev(&dev->mc, dev, sync, unsync); +#elif defined(HAVE_SET_RX_MODE) + return __kc_dev_addr_sync_dev(&dev->mc_list, &dev->mc_count, + dev, sync, unsync); +#else + return 0; +#endif + +} +#define __dev_mc_sync __kc_dev_mc_sync + +static inline void __kc_dev_mc_unsync(struct net_device __maybe_unused *dev, + int __maybe_unused (*unsync)(struct net_device *, const unsigned char *)) +{ +#ifdef HAVE_SET_RX_MODE +#ifdef NETDEV_HW_ADDR_T_MULTICAST + __kc_hw_addr_unsync_dev(&dev->mc, dev, unsync); +#else /* NETDEV_HW_ADDR_T_MULTICAST */ + __kc_dev_addr_unsync_dev(&dev->mc_list, &dev->mc_count, dev, unsync); +#endif /* NETDEV_HW_ADDR_T_MULTICAST */ +#endif /* HAVE_SET_RX_MODE */ +} +#define __dev_mc_unsync __kc_dev_mc_unsync +#endif /* __dev_uc_sync */ + +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,1)) +#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE +#endif + +#ifndef NETIF_F_GSO_UDP_TUNNEL_CSUM +/* if someone backports this, hopefully they backport as a #define. + * declare it as zero on older kernels so that if it get's or'd in + * it won't effect anything, therefore preventing core driver changes + */ +#define NETIF_F_GSO_UDP_TUNNEL_CSUM 0 +#define SKB_GSO_UDP_TUNNEL_CSUM 0 +#endif +#else +#if ( ( LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0) ) && \ + ! ( SLE_VERSION_CODE && ( SLE_VERSION_CODE >= SLE_VERSION(12,4,0)) ) ) +#define HAVE_PCI_ERROR_HANDLER_RESET_NOTIFY +#endif /* >= 3.16.0 && < 4.13.0 && !(SLES >= 12sp4) */ +#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE +#endif /* 3.16.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) ) +#if !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,8) && \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) && \ + !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2)) +#ifndef timespec64 +#define timespec64 timespec +static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) +{ + return ts; +} +static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) +{ + return ts64; +} +#define timespec64_equal timespec_equal +#define timespec64_compare timespec_compare +#define set_normalized_timespec64 set_normalized_timespec +#define timespec64_add_safe timespec_add_safe +#define timespec64_add timespec_add +#define timespec64_sub timespec_sub +#define timespec64_valid timespec_valid +#define timespec64_valid_strict timespec_valid_strict +#define timespec64_to_ns timespec_to_ns +#define ns_to_timespec64 ns_to_timespec +#define ktime_to_timespec64 ktime_to_timespec +#define ktime_get_ts64 ktime_get_ts +#define ktime_get_real_ts64 ktime_get_real_ts +#define timespec64_add_ns timespec_add_ns +#endif /* timespec64 */ +#endif /* !(RHEL6.8= RHEL_RELEASE_VERSION(6,8) && \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) +static inline void ktime_get_real_ts64(struct timespec64 *ts) +{ + *ts = ktime_to_timespec64(ktime_get_real()); +} + +static inline void ktime_get_ts64(struct timespec64 *ts) +{ + *ts = ktime_to_timespec64(ktime_get()); +} +#endif + +#if !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +#define hlist_add_behind(_a, _b) hlist_add_after(_b, _a) +#endif + +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5)) +#endif /* RHEL_RELEASE_CODE < RHEL7.5 */ + +#if RHEL_RELEASE_CODE && \ + RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,3) && \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) +static inline u64 ktime_get_ns(void) +{ + return ktime_to_ns(ktime_get()); +} + +static inline u64 ktime_get_real_ns(void) +{ + return ktime_to_ns(ktime_get_real()); +} + +static inline u64 ktime_get_boot_ns(void) +{ + return ktime_to_ns(ktime_get_boottime()); +} +#endif /* RHEL < 7.3 */ + +#else +#define HAVE_DCBNL_OPS_SETAPP_RETURN_INT +#include +#define HAVE_RHASHTABLE +#endif /* 3.17.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) ) +#ifndef NO_PTP_SUPPORT +#include +struct sk_buff *__kc_skb_clone_sk(struct sk_buff *skb); +void __kc_skb_complete_tx_timestamp(struct sk_buff *skb, + struct skb_shared_hwtstamps *hwtstamps); +#define skb_clone_sk __kc_skb_clone_sk +#define skb_complete_tx_timestamp __kc_skb_complete_tx_timestamp +#endif +#ifndef ETH_P_XDSA +#define ETH_P_XDSA 0x00F8 +#endif +/* RHEL 7.1 backported csum_level, but SLES 12 and 12-SP1 did not */ +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,1)) +#define HAVE_SKBUFF_CSUM_LEVEL +#endif /* >= RH 7.1 */ + +/* RHEL 7.3 backported xmit_more */ +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) +#define HAVE_SKB_XMIT_MORE +#endif /* >= RH 7.3 */ + +#undef GENMASK +#define GENMASK(h, l) \ + (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) +#undef GENMASK_ULL +#define GENMASK_ULL(h, l) \ + (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + +#else /* 3.18.0 */ +#define HAVE_SKBUFF_CSUM_LEVEL +#define HAVE_SKB_XMIT_MORE +#define HAVE_SKB_INNER_PROTOCOL_TYPE +#endif /* 3.18.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,18,4) ) +#else +#define HAVE_NDO_FEATURES_CHECK +#endif /* 3.18.4 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,18,13) ) +#ifndef WRITE_ONCE +#define WRITE_ONCE(x, val) ({ ACCESS_ONCE(x) = (val); }) +#endif +#endif /* 3.18.13 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) ) +/* netdev_phys_port_id renamed to netdev_phys_item_id */ +#define netdev_phys_item_id netdev_phys_port_id + +static inline void _kc_napi_complete_done(struct napi_struct *napi, + int __always_unused work_done) { + napi_complete(napi); +} +/* don't use our backport if the distro kernels already have it */ +#if (SLE_VERSION_CODE && (SLE_VERSION_CODE < SLE_VERSION(12,3,0))) || \ + (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5))) +#define napi_complete_done _kc_napi_complete_done +#endif + +int _kc_bitmap_print_to_pagebuf(bool list, char *buf, + const unsigned long *maskp, int nmaskbits); +#define bitmap_print_to_pagebuf _kc_bitmap_print_to_pagebuf + +#ifndef NETDEV_RSS_KEY_LEN +#define NETDEV_RSS_KEY_LEN (13 * 4) +#endif +#if (!(RHEL_RELEASE_CODE && \ + ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,7) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) || \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2))))) +#define netdev_rss_key_fill(buffer, len) __kc_netdev_rss_key_fill(buffer, len) +#endif /* RHEL_RELEASE_CODE */ +void __kc_netdev_rss_key_fill(void *buffer, size_t len); +#define SPEED_20000 20000 +#define SPEED_40000 40000 +#ifndef dma_rmb +#define dma_rmb() rmb() +#endif +#ifndef dev_alloc_pages +#ifndef NUMA_NO_NODE +#define NUMA_NO_NODE -1 +#endif +#define dev_alloc_pages(_order) alloc_pages_node(NUMA_NO_NODE, (GFP_ATOMIC | __GFP_COLD | __GFP_COMP | __GFP_MEMALLOC), (_order)) +#endif +#ifndef dev_alloc_page +#define dev_alloc_page() dev_alloc_pages(0) +#endif +#if !defined(eth_skb_pad) && !defined(skb_put_padto) +/** + * __kc_skb_put_padto - increase size and pad an skbuff up to a minimal size + * @skb: buffer to pad + * @len: minimal length + * + * Pads up a buffer to ensure the trailing bytes exist and are + * blanked. If the buffer already contains sufficient data it + * is untouched. Otherwise it is extended. Returns zero on + * success. The skb is freed on error. + */ +static inline int __kc_skb_put_padto(struct sk_buff *skb, unsigned int len) +{ + unsigned int size = skb->len; + + if (unlikely(size < len)) { + len -= size; + if (skb_pad(skb, len)) + return -ENOMEM; + __skb_put(skb, len); + } + return 0; +} +#define skb_put_padto(skb, len) __kc_skb_put_padto(skb, len) + +static inline int __kc_eth_skb_pad(struct sk_buff *skb) +{ + return __kc_skb_put_padto(skb, ETH_ZLEN); +} +#define eth_skb_pad(skb) __kc_eth_skb_pad(skb) +#endif /* eth_skb_pad && skb_put_padto */ + +#ifndef SKB_ALLOC_NAPI +/* RHEL 7.2 backported napi_alloc_skb and friends */ +static inline struct sk_buff *__kc_napi_alloc_skb(struct napi_struct *napi, unsigned int length) +{ + return netdev_alloc_skb_ip_align(napi->dev, length); +} +#define napi_alloc_skb(napi,len) __kc_napi_alloc_skb(napi,len) +#define __napi_alloc_skb(napi,len,mask) __kc_napi_alloc_skb(napi,len) +#endif /* SKB_ALLOC_NAPI */ +#define HAVE_CONFIG_PM_RUNTIME +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,7)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))) +#define HAVE_RXFH_HASHFUNC +#endif /* 6.7 < RHEL < 7.0 */ +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,1)) +#define HAVE_RXFH_HASHFUNC +#define NDO_DFLT_BRIDGE_GETLINK_HAS_BRFLAGS +#endif /* RHEL > 7.1 */ +#ifndef napi_schedule_irqoff +#define napi_schedule_irqoff napi_schedule +#endif +#ifndef READ_ONCE +#define READ_ONCE(_x) ACCESS_ONCE(_x) +#endif +#ifndef ETH_MODULE_SFF_8636 +#define ETH_MODULE_SFF_8636 0x3 +#endif +#ifndef ETH_MODULE_SFF_8636_LEN +#define ETH_MODULE_SFF_8636_LEN 256 +#endif +#ifndef ETH_MODULE_SFF_8436 +#define ETH_MODULE_SFF_8436 0x4 +#endif +#ifndef ETH_MODULE_SFF_8436_LEN +#define ETH_MODULE_SFF_8436_LEN 256 +#endif +#ifndef writel_relaxed +#define writel_relaxed writel +#endif +#else /* 3.19.0 */ +#define HAVE_RXFH_HASHFUNC +#define NDO_DFLT_BRIDGE_GETLINK_HAS_BRFLAGS +#endif /* 3.19.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,20,0) ) +/* vlan_tx_xx functions got renamed to skb_vlan */ +#ifndef skb_vlan_tag_get +#define skb_vlan_tag_get vlan_tx_tag_get +#endif +#ifndef skb_vlan_tag_present +#define skb_vlan_tag_present vlan_tx_tag_present +#endif +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,1)) +#define HAVE_INCLUDE_LINUX_TIMECOUNTER_H +#endif +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) +#define HAVE_NDO_BRIDGE_SET_DEL_LINK_FLAGS +#endif +#else +#define HAVE_INCLUDE_LINUX_TIMECOUNTER_H +#define HAVE_NDO_BRIDGE_SET_DEL_LINK_FLAGS +#endif /* 3.20.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) +/* Definition for CONFIG_OF was introduced earlier */ +#if !defined(CONFIG_OF) && \ + !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) +static inline struct device_node * +pci_device_to_OF_node(const struct pci_dev __always_unused *pdev) { return NULL; } +#else /* !CONFIG_OF && RHEL < 7.3 */ +#define HAVE_DDP_PROFILE_UPLOAD_SUPPORT +#endif /* !CONFIG_OF && RHEL < 7.3 */ +#else /* < 4.0 */ +#define HAVE_DDP_PROFILE_UPLOAD_SUPPORT +#endif /* < 4.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0) ) +#ifndef NO_PTP_SUPPORT +#ifdef HAVE_INCLUDE_LINUX_TIMECOUNTER_H +#include +#else +#include +#endif +static inline void __kc_timecounter_adjtime(struct timecounter *tc, s64 delta) +{ + tc->nsec += delta; +} + +static inline struct net_device * +of_find_net_device_by_node(struct device_node __always_unused *np) +{ + return NULL; +} + +#define timecounter_adjtime __kc_timecounter_adjtime +#endif +#if ((RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2))) || \ + (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,2,0)))) +#define HAVE_NDO_SET_VF_RSS_QUERY_EN +#endif +#if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) +#define HAVE_NDO_BRIDGE_GETLINK_NLFLAGS +#define HAVE_RHEL7_EXTENDED_NDO_SET_TX_MAXRATE +#define HAVE_NDO_SET_TX_MAXRATE +#endif +#if !((RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,8) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) && \ + (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) && \ + (SLE_VERSION_CODE > SLE_VERSION(12,1,0))) +unsigned int _kc_cpumask_local_spread(unsigned int i, int node); +#define cpumask_local_spread _kc_cpumask_local_spread +#endif +#ifdef HAVE_RHASHTABLE +#define rhashtable_loopup_fast(ht, key, params) \ + do { \ + (void)params; \ + rhashtable_lookup((ht), (key)); \ + } while (0) + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) ) +#define rhashtable_insert_fast(ht, obj, params) \ + do { \ + (void)params; \ + rhashtable_insert((ht), (obj), GFP_KERNEL); \ + } while (0) + +#define rhashtable_remove_fast(ht, obj, params) \ + do { \ + (void)params; \ + rhashtable_remove((ht), (obj), GFP_KERNEL); \ + } while (0) + +#else /* >= 3,19,0 */ +#define rhashtable_insert_fast(ht, obj, params) \ + do { \ + (void)params; \ + rhashtable_insert((ht), (obj)); \ + } while (0) + +#define rhashtable_remove_fast(ht, obj, params) \ + do { \ + (void)params; \ + rhashtable_remove((ht), (obj)); \ + } while (0) + +#endif /* 3,19,0 */ +#endif /* HAVE_RHASHTABLE */ +#else /* >= 4,1,0 */ +#define HAVE_NDO_GET_PHYS_PORT_NAME +#define HAVE_NDO_BRIDGE_GETLINK_NLFLAGS +#define HAVE_PASSTHRU_FEATURES_CHECK +#define HAVE_NDO_SET_VF_RSS_QUERY_EN +#define HAVE_NDO_SET_TX_MAXRATE +#endif /* 4,1,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,1,9)) +#if (!(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) && \ + !((SLE_VERSION_CODE == SLE_VERSION(11,3,0)) && \ + (SLE_LOCALVERSION_CODE >= SLE_LOCALVERSION(0,47,71))) && \ + !((SLE_VERSION_CODE == SLE_VERSION(11,4,0)) && \ + (SLE_LOCALVERSION_CODE >= SLE_LOCALVERSION(65,0,0))) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(12,1,0))) +static inline bool page_is_pfmemalloc(struct page __maybe_unused *page) +{ +#ifdef HAVE_STRUCT_PAGE_PFMEMALLOC + return page->pfmemalloc; +#else + return false; +#endif +} +#endif /* !RHEL7.2+ && !SLES11sp3(3.0.101-0.47.71+ update) && !SLES11sp4(3.0.101-65+ update) & !SLES12sp1+ */ +#else +#undef HAVE_STRUCT_PAGE_PFMEMALLOC +#endif /* 4.1.9 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)) +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(12,1,0))) +#define ETHTOOL_RX_FLOW_SPEC_RING 0x00000000FFFFFFFFULL +#define ETHTOOL_RX_FLOW_SPEC_RING_VF 0x000000FF00000000ULL +#define ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF 32 +static inline __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie) +{ + return ETHTOOL_RX_FLOW_SPEC_RING & ring_cookie; +}; + +static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie) +{ + return (ETHTOOL_RX_FLOW_SPEC_RING_VF & ring_cookie) >> + ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF; +}; +#endif /* ! RHEL >= 7.2 && ! SLES >= 12.1 */ +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +#define HAVE_NDO_DFLT_BRIDGE_GETLINK_VLAN_SUPPORT +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)) +#if (!((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,8) && \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)) || \ + RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2))) +static inline bool pci_ari_enabled(struct pci_bus *bus) +{ + return bus->self && bus->self->ari_enabled; +} +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2)) +#define HAVE_VF_STATS +#endif /* (RHEL7.2+) */ +#endif /* !(RHEL6.8+ || RHEL7.2+) */ +#else +static inline bool pci_ari_enabled(struct pci_bus *bus) +{ + return false; +} +#endif /* 2.6.27 */ +#else +#define HAVE_NDO_DFLT_BRIDGE_GETLINK_VLAN_SUPPORT +#define HAVE_VF_STATS +#endif /* 4.2.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)) +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(12,2,0))) +/** + * _kc_flow_dissector_key_ipv4_addrs: + * @src: source ip address + * @dst: destination ip address + */ +struct _kc_flow_dissector_key_ipv4_addrs { + __be32 src; + __be32 dst; +}; + +/** + * _kc_flow_dissector_key_ipv6_addrs: + * @src: source ip address + * @dst: destination ip address + */ +struct _kc_flow_dissector_key_ipv6_addrs { + struct in6_addr src; + struct in6_addr dst; +}; + +/** + * _kc_flow_dissector_key_addrs: + * @v4addrs: IPv4 addresses + * @v6addrs: IPv6 addresses + */ +struct _kc_flow_dissector_key_addrs { + union { + struct _kc_flow_dissector_key_ipv4_addrs v4addrs; + struct _kc_flow_dissector_key_ipv6_addrs v6addrs; + }; +}; + +/** + * _kc_flow_dissector_key_tp_ports: + * @ports: port numbers of Transport header + * src: source port number + * dst: destination port number + */ +struct _kc_flow_dissector_key_ports { + union { + __be32 ports; + struct { + __be16 src; + __be16 dst; + }; + }; +}; + +/** + * _kc_flow_dissector_key_basic: + * @n_proto: Network header protocol (eg. IPv4/IPv6) + * @ip_proto: Transport header protocol (eg. TCP/UDP) + * @padding: padding for alignment + */ +struct _kc_flow_dissector_key_basic { + __be16 n_proto; + u8 ip_proto; + u8 padding; +}; + +struct _kc_flow_keys { + struct _kc_flow_dissector_key_basic basic; + struct _kc_flow_dissector_key_ports ports; + struct _kc_flow_dissector_key_addrs addrs; +}; + +/* These are all the include files for kernels inside this #ifdef block that + * have any reference to the in kernel definition of struct flow_keys. The + * reason for putting them here is to make 100% sure that these files do not get + * included after re-defining flow_keys to _kc_flow_keys. This is done to + * prevent any possible ABI issues that this structure re-definition could case. + */ +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)) || \ + RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,7) || \ + SLE_VERSION_CODE >= SLE_VERSION(11,4,0)) +#include +#endif /* (>= 3.3.0 && < 4.2.0) || >= RHEL 6.7 || >= SLE 11.4 */ +#if (LINUX_VERSION_CODE == KERNEL_VERSION(4,2,0)) +#include +#endif /* 4.2.0 */ +#include +#include +#include +#include + +#define flow_keys _kc_flow_keys +bool +_kc_skb_flow_dissect_flow_keys(const struct sk_buff *skb, + struct flow_keys *flow, + unsigned int __always_unused flags); +#define skb_flow_dissect_flow_keys _kc_skb_flow_dissect_flow_keys +#endif /* ! >= RHEL 7.4 && ! >= SLES 12.2 */ + +#if ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) || \ + (SLE_VERSION_CODE >= SLE_VERSION(12,2,0))) +#include +#endif /* >= RHEL7.3 || >= SLE12sp2 */ +#else /* >= 4.3.0 */ +#include +#endif /* 4.3.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)) +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) +#define HAVE_NDO_SET_VF_TRUST +#endif /* (RHEL_RELEASE >= 7.3) */ +#ifndef CONFIG_64BIT +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +#include /* 32-bit readq/writeq */ +#else /* 3.3.0 => 4.3.x */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) +#include +#endif /* 2.6.26 => 3.3.0 */ +#ifndef readq +static inline __u64 readq(const volatile void __iomem *addr) +{ + const volatile u32 __iomem *p = addr; + u32 low, high; + + low = readl(p); + high = readl(p + 1); + + return low + ((u64)high << 32); +} +#define readq readq +#endif + +#ifndef writeq +static inline void writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val >> 32, (u8 *)addr + 4); +} +#define writeq writeq +#endif +#endif /* < 3.3.0 */ +#endif /* !CONFIG_64BIT */ +#else /* < 4.4.0 */ +#define HAVE_NDO_SET_VF_TRUST + +#ifndef CONFIG_64BIT +#include /* 32-bit readq/writeq */ +#endif /* !CONFIG_64BIT */ +#endif /* 4.4.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)) +/* protect against a likely backport */ +#ifndef NETIF_F_CSUM_MASK +#define NETIF_F_CSUM_MASK NETIF_F_ALL_CSUM +#endif /* NETIF_F_CSUM_MASK */ +#ifndef NETIF_F_SCTP_CRC +#define NETIF_F_SCTP_CRC NETIF_F_SCTP_CSUM +#endif /* NETIF_F_SCTP_CRC */ +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3))) +#define eth_platform_get_mac_address _kc_eth_platform_get_mac_address +int _kc_eth_platform_get_mac_address(struct device *dev __maybe_unused, + u8 *mac_addr __maybe_unused); +#endif /* !(RHEL_RELEASE >= 7.3) */ +#else /* 4.5.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) ) +#define HAVE_GENEVE_RX_OFFLOAD +#if !defined(HAVE_UDP_ENC_TUNNEL) && IS_ENABLED(CONFIG_GENEVE) +#define HAVE_UDP_ENC_TUNNEL +#endif +#endif /* < 4.8.0 */ +#define HAVE_NETIF_NAPI_ADD_CALLS_NAPI_HASH_ADD +#define HAVE_NETDEV_UPPER_INFO +#endif /* 4.5.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) +#if !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,3)) +static inline unsigned char *skb_checksum_start(const struct sk_buff *skb) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) + return skb->head + skb->csum_start; +#else /* < 2.6.22 */ + return skb_transport_header(skb); +#endif +} +#endif + +#if !(UBUNTU_VERSION_CODE && \ + UBUNTU_VERSION_CODE >= UBUNTU_VERSION(4,4,0,21)) && \ + !(RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2))) && \ + !(SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) +static inline void napi_consume_skb(struct sk_buff *skb, + int __always_unused budget) +{ + dev_consume_skb_any(skb); +} + +#endif /* UBUNTU 4,4,0,21, RHEL 7.2, SLES12 SP3 */ +#if !(SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) && \ + !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff) +{ + * sum = csum_fold(csum_add(diff, ~csum_unfold(*sum))); +} +#endif +#if !(RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2))) && \ + !(SLE_VERSION_CODE && (SLE_VERSION_CODE > SLE_VERSION(12,3,0))) +static inline void page_ref_inc(struct page *page) +{ + get_page(page); +} +#else +#define HAVE_PAGE_COUNT_BULK_UPDATE +#endif +#ifndef IPV4_USER_FLOW +#define IPV4_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ +#endif + +#if ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,7)) || \ + (SLE_VERSION_CODE >= SLE_VERSION(12,2,0))) +#define HAVE_TC_SETUP_CLSU32 +#endif + +#ifndef kstrtobool +#define kstrtobool _kc_kstrtobool +int _kc_kstrtobool(const char *s, bool *res); +#endif + +#else /* >= 4.6.0 */ +#define HAVE_PAGE_COUNT_BULK_UPDATE +#define HAVE_ETHTOOL_FLOW_UNION_IP6_SPEC +#define HAVE_TC_SETUP_CLSU32 +#endif /* 4.6.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) +#if ((SLE_VERSION_CODE >= SLE_VERSION(12,3,0)) ||\ + (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4))) +#define HAVE_NETIF_TRANS_UPDATE +#endif /* SLES12sp3+ || RHEL7.4+ */ +#if ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) ||\ + (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) +#define HAVE_ETHTOOL_25G_BITS +#define HAVE_ETHTOOL_50G_BITS +#define HAVE_ETHTOOL_100G_BITS +#endif /* RHEL7.3+ || SLES12sp3+ */ +#else /* 4.7.0 */ +#define HAVE_NETIF_TRANS_UPDATE +#define HAVE_ETHTOOL_CONVERT_U32_AND_LINK_MODE +#define HAVE_ETHTOOL_25G_BITS +#define HAVE_ETHTOOL_50G_BITS +#define HAVE_ETHTOOL_100G_BITS +#endif /* 4.7.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)) +#if !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +enum udp_parsable_tunnel_type { + UDP_TUNNEL_TYPE_VXLAN, + UDP_TUNNEL_TYPE_GENEVE, +}; +struct udp_tunnel_info { + unsigned short type; + sa_family_t sa_family; + __be16 port; +}; +#endif + +#if (UBUNTU_VERSION_CODE && UBUNTU_VERSION_CODE < UBUNTU_VERSION(4,8,0,0)) +#define tc_no_actions(_exts) true +#define tc_for_each_action(_a, _exts) while (0) +#endif +#if !(SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) &&\ + !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +static inline int +#ifdef HAVE_NON_CONST_PCI_DRIVER_NAME +pci_request_io_regions(struct pci_dev *pdev, char *name) +#else +pci_request_io_regions(struct pci_dev *pdev, const char *name) +#endif +{ + return pci_request_selected_regions(pdev, + pci_select_bars(pdev, IORESOURCE_IO), name); +} + +static inline void +pci_release_io_regions(struct pci_dev *pdev) +{ + return pci_release_selected_regions(pdev, + pci_select_bars(pdev, IORESOURCE_IO)); +} + +static inline int +#ifdef HAVE_NON_CONST_PCI_DRIVER_NAME +pci_request_mem_regions(struct pci_dev *pdev, char *name) +#else +pci_request_mem_regions(struct pci_dev *pdev, const char *name) +#endif +{ + return pci_request_selected_regions(pdev, + pci_select_bars(pdev, IORESOURCE_MEM), name); +} + +static inline void +pci_release_mem_regions(struct pci_dev *pdev) +{ + return pci_release_selected_regions(pdev, + pci_select_bars(pdev, IORESOURCE_MEM)); +} +#endif /* !SLE_VERSION(12,3,0) */ +#if ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) ||\ + (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) +#define HAVE_ETHTOOL_NEW_50G_BITS +#endif /* RHEL7.4+ || SLES12sp3+ */ +#else +#define HAVE_UDP_ENC_RX_OFFLOAD +#define HAVE_ETHTOOL_NEW_50G_BITS +#endif /* 4.8.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +#define HAVE_ETHTOOL_NEW_1G_BITS +#define HAVE_ETHTOOL_NEW_10G_BITS +#endif /* RHEL7.4+ */ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,4)) +static inline void bitmap_from_u64(unsigned long *dst, u64 mask) +{ + dst[0] = mask & ULONG_MAX; + + if (sizeof(mask) > sizeof(unsigned long)) + dst[1] = mask >> 32; +} +#endif /* =4.9 */ +#define HAVE_FLOW_DISSECTOR_KEY_VLAN_PRIO +#define HAVE_ETHTOOL_NEW_1G_BITS +#define HAVE_ETHTOOL_NEW_10G_BITS +#endif /* KERNEL_VERSION(4.9.0) */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)) +/* SLES 12.3 and RHEL 7.5 backported this interface */ +#if (!SLE_VERSION_CODE && !RHEL_RELEASE_CODE) || \ + (SLE_VERSION_CODE && (SLE_VERSION_CODE < SLE_VERSION(12,3,0))) || \ + (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5))) +static inline bool _kc_napi_complete_done2(struct napi_struct *napi, + int __always_unused work_done) +{ + /* it was really hard to get napi_complete_done to be safe to call + * recursively without running into our own kcompat, so just use + * napi_complete + */ + napi_complete(napi); + + /* true means that the stack is telling the driver to go-ahead and + * re-enable interrupts + */ + return true; +} + +#ifdef napi_complete_done +#undef napi_complete_done +#endif +#define napi_complete_done _kc_napi_complete_done2 +#endif /* sles and rhel exclusion for < 4.10 */ +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4)) +#define HAVE_DEV_WALK_API +#define HAVE_ETHTOOL_NEW_2500MB_BITS +#define HAVE_ETHTOOL_5G_BITS +#endif /* RHEL7.4+ */ +#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) +#define HAVE_NETDEVICE_MIN_MAX_MTU +#endif /* (SLES >= 12.3.0) */ +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))) +#define HAVE_RHEL7_EXTENDED_MIN_MAX_MTU +#define HAVE_NETDEVICE_MIN_MAX_MTU +#endif +#if ((SLE_VERSION_CODE && (SLE_VERSION_CODE > SLE_VERSION(12,3,0))) ||\ + (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))) +#define HAVE_SWIOTLB_SKIP_CPU_SYNC +#endif + +#if ((SLE_VERSION_CODE && (SLE_VERSION_CODE < SLE_VERSION(15,0,0))) ||\ + (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7,4)))) +#define page_frag_free __free_page_frag +#endif +#ifndef ETH_MIN_MTU +#define ETH_MIN_MTU 68 +#endif /* ETH_MIN_MTU */ + +/* If kernel is older than 4.10 but distro is RHEL >= 7.5 || SLES > 12SP4, + * it does have support for NAPI_STATE + */ +#if ((RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))) ||\ + (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,4,0)))) +#define HAVE_NAPI_STATE_IN_BUSY_POLL +#endif /* RHEL >= 7.5 || SLES >=12.4 */ +#else /* >= 4.10 */ +#define HAVE_NETDEVICE_MIN_MAX_MTU +#define HAVE_SWIOTLB_SKIP_CPU_SYNC +#define HAVE_NETDEV_TC_RESETS_XPS +#define HAVE_XPS_QOS_SUPPORT +#define HAVE_DEV_WALK_API +#define HAVE_ETHTOOL_NEW_2500MB_BITS +#define HAVE_ETHTOOL_5G_BITS +/* kernel 4.10 onwards, as part of busy_poll rewrite, new state were added + * which is part of NAPI:state. If NAPI:state=NAPI_STATE_IN_BUSY_POLL, + * it means napi_poll is invoked in busy_poll context + */ +#define HAVE_NAPI_STATE_IN_BUSY_POLL +#endif /* 4.10.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)) +#ifdef CONFIG_NET_RX_BUSY_POLL +#define HAVE_NDO_BUSY_POLL +#endif /* CONFIG_NET_RX_BUSY_POLL */ +#if ((SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) || \ + (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5)))) +#define HAVE_VOID_NDO_GET_STATS64 +#endif /* (SLES >= 12.3.0) && (RHEL >= 7.5) */ + +static inline void _kc_dev_kfree_skb_irq(struct sk_buff *skb) +{ + if (!skb) + return; + dev_kfree_skb_irq(skb); +} + +#undef dev_kfree_skb_irq +#define dev_kfree_skb_irq _kc_dev_kfree_skb_irq + +static inline void _kc_dev_consume_skb_irq(struct sk_buff *skb) +{ + if (!skb) + return; + dev_consume_skb_irq(skb); +} + +#undef dev_consume_skb_irq +#define dev_consume_skb_irq _kc_dev_consume_skb_irq + +static inline void _kc_dev_kfree_skb_any(struct sk_buff *skb) +{ + if (!skb) + return; + dev_kfree_skb_any(skb); +} + +#undef dev_kfree_skb_any +#define dev_kfree_skb_any _kc_dev_kfree_skb_any + +static inline void _kc_dev_consume_skb_any(struct sk_buff *skb) +{ + if (!skb) + return; + dev_consume_skb_any(skb); +} + +#undef dev_consume_skb_any +#define dev_consume_skb_any _kc_dev_consume_skb_any + +#else /* > 4.11 */ +#define HAVE_VOID_NDO_GET_STATS64 +#define HAVE_VM_OPS_FAULT_NO_VMA +#endif /* 4.11.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)) +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,7) && \ + RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)) +/* The RHEL 7.7+ NL_SET_ERR_MSG_MOD triggers unused parameter warnings */ +#undef NL_SET_ERR_MSG_MOD +#endif +/* If kernel is older than 4.12 but distro is RHEL >= 7.5 || SLES > 12SP4, + * it does have support for MIN_NAPI_ID + */ +#if ((RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))) || \ + (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,4,0)))) +#define HAVE_MIN_NAPI_ID +#endif /* RHEL >= 7.5 || SLES >= 12.4 */ +#ifndef NL_SET_ERR_MSG_MOD +#define NL_SET_ERR_MSG_MOD(extack, msg) \ + do { \ + uninitialized_var(extack); \ + pr_err(KBUILD_MODNAME ": " msg); \ + } while (0) +#endif /* !NL_SET_ERR_MSG_MOD */ +#else /* >= 4.12 */ +#define HAVE_MIN_NAPI_ID +#endif /* 4.12 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)) +#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit 2 */ +#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,4,0))) +#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE +#endif /* SLES >= 12sp4 */ +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(12,4,0))) +#define UUID_SIZE 16 +typedef struct { + __u8 b[UUID_SIZE]; +} uuid_t; + +#ifndef UUID_INIT +#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ +((uuid_t) \ +{{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, \ + ((b) >> 8) & 0xff, (b) & 0xff, \ + ((c) >> 8) & 0xff, (c) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) +#endif + +static inline bool uuid_equal(const uuid_t *u1, const uuid_t *u2) +{ + return memcmp(u1, u2, sizeof(uuid_t)) == 0; +} +#else +#define HAVE_METADATA_PORT_INFO +#endif /* !(RHEL >= 7.5) && !(SLES >= 12.4) */ +#else /* > 4.13 */ +#define HAVE_METADATA_PORT_INFO +#define HAVE_HWTSTAMP_FILTER_NTP_ALL +#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE +#endif /* 4.13.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)) +#ifdef ETHTOOL_GLINKSETTINGS +#ifndef ethtool_link_ksettings_del_link_mode +#define ethtool_link_ksettings_del_link_mode(ptr, name, mode) \ + __clear_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name) +#endif +#endif /* ETHTOOL_GLINKSETTINGS */ + +#define TIMER_DATA_TYPE unsigned long +#define TIMER_FUNC_TYPE void (*)(TIMER_DATA_TYPE) + +#define timer_setup(timer, callback, flags) \ + __setup_timer((timer), (TIMER_FUNC_TYPE)(callback), \ + (TIMER_DATA_TYPE)(timer), (flags)) + +#define from_timer(var, callback_timer, timer_fieldname) \ + container_of(callback_timer, typeof(*var), timer_fieldname) + +#ifndef xdp_do_flush_map +#define xdp_do_flush_map() do {} while (0) +#endif +struct _kc_xdp_buff { + void *data; + void *data_end; + void *data_hard_start; +}; +#define xdp_buff _kc_xdp_buff +struct _kc_bpf_prog { +}; +#define bpf_prog _kc_bpf_prog +#ifndef DIV_ROUND_DOWN_ULL +#define DIV_ROUND_DOWN_ULL(ll, d) \ + ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) +#endif /* DIV_ROUND_DOWN_ULL */ +#else /* > 4.14 */ +#define HAVE_XDP_SUPPORT +#endif /* 4.14.0 */ + +/*****************************************************************************/ +#ifndef ETHTOOL_GLINKSETTINGS + +#define __ETHTOOL_LINK_MODE_MASK_NBITS 32 +#define ETHTOOL_LINK_MASK_SIZE BITS_TO_LONGS(__ETHTOOL_LINK_MODE_MASK_NBITS) + +/** + * struct ethtool_link_ksettings + * @link_modes: supported and advertising, single item arrays + * @link_modes.supported: bitmask of supported link speeds + * @link_modes.advertising: bitmask of currently advertised speeds + * @base: base link details + * @base.speed: current link speed + * @base.port: current port type + * @base.duplex: current duplex mode + * @base.autoneg: current autonegotiation settings + * + * This struct and the following macros provide a way to support the old + * ethtool get/set_settings API on older kernels, but in the style of the new + * GLINKSETTINGS API. In this way, the same code can be used to support both + * APIs as seemlessly as possible. + * + * It should be noted the old API only has support up to the first 32 bits. + */ +struct ethtool_link_ksettings { + struct { + u32 speed; + u8 port; + u8 duplex; + u8 autoneg; + } base; + struct { + unsigned long supported[ETHTOOL_LINK_MASK_SIZE]; + unsigned long advertising[ETHTOOL_LINK_MASK_SIZE]; + } link_modes; +}; + +#define ETHTOOL_LINK_NAME_advertising(mode) ADVERTISED_ ## mode +#define ETHTOOL_LINK_NAME_supported(mode) SUPPORTED_ ## mode +#define ETHTOOL_LINK_NAME(name) ETHTOOL_LINK_NAME_ ## name +#define ETHTOOL_LINK_CONVERT(name, mode) ETHTOOL_LINK_NAME(name)(mode) + +/** + * ethtool_link_ksettings_zero_link_mode + * @ptr: ptr to ksettings struct + * @name: supported or advertising + */ +#define ethtool_link_ksettings_zero_link_mode(ptr, name)\ + (*((ptr)->link_modes.name) = 0x0) + +/** + * ethtool_link_ksettings_add_link_mode + * @ptr: ptr to ksettings struct + * @name: supported or advertising + * @mode: link mode to add + */ +#define ethtool_link_ksettings_add_link_mode(ptr, name, mode)\ + (*((ptr)->link_modes.name) |= (typeof(*((ptr)->link_modes.name)))ETHTOOL_LINK_CONVERT(name, mode)) + +/** + * ethtool_link_ksettings_del_link_mode + * @ptr: ptr to ksettings struct + * @name: supported or advertising + * @mode: link mode to delete + */ +#define ethtool_link_ksettings_del_link_mode(ptr, name, mode)\ + (*((ptr)->link_modes.name) &= ~(typeof(*((ptr)->link_modes.name)))ETHTOOL_LINK_CONVERT(name, mode)) + +/** + * ethtool_link_ksettings_test_link_mode + * @ptr: ptr to ksettings struct + * @name: supported or advertising + * @mode: link mode to add + */ +#define ethtool_link_ksettings_test_link_mode(ptr, name, mode)\ + (!!(*((ptr)->link_modes.name) & ETHTOOL_LINK_CONVERT(name, mode))) + +/** + * _kc_ethtool_ksettings_to_cmd - Convert ethtool_link_ksettings to ethtool_cmd + * @ks: ethtool_link_ksettings struct + * @cmd: ethtool_cmd struct + * + * Convert an ethtool_link_ksettings structure into the older ethtool_cmd + * structure. We provide this in kcompat.h so that drivers can easily + * implement the older .{get|set}_settings as wrappers around the new api. + * Hence, we keep it prefixed with _kc_ to make it clear this isn't actually + * a real function in the kernel. + */ +static inline void +_kc_ethtool_ksettings_to_cmd(struct ethtool_link_ksettings *ks, + struct ethtool_cmd *cmd) +{ + cmd->supported = (u32)ks->link_modes.supported[0]; + cmd->advertising = (u32)ks->link_modes.advertising[0]; + ethtool_cmd_speed_set(cmd, ks->base.speed); + cmd->duplex = ks->base.duplex; + cmd->autoneg = ks->base.autoneg; + cmd->port = ks->base.port; +} + +#endif /* !ETHTOOL_GLINKSETTINGS */ + +/*****************************************************************************/ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)) || \ + (SLE_VERSION_CODE && (SLE_VERSION_CODE <= SLE_VERSION(12,3,0))) || \ + (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7,5)))) +#define phy_speed_to_str _kc_phy_speed_to_str +const char *_kc_phy_speed_to_str(int speed); +#else /* (LINUX >= 4.14.0) || (SLES > 12.3.0) || (RHEL > 7.5) */ +#include +#endif /* (LINUX < 4.14.0) || (SLES <= 12.3.0) || (RHEL <= 7.5) */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +#if ((RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,6))) || \ + (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(15,1,0)))) +#else /* RHEL >= 7.6 || SLES >= 15.1 */ +#endif /* !(RHEL >= 7.6) && !(SLES >= 15.1) */ +void _kc_ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst, + struct ethtool_link_ksettings *src); +#define ethtool_intersect_link_masks _kc_ethtool_intersect_link_masks +#else /* >= 4.15 */ +#define HAVE_XDP_BUFF_DATA_META +#endif /* 4.15.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0)) +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,7)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(12,4,0) && \ + SLE_VERSION_CODE < SLE_VERSION(15,0,0)) && \ + !(SLE_VERSION_CODE >= SLE_VERSION(15,1,0))) +/* The return value of the strscpy() and strlcpy() functions is different. + * This could be potentially hazard for the future. + * To avoid this the void result is forced. + * So it is not possible use this function with the return value. + * Return value is required in kernel 4.3 through 4.15 + */ +#define strscpy(...) (void)(strlcpy(__VA_ARGS__)) +#endif /* !RHEL >= 7.7 && !SLES12sp4+ && !SLES15sp1+ */ + +#define pci_printk(level, pdev, fmt, arg...) \ + dev_printk(level, &(pdev)->dev, fmt, ##arg) +#define pci_emerg(pdev, fmt, arg...) dev_emerg(&(pdev)->dev, fmt, ##arg) +#define pci_alert(pdev, fmt, arg...) dev_alert(&(pdev)->dev, fmt, ##arg) +#define pci_crit(pdev, fmt, arg...) dev_crit(&(pdev)->dev, fmt, ##arg) +#define pci_err(pdev, fmt, arg...) dev_err(&(pdev)->dev, fmt, ##arg) +#define pci_warn(pdev, fmt, arg...) dev_warn(&(pdev)->dev, fmt, ##arg) +#define pci_notice(pdev, fmt, arg...) dev_notice(&(pdev)->dev, fmt, ##arg) +#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg) +#define pci_dbg(pdev, fmt, arg...) dev_dbg(&(pdev)->dev, fmt, ##arg) + +#ifndef array_index_nospec +static inline unsigned long _kc_array_index_mask_nospec(unsigned long index, + unsigned long size) +{ + /* + * Always calculate and emit the mask even if the compiler + * thinks the mask is not needed. The compiler does not take + * into account the value of @index under speculation. + */ + OPTIMIZER_HIDE_VAR(index); + return ~(long)(index | (size - 1UL - index)) >> (BITS_PER_LONG - 1); +} + +#define array_index_nospec(index, size) \ +({ \ + typeof(index) _i = (index); \ + typeof(size) _s = (size); \ + unsigned long _mask = _kc_array_index_mask_nospec(_i, _s); \ + \ + BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ + BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ + \ + (typeof(_i)) (_i & _mask); \ +}) +#endif /* array_index_nospec */ +#ifndef sizeof_field +#define sizeof_field(TYPE, MEMBER) (sizeof((((TYPE *)0)->MEMBER))) +#endif /* sizeof_field */ +#else /* >= 4.16 */ +#include +#define HAVE_TC_FLOWER_OFFLOAD_COMMON_EXTACK +#define HAVE_VF_STATS_DROPPED +#endif /* 4.16.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,17,0)) +#include +#include +#define PCIE_SPEED_16_0GT 0x17 +#define PCI_EXP_LNKCAP_SLS_16_0GB 0x00000004 /* LNKCAP2 SLS Vector bit 3 */ +#define PCI_EXP_LNKSTA_CLS_16_0GB 0x0004 /* Current Link Speed 16.0GT/s */ +#define PCI_EXP_LNKCAP2_SLS_16_0GB 0x00000010 /* Supported Speed 16GT/s */ +void _kc_pcie_print_link_status(struct pci_dev *dev); +#define pcie_print_link_status _kc_pcie_print_link_status +#else /* >= 4.17.0 */ +#define HAVE_XDP_BUFF_IN_XDP_H +#endif /* 4.17.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0)) +#if (SLE_VERSION_CODE < SLE_VERSION(15,1,0)) +#define firmware_request_nowarn request_firmware_direct +#endif /* SLES < 15.1 */ +#else +#include +#define HAVE_XDP_FRAME_STRUCT +#define HAVE_XDP_SOCK +#define HAVE_NDO_XDP_XMIT_BULK_AND_FLAGS +#define NO_NDO_XDP_FLUSH +#endif /* 4.18.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0)) +#define bitmap_alloc(nbits, flags) \ + kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long), flags) +#define bitmap_zalloc(nbits, flags) bitmap_alloc(nbits, ((flags) | __GFP_ZERO)) +#define bitmap_free(bitmap) kfree(bitmap) +#ifdef ETHTOOL_GLINKSETTINGS +#define ethtool_ks_clear(ptr, name) \ + ethtool_link_ksettings_zero_link_mode(ptr, name) +#define ethtool_ks_add_mode(ptr, name, mode) \ + ethtool_link_ksettings_add_link_mode(ptr, name, mode) +#define ethtool_ks_del_mode(ptr, name, mode) \ + ethtool_link_ksettings_del_link_mode(ptr, name, mode) +#define ethtool_ks_test(ptr, name, mode) \ + ethtool_link_ksettings_test_link_mode(ptr, name, mode) +#endif /* ETHTOOL_GLINKSETTINGS */ +#define HAVE_NETPOLL_CONTROLLER +#define REQUIRE_PCI_CLEANUP_AER_ERROR_STATUS +#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(15,1,0))) +#define HAVE_NDO_SELECT_QUEUE_SB_DEV +#endif + +static inline void __kc_metadata_dst_free(void *md_dst) +{ + kfree(md_dst); +} + +#define metadata_dst_free(md_dst) __kc_metadata_dst_free(md_dst) +#else /* >= 4.19.0 */ +#define NO_NETDEV_BPF_PROG_ATTACHED +#define HAVE_NDO_SELECT_QUEUE_SB_DEV +#define HAVE_NETDEV_SB_DEV +#define HAVE_TCF_VLAN_TPID +#define HAVE_RHASHTABLE_TYPES +#endif /* 4.19.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)) +#define HAVE_XDP_UMEM_PROPS +#else /* >= 4.20.0 */ +#define HAVE_AF_XDP_ZC_SUPPORT +#define HAVE_ETF_SUPPORT /* Earliest TxTime First */ +#endif /* 4.20.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(8,0))) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)) +#define NETLINK_MAX_COOKIE_LEN 20 +struct netlink_ext_ack { + const char *_msg; + const struct nlattr *bad_attr; + u8 cookie[NETLINK_MAX_COOKIE_LEN]; + u8 cookie_len; +}; + +#endif /* < 4.12 */ +static inline int _kc_dev_open(struct net_device *netdev, + struct netlink_ext_ack __always_unused *extack) +{ + return dev_open(netdev); +} + +#define dev_open _kc_dev_open + +static inline int +_kc_dev_change_flags(struct net_device *netdev, unsigned int flags, + struct netlink_ext_ack __always_unused *extack) +{ + return dev_change_flags(netdev, flags); +} + +#define dev_change_flags _kc_dev_change_flags +#endif /* !(RHEL_RELEASE_CODE && RHEL > RHEL(8,0)) */ +#else /* >= 5.0.0 */ +#define HAVE_DMA_ALLOC_COHERENT_ZEROES_MEM +#endif /* 5.0.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0)) +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,1))) +#define HAVE_DEVLINK_INFO_GET +#define HAVE_DEVLINK_FLASH_UPDATE +#endif /* RHEL < 8.1 */ +#else /* >= 5.1.0 */ +#define NO_XDP_QUERY_XSK_UMEM +#define HAVE_AF_XDP_NETDEV_UMEM +#define HAVE_DEVLINK_INFO_GET +#define HAVE_DEVLINK_FLASH_UPDATE +#endif /* 5.1.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)) +#if (defined HAVE_SKB_XMIT_MORE) && \ +(!(RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,2)))) +#define netdev_xmit_more() (skb->xmit_more) +#else +#define netdev_xmit_more() (0) +#endif + +#ifndef mmiowb +#ifdef CONFIG_IA64 +#define mmiowb() asm volatile ("mf.a" ::: "memory") +#else +#define mmiowb() +#endif +#endif /* mmiowb */ + +#else /* >= 5.2.0 */ +#define HAVE_NDO_SELECT_QUEUE_FALLBACK_REMOVED +#define SPIN_UNLOCK_IMPLIES_MMIOWB +#endif /* 5.2.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,3,0)) +#if (!(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,2))) +#else /* RHEL >= 8.2 */ +#define HAVE_DEVLINK_PORT_ATTR_PCI_VF +#endif /* RHEL >= 8.2 */ + +#ifndef ETH_P_LLDP +#define ETH_P_LLDP 0x88CC +#endif /* !ETH_P_LLDP */ + +#else /* >= 5.3.0 */ +#define XSK_UMEM_RETURNS_XDP_DESC +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)) +#if !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(15,3,0)) +#define HAVE_XSK_UMEM_HAS_ADDRS +#endif /* SLE < 15.3 */ +#endif /* < 5.8.0*/ +#define HAVE_DEVLINK_PORT_ATTR_PCI_VF +#if IS_ENABLED(CONFIG_DIMLIB) +#define HAVE_CONFIG_DIMLIB +#endif +#endif /* 5.3.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)) +#if (SLE_VERSION_CODE >= SLE_VERSION(15,2,0)) +#define HAVE_NDO_XSK_WAKEUP +#endif /* SLES15sp2 */ +#else /* >= 5.4.0 */ +#define HAVE_NDO_XSK_WAKEUP +#endif /* 5.4.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,5,0)) +static inline unsigned long _kc_bitmap_get_value8(const unsigned long *map, + unsigned long start) +{ + const size_t index = BIT_WORD(start); + const unsigned long offset = start % BITS_PER_LONG; + + return (map[index] >> offset) & 0xFF; +} +#define bitmap_get_value8 _kc_bitmap_get_value8 + +static inline void _kc_bitmap_set_value8(unsigned long *map, + unsigned long value, + unsigned long start) +{ + const size_t index = BIT_WORD(start); + const unsigned long offset = start % BITS_PER_LONG; + + map[index] &= ~(0xFFUL << offset); + map[index] |= value << offset; +} +#define bitmap_set_value8 _kc_bitmap_set_value8 + +#endif /* 5.5.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)) +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#define xsk_umem_release_addr xsk_umem_discard_addr +#define xsk_umem_release_addr_rq xsk_umem_discard_addr_rq +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,3)) || \ + (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(15,3,0))) +#define HAVE_TX_TIMEOUT_TXQUEUE +#endif +#else /* >= 5.6.0 */ +#define HAVE_TX_TIMEOUT_TXQUEUE +#endif /* 5.6.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0)) +u64 _kc_pci_get_dsn(struct pci_dev *dev); +#define pci_get_dsn(dev) _kc_pci_get_dsn(dev) +#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID +#define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID "fw.bundle_id" +#endif +#else /* >= 5.7.0 */ +#define HAVE_ETHTOOL_COALESCE_PARAMS_SUPPORT +#endif /* 5.7.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)) +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,4))) +/* RHEL >= 8.4 */ +#define HAVE_XDP_BUFF_FRAME_SZ +#endif +#else /* >= 5.8.0 */ +#define HAVE_XDP_BUFF_FRAME_SZ +#define HAVE_MEM_TYPE_XSK_BUFF_POOL +#endif /* 5.8.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0)) +#else /* >= 5.9.0 */ +#define HAVE_FLOW_INDIR_BLOCK_QDISC +#define HAVE_UDP_TUNNEL_NIC_INFO +#endif /* 5.9.0 */ +#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(8,3))) +#define HAVE_FLOW_INDIR_BLOCK_QDISC +#endif +#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(15,3,0))) +#define HAVE_FLOW_INDIR_BLOCK_QDISC +#endif /* SLE_VERSION_CODE && SLE_VERSION_CODE >= SLES15SP3 */ + +/*****************************************************************************/ +#ifdef HAVE_XDP_RXQ_INFO_REG_3_PARAMS +#ifdef HAVE_XDP_BUFF_IN_XDP_H +#include +#else +#include +#endif /* HAVE_XDP_BUFF_IN_XDP_H */ +static inline int +_kc_xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, struct net_device *dev, + u32 queue_index, unsigned int __always_unused napi_id) +{ + return xdp_rxq_info_reg(xdp_rxq, dev, queue_index); +} + +#define xdp_rxq_info_reg(xdp_rxq, dev, queue_index, napi_id) \ + _kc_xdp_rxq_info_reg(xdp_rxq, dev, queue_index, napi_id) +#endif /* HAVE_XDP_RXQ_INFO_REG_3_PARAMS */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0)) +#ifdef HAVE_NAPI_BUSY_LOOP +#ifdef CONFIG_NET_RX_BUSY_POLL +#include +static inline void +_kc_napi_busy_loop(unsigned int napi_id, + bool (*loop_end)(void *, unsigned long), void *loop_end_arg, + bool __always_unused prefer_busy_poll, + u16 __always_unused budget) +{ + napi_busy_loop(napi_id, loop_end, loop_end_arg); +} + +#define napi_busy_loop(napi_id, loop_end, loop_end_arg, prefer_busy_poll, budget) \ + _kc_napi_busy_loop(napi_id, loop_end, loop_end_arg, prefer_busy_poll, budget) +#endif /* CONFIG_NET_RX_BUSY_POLL */ +#endif /* HAVE_NAPI_BUSY_LOOP */ +#endif /* <5.11.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0)) +#define HAVE_GRO_HEADER +#endif /* >=5.12.0 */ + +/*****************************************************************************/ +/* + * Load the implementations file which actually defines kcompat backports. + * Legacy backports still exist in this file, but all new backports must be + * implemented using kcompat_*defs.h and kcompat_impl.h + */ +#include "kcompat_impl.h" + +#endif /* _KCOMPAT_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_cleanup.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_cleanup.h new file mode 100644 index 0000000000..7db86ea9ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_cleanup.h @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _KCOMPAT_CLEANUP_H_ +#define _KCOMPAT_CLEANUP_H_ + +#include + +#ifndef typeof_member +#define typeof_member(T, m) typeof(((T*)0)->m) +#endif +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) +#endif /* GCC_VERSION */ +#define GCC_IS_BELOW(x) (GCC_VERSION < (x)) + +#if defined __has_attribute +#if __has_attribute(cleanup) +#define HAVE_ATTRIBUTE_CLEANUP +#endif +#else +#if !GCC_IS_BELOW(30306) +#define HAVE_ATTRIBUTE_CLEANUP +#endif +#endif + +#ifndef HAVE_ATTRIBUTE_CLEANUP +#error "This compiler is too old, cleanup extension (GCC 3.3.6) is required." +#endif + +#if defined(__clang__) +/* + * Clang prior to 17 is being silly and considers many __cleanup() variables + * as unused (because they are, their sole purpose is to go out of scope). + * + * https://reviews.llvm.org/D152180 + */ +#define __cleanup(func) __maybe_unused __attribute__((__cleanup__(func))) +#else /* __clang__ */ +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#cleanup + */ +#define __cleanup(func) __attribute__((__cleanup__(func))) +#endif /* __clang__ */ + +/* We do the same style backport as usual with cleanup.h stuff, except it + * has its own file. So, include the base if it exist: + */ +#ifndef NEED_DEFINE_FREE +#include +#endif + +#ifdef NEED_DEFINE_FREE +/* there is no cleanup.h stuff at all given by the kernel */ +/* cond guards omitted */ + +#define DEFINE_FREE(_name, _type, _free) \ + static inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; } + +#define __free(_name) __cleanup(__free_##_name) + +#define __get_and_null(p, nullvalue) \ + ({ \ + __auto_type __ptr = &(p); \ + __auto_type __val = *__ptr; \ + *__ptr = nullvalue; \ + __val; \ + }) + +static inline __must_check +const volatile void * __must_check_fn(const volatile void *val) +{ return val; } + +#define no_free_ptr(p) \ + ((typeof(p)) __must_check_fn((__force const volatile void *)__get_and_null(p, NULL))) + +#define return_ptr(p) return no_free_ptr(p) + +#define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...) \ +typedef _type class_##_name##_t; \ +static inline void class_##_name##_destructor(_type *p) \ +{ _type _T = *p; _exit; } \ +static inline _type class_##_name##_constructor(_init_args) \ +{ _type t = _init; return t; } + +#define EXTEND_CLASS(_name, ext, _init, _init_args...) \ +typedef class_##_name##_t class_##_name##ext##_t; \ +static inline void class_##_name##ext##_destructor(class_##_name##_t *p)\ +{ class_##_name##_destructor(p); } \ +static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ +{ class_##_name##_t t = _init; return t; } + +#define CLASS(_name, var) \ + class_##_name##_t var __cleanup(class_##_name##_destructor) = \ + class_##_name##_constructor + +#define guard(_name) \ + CLASS(_name, __UNIQUE_ID(guard)) + +#define __DEFINE_LOCK_GUARD_1(_name, _type, _lock) \ +static inline class_##_name##_t class_##_name##_constructor(_type *l) \ +{ \ + class_##_name##_t _t = { .lock = l }, *_T = &_t; \ + _lock; \ + return _t; \ +} + +#define __DEFINE_LOCK_GUARD_0(_name, _lock) \ +static inline class_##_name##_t class_##_name##_constructor(void) \ +{ \ + class_##_name##_t _t = { .lock = (void*)1 }, \ + *_T __maybe_unused = &_t; \ + _lock; \ + return _t; \ +} + + +#endif /* NEED_DEFINE_FREE */ + +#ifdef NEED___DEFINE_CLASS_IS_CONDITIONAL +/* If there is very early implementation present, lacking commit + * fcc22ac5baf0 ("cleanup: Adjust scoped_guard() macros to avoid potential + * warning"), we must #undef some macros and provide newer versions. + * + * If there were no cleanup.h at all, we could also do the same. + */ +#undef scoped_guard +#undef DEFINE_GUARD +#undef DEFINE_LOCK_GUARD_1 +#undef DEFINE_LOCK_GUARD_0 +#undef __DEFINE_UNLOCK_GUARD + +#define __DEFINE_CLASS_IS_CONDITIONAL(_name, _is_cond) \ +static __maybe_unused const bool class_##_name##_is_conditional = _is_cond + +#define DEFINE_GUARD(_name, _type, _lock, _unlock) \ + __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \ + static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \ + { return (void *)(__force unsigned long)*_T; } + +#define __guard_ptr(_name) class_##_name##_lock_ptr +#define __is_cond_ptr(_name) class_##_name##_is_conditional + +#define __scoped_guard(_name, _label, args...) \ + for (CLASS(_name, scope)(args); \ + __guard_ptr(_name)(&scope) || !__is_cond_ptr(_name); \ + ({ goto _label; })) \ + if (0) { \ +_label: \ + break; \ + } else + +#define __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, ...) \ +typedef struct { \ + _type *lock; \ + __VA_ARGS__; \ +} class_##_name##_t; \ + \ +static inline void class_##_name##_destructor(class_##_name##_t *_T) \ +{ \ + if (_T->lock) { _unlock; } \ +} \ + \ +static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T) \ +{ \ + return (void *)(__force unsigned long)_T->lock; \ +} + +#define scoped_guard(_name, args...) \ + __scoped_guard(_name, __UNIQUE_ID(label), args) + +#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \ +__DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ +__DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \ +__DEFINE_LOCK_GUARD_1(_name, _type, _lock) + +#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \ +__DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ +__DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ +__DEFINE_LOCK_GUARD_0(_name, _lock) + +#endif /* NEED___DEFINE_CLASS_IS_CONDITIONAL */ + +/* We put "DEFINE" macros invocations here (instead of kernel_impl.h), to + * have easier time changing them (as changes are most often related). + * + * Content is synchronized to upstream commit 0ff41df1cb26 ("Linux 6.15"). + * + * Please note that most "DEFINE" macros invocations are not covered here, only + * those that we actually have used in the code. That means that even some of + * the files we cover could have some invocations in upstream that we miss. + * + * Please also note that we could not just put newest version of, say, mutex.h + * invocations here, as that would force use to replace whole file. + */ + +#include +#ifdef NEED_DEFINE_GUARD_MUTEX +DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T)) +#endif + +#include +#ifdef NEED_DEFINE_FREE_KFREE +DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T)) +#endif +#ifdef NEED_DEFINE_FREE_KVFREE +void kvfree(const void *); +DEFINE_FREE(kvfree, void *, if (!IS_ERR_OR_NULL(_T)) kvfree(_T)) +#endif + +#include +/* COND guards omitted */ +#ifdef NEED_LOCK_GUARD_FOR_SPINLOCK +DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t, + raw_spin_lock(_T->lock), + raw_spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t, + raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING), + raw_spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t, + raw_spin_lock_irq(_T->lock), + raw_spin_unlock_irq(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, + raw_spin_lock_irqsave(_T->lock, _T->flags), + raw_spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + +DEFINE_LOCK_GUARD_1(spinlock, spinlock_t, + spin_lock(_T->lock), + spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t, + spin_lock_irq(_T->lock), + spin_unlock_irq(_T->lock)) + +DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t, + spin_lock_irqsave(_T->lock, _T->flags), + spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) +#endif /* NEED_LOCK_GUARD_FOR_SPINLOCK */ + +#ifdef NEED_LOCK_GUARD_FOR_SPINLOCK_BH +DEFINE_LOCK_GUARD_1(raw_spinlock_bh, raw_spinlock_t, + raw_spin_lock_bh(_T->lock), + raw_spin_unlock_bh(_T->lock)) +DEFINE_LOCK_GUARD_1(spinlock_bh, spinlock_t, + spin_lock_bh(_T->lock), + spin_unlock_bh(_T->lock)) +#endif /* NEED_LOCK_GUARD_FOR_SPINLOCK_BH */ + +#include +#ifdef NEED_LOCK_GUARD_FOR_RCU +DEFINE_LOCK_GUARD_0(rcu, + do { + rcu_read_lock(); + /* + * sparse doesn't call the cleanup function, + * so just release immediately and don't track + * the context. We don't need to anyway, since + * the whole point of the guard is to not need + * the explicit unlock. + */ + __release(RCU); + } while (0), + rcu_read_unlock()) +#endif + +#ifdef NEED_DEFINE_GUARD_DEVLINK +struct devlink; +#ifdef NEED_DEVL_LOCK +static +#endif + void devl_lock(struct devlink *); +#ifdef NEED_DEVL_LOCK +static +#endif + void devl_unlock(struct devlink *); +DEFINE_GUARD(devl, struct devlink *, devl_lock(_T), devl_unlock(_T)); +#endif + +#endif /* _KCOMPAT_CLEANUP_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_defs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_defs.h new file mode 100644 index 0000000000..87b5e51450 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_defs.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_DEFS_H_ +#define _KCOMPAT_DEFS_H_ + +#ifndef LINUX_VERSION_CODE +#include +#else +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif +#endif /* LINUX_VERSION_CODE */ + +#ifndef UTS_RELEASE +#include +#endif + +/* + * Include the definitions file for HAVE/NEED flags for the standard upstream + * kernels. + * + * Then, based on the distribution we detect, load the distribution specific + * definitions file that customizes the definitions for the target + * distribution. + */ +#include "kcompat_std_defs.h" + +#ifdef CONFIG_SUSE_KERNEL +#include "kcompat_sles_defs.h" +#elif UBUNTU_VERSION_CODE +#include "kcompat_ubuntu_defs.h" +#elif RHEL_RELEASE_CODE +#include "kcompat_rhel_defs.h" +#endif +#endif /* _KCOMPAT_DEFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_gcc.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_gcc.h new file mode 100644 index 0000000000..2a5047f129 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_gcc.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_GCC_H_ +#define _KCOMPAT_GCC_H_ + +#ifdef __has_attribute +#if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +#else +# define fallthrough do {} while (0) /* fallthrough */ +#endif /* __has_attribute(fallthrough) */ +#else +# define fallthrough do {} while (0) /* fallthrough */ +#endif /* __has_attribute */ + +/* Backport macros for controlling GCC diagnostics */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0) ) +/* Compilers before gcc-4.6 do not understand "#pragma GCC diagnostic push" */ +#if GCC_VERSION >= 40600 +#define __diag_str1(s) #s +#define __diag_str(s) __diag_str1(s) +#define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) +#else +#define __diag(s) +#endif /* GCC_VERSION >= 4.6 */ +#define __diag_push() __diag(push) +#define __diag_pop() __diag(pop) +#endif /* LINUX_VERSION < 4.18.0 */ + +#if GCC_IS_BELOW(50000) +/* Workaround for gcc bug - not accepting "(type)" before "{ ... }" as part of + * static struct initializers [when used with -std=gnu11 switch] + * https://bugzilla.redhat.com/show_bug.cgi?id=1672652 + * + * fix was backported to gcc 4.8.5-39 by RedHat, contained in RHEL 7.7 + * workaround here is to just drop that redundant (commented out below) part and + * redefine kernel macros used by us. + */ + +/* Since problematic code could be triggered by print-family (incl. wrappers) + * invocation, we have to first include headers that contain macros that we are + * redefining, and only later proceed with the rest of includes. + */ +#include +#include +#include +#include + +#ifdef __SPIN_LOCK_INITIALIZER +#undef __SPIN_LOCK_UNLOCKED +#define __SPIN_LOCK_UNLOCKED(lockname) \ + /* (spinlock_t) */ __SPIN_LOCK_INITIALIZER(lockname) +#endif /* __SPIN_LOCK_INITIALIZER */ + +#ifdef __RAW_SPIN_LOCK_INITIALIZER +#undef __RAW_SPIN_LOCK_UNLOCKED +#define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ + /* (raw_spinlock_t) */ __RAW_SPIN_LOCK_INITIALIZER(lockname) +#endif /* __RAW_SPIN_LOCK_INITIALIZER */ + +#ifndef CONFIG_DEBUG_SPINLOCK +/* raw_spin_lock_init needs __RAW_SPIN_LOCK_UNLOCKED with typecast, so keep the + * original impl, + * but enhance it with typecast dropped from __RAW_SPIN_LOCK_UNLOCKED() */ +#undef raw_spin_lock_init +#define raw_spin_lock_init(lock) \ + do { *(lock) = (raw_spinlock_t) __RAW_SPIN_LOCK_UNLOCKED(lock); \ + } while (0) +#endif /* !CONFIG_DEBUG_SPINLOCK */ + +#undef STATIC_KEY_INIT_TRUE +#define STATIC_KEY_INIT_TRUE \ + { .enabled = { 1 }, \ + { .type = 1UL } } + +#undef STATIC_KEY_INIT_FALSE +#define STATIC_KEY_INIT_FALSE \ + { .enabled = { 0 } } + +#undef STATIC_KEY_TRUE_INIT +#define STATIC_KEY_TRUE_INIT \ + /* (struct static_key_true) */ { .key = STATIC_KEY_INIT_TRUE } + +#undef STATIC_KEY_FALSE_INIT +#define STATIC_KEY_FALSE_INIT \ + /* (struct static_key_false) */ { .key = STATIC_KEY_INIT_FALSE } + +#ifdef HAVE_JUMP_LABEL +/* dd_key_init() is used (indirectly) with arg like "(STATIC_KEY_INIT_FALSE)" + * from DEFINE_DYNAMIC_DEBUG_METADATA(), which, depending on config has many + * different definitions (including helper macros). + * To reduce compat code, just consume parens from the arg instead copy-pasting + * all definitions and slightly changing them. */ +#define _KC_SLURP_PARENS(...) __VA_ARGS__ +#undef dd_key_init +#define dd_key_init(key, init) key = _KC_SLURP_PARENS init +#endif /* HAVE_JUMP_LABEL */ + +#undef UUID_INIT +#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ + {{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, \ + ((a) >> 8) & 0xff, (a) & 0xff, \ + ((b) >> 8) & 0xff, (b) & 0xff, \ + ((c) >> 8) & 0xff, (c) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) \ + }} + +#endif /* old GCC < 5.0 */ + +#endif /* _KCOMPAT_GCC_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_impl.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_impl.h new file mode 100644 index 0000000000..29d8a489e3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_impl.h @@ -0,0 +1,3638 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_IMPL_H_ +#define _KCOMPAT_IMPL_H_ + +#ifdef HAVE_STRING_HELPERS_H +#include +#endif /* HAVE_STRING_HELPERS_H */ + +#ifdef HAVE_STRING_CHOICES_H +#include +#endif /* HAVE_STRING_CHOICES_H */ + +/* devlink support */ +#if IS_ENABLED(CONFIG_NET_DEVLINK) + +/* + * This change is adding buffer in enum value for ice_devlink_param_id. + * + * In upstream / OOT compiled from source it is safe to use + * DEVLINK_PARAM_GENERIC_ID_MAX as first value for ice_devlink_param_id + * enum. + * + * In case of binary release (for Secure Boot purpose) this caused issue + * with supporting multiple kernels because backport made by SLES changed + * value of DEVLINK_PARAM_GENERIC_ID_MAX. This caused -EINVAL to + * be returned by devlink_params_register() because + * ICE_DEVLINK_PARAM_ID_FW_MGMT_MINSREV (compiled on older kernel) was equal + * to DEVLINK_PARAM_GENERIC_ID_MAX (in newer kernel). + */ +#define DEVLINK_PARAM_GENERIC_ID_MAX __KC_DEVLINK_PARAM_GENERIC_ID_MAX +#include +#undef DEVLINK_PARAM_GENERIC_ID_MAX +#define DEVLINK_PARAM_GENERIC_ID_MAX (__KC_DEVLINK_PARAM_GENERIC_ID_MAX + 32) +#endif /* CONFIG_DEVLINK */ + +/* This file contains implementations of backports from various kernels. It + * must rely only on NEED_ and HAVE_ checks. It must not make any + * checks to determine the kernel version when deciding whether to include an + * implementation. + * + * All new implementations must go in this file, and legacy implementations + * should be migrated to the new format over time. + */ + +/* The same kcompat code is used here and auxiliary module. To avoid + * duplication and functions redefitions in some scenarios, include the + * auxiliary kcompat implementation here. + */ +#include "auxiliary_compat.h" + +/* generic network stack functions */ + +/* NEED_NETDEV_TXQ_BQL_PREFETCH + * + * functions + * netdev_txq_bql_complete_prefetchw() + * netdev_txq_bql_enqueue_prefetchw() + * + * were added in kernel 4.20 upstream commit + * 535114539bb2 ("net: add netdev_txq_bql_{enqueue, complete}_prefetchw() + * helpers") + */ +#ifdef NEED_NETDEV_TXQ_BQL_PREFETCH +/** + * netdev_txq_bql_enqueue_prefetchw - prefetch bql data for write + * @dev_queue: pointer to transmit queue + * + * BQL enabled drivers might use this helper in their ndo_start_xmit(), + * to give appropriate hint to the CPU. + */ +static inline +void netdev_txq_bql_enqueue_prefetchw(struct netdev_queue *dev_queue) +{ +#ifdef CONFIG_BQL + prefetchw(&dev_queue->dql.num_queued); +#endif +} + +/** + * netdev_txq_bql_complete_prefetchw - prefetch bql data for write + * @dev_queue: pointer to transmit queue + * + * BQL enabled drivers might use this helper in their TX completion path, + * to give appropriate hint to the CPU. + */ +static inline +void netdev_txq_bql_complete_prefetchw(struct netdev_queue *dev_queue) +{ +#ifdef CONFIG_BQL + prefetchw(&dev_queue->dql.limit); +#endif +} +#endif /* NEED_NETDEV_TXQ_BQL_PREFETCH */ + +/* NEED_NETDEV_TX_SENT_QUEUE + * + * __netdev_tx_sent_queue was added in kernel 4.20 upstream commit + * 3e59020abf0f ("net: bql: add __netdev_tx_sent_queue()") + */ +#ifdef NEED_NETDEV_TX_SENT_QUEUE +/* Variant of netdev_tx_sent_queue() for drivers that are aware + * that they should not test BQL status themselves. + * We do want to change __QUEUE_STATE_STACK_XOFF only for the last + * skb of a batch. + * Returns true if the doorbell must be used to kick the NIC. + */ +static inline bool __netdev_tx_sent_queue(struct netdev_queue *dev_queue, + unsigned int bytes, + bool xmit_more) +{ + if (xmit_more) { +#ifdef CONFIG_BQL + dql_queued(&dev_queue->dql, bytes); +#endif + return netif_tx_queue_stopped(dev_queue); + } + netdev_tx_sent_queue(dev_queue, bytes); + return true; +} +#endif /* NEED_NETDEV_TX_SENT_QUEUE */ + +/*HAVE_NETIF_SUBQUEUE_MAYBE_STOP + * + * netif_subqueue_maybe_stop was added in kernel 6.3 upstream commit + * c91c46de6bbc ("net: provide macros for commonly copied lockless queue + * stop/wake code") + */ +#ifndef HAVE_NETIF_SUBQUEUE_MAYBE_STOP +#define netif_txq_try_stop(txq, get_desc, start_thrs) \ + ({ \ + int _res; \ + \ + netif_tx_stop_queue(txq); \ + /* Producer index and stop bit must be visible \ + * to consumer before we recheck. \ + * Pairs with a barrier in __netif_txq_completed_wake(). \ + */ \ + smp_mb__after_atomic(); \ + \ + /* We need to check again in a case another \ + * CPU has just made room available. \ + */ \ + _res = 0; \ + if (unlikely(get_desc >= start_thrs)) { \ + netif_tx_start_queue(txq); \ + _res = -1; \ + } \ + _res; \ + }) + +/** + * netif_txq_maybe_stop() - locklessly stop a Tx queue, if needed + * @txq: struct netdev_queue to stop/start + * @get_desc: get current number of free descriptors (see requirements below!) + * @stop_thrs: minimal number of available descriptors for queue to be left + * enabled + * @start_thrs: minimal number of descriptors to re-enable the queue, can be + * equal to @stop_thrs or higher to avoid frequent waking + * + * All arguments may be evaluated multiple times, beware of side effects. + * @get_desc must be a formula or a function call, it must always + * return up-to-date information when evaluated! + * Expected to be used from ndo_start_xmit, see the comment on top of the file. + * + * Returns: + * 0 if the queue was stopped + * 1 if the queue was left enabled + * -1 if the queue was re-enabled (raced with waking) + */ +#define netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs) \ + ({ \ + int _res; \ + \ + _res = 1; \ + if (unlikely(get_desc < stop_thrs)) \ + _res = netif_txq_try_stop(txq, get_desc, start_thrs); \ + _res; \ + }) + +#define netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, start_thrs) \ + ({ \ + struct netdev_queue *txq; \ + \ + txq = netdev_get_tx_queue(dev, idx); \ + netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs); \ + }) +#endif /* !HAVE_NETIF_SUBQUEUE_MAYBE_STOP */ + +/* NEED_NET_PREFETCH + * + * net_prefetch was introduced by commit f468f21b7af0 ("net: Take common + * prefetch code structure into a function") + * + * This function is trivial to re-implement in full. + */ +#ifdef NEED_NET_PREFETCH +static inline void net_prefetch(void *p) +{ + prefetch(p); +#if L1_CACHE_BYTES < 128 + prefetch((u8 *)p + L1_CACHE_BYTES); +#endif +} +#endif /* NEED_NET_PREFETCH */ + +/* NEED_SKB_FRAG_OFF and NEED_SKB_FRAG_OFF_ADD + * + * skb_frag_off and skb_frag_off_add were added in upstream commit + * 7240b60c98d6 ("linux: Add skb_frag_t page_offset accessors") + * + * Implementing the wrappers directly for older kernels which still have the + * old implementation of skb_frag_t is trivial. + * + * LTS 4.19 backported the define for skb_frag_off in 4.19.201. + * d94d95ae0dd0 ("gro: ensure frag0 meets IP header alignment") + * Need to exclude defining skb_frag_off for 4.19.X where X > 200 + */ +#ifdef NEED_SKB_FRAG_OFF +static inline unsigned int skb_frag_off(const skb_frag_t *frag) +{ + return frag->page_offset; +} +#endif /* NEED_SKB_FRAG_OFF */ +#ifdef NEED_SKB_FRAG_OFF_ADD +static inline void skb_frag_off_add(skb_frag_t *frag, int delta) +{ + frag->page_offset += delta; +} +#endif /* NEED_SKB_FRAG_OFF_ADD */ + +/* + * NEED_DMA_ATTRS, NEED_DMA_ATTRS_PTR and related functions + * + * dma_map_page_attrs and dma_unmap_page_attrs were added in upstream commit + * 0495c3d36794 ("dma: add calls for dma_map_page_attrs and + * dma_unmap_page_attrs") + * + * Implementing these calls in this way makes RHEL7.4 compile (which doesn't + * have these) and all newer kernels compile fine, while using only the new + * calls with no ifdeffery. + * + * In kernel 4.10 the commit ("dma-mapping: use unsigned long for dma_attrs") + * switched the argument from struct dma_attrs * to unsigned long. + * + * __page_frag_cache_drain was implemented in 2017, but __page_frag_drain came + * with the above series for _attrs, and seems to have been backported at the + * same time. + * + * Please note SLES12.SP3 and RHEL7.5 and newer have all three of these + * already. + * + * If need be in the future for some reason, we could make a separate NEED_ + * define for __page_frag_cache_drain, but not yet. + * + * For clarity: there are three states: + * 1) no attrs + * 2) attrs but with a pointer to a struct dma_attrs + * 3) attrs but with unsigned long type + */ +#ifdef NEED_DMA_ATTRS +static inline +dma_addr_t __kc_dma_map_page_attrs(struct device *dev, struct page *page, + size_t offset, size_t size, + enum dma_data_direction dir, + unsigned long __always_unused attrs) +{ + return dma_map_page(dev, page, offset, size, dir); +} +#define dma_map_page_attrs __kc_dma_map_page_attrs + +static inline +void __kc_dma_unmap_page_attrs(struct device *dev, + dma_addr_t addr, size_t size, + enum dma_data_direction dir, + unsigned long __always_unused attrs) +{ + dma_unmap_page(dev, addr, size, dir); +} +#define dma_unmap_page_attrs __kc_dma_unmap_page_attrs + +static inline void __page_frag_cache_drain(struct page *page, + unsigned int count) +{ +#ifdef HAVE_PAGE_COUNT_BULK_UPDATE + if (!page_ref_sub_and_test(page, count)) + return; + + init_page_count(page); +#else + WARN_ON(count > 1); + if (!count) + return; +#endif + __free_pages(page, compound_order(page)); +} +#elif defined(NEED_DMA_ATTRS_PTR) +static inline +dma_addr_t __kc_dma_map_page_attrs_long(struct device *dev, struct page *page, + size_t offset, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + struct dma_attrs dmaattrs = {}; + + if (attrs & DMA_ATTR_SKIP_CPU_SYNC) + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &dmaattrs); + + if (attrs & DMA_ATTR_WEAK_ORDERING) + dma_set_attr(DMA_ATTR_WEAK_ORDERING, &dmaattrs); + + return dma_map_page_attrs(dev, page, offset, size, dir, &dmaattrs); +} +#define dma_map_page_attrs __kc_dma_map_page_attrs_long +/* there is a nasty macro buried in dma-mapping.h which reroutes dma_map_page + * and dma_unmap_page to attribute versions, so take control of that macro and + * fix it here. */ +#ifdef dma_map_page +#undef dma_map_page +#define dma_map_page(a,b,c,d,r) dma_map_page_attrs(a,b,c,d,r,0) +#endif + +static inline +void __kc_dma_unmap_page_attrs_long(struct device *dev, + dma_addr_t addr, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + struct dma_attrs dmaattrs = {}; + + if (attrs & DMA_ATTR_SKIP_CPU_SYNC) + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &dmaattrs); + + if (attrs & DMA_ATTR_WEAK_ORDERING) + dma_set_attr(DMA_ATTR_WEAK_ORDERING, &dmaattrs); + + dma_unmap_page_attrs(dev, addr, size, dir, &dmaattrs); +} +#define dma_unmap_page_attrs __kc_dma_unmap_page_attrs_long +#ifdef dma_unmap_page +#undef dma_unmap_page +#define dma_unmap_page(a,b,c,r) dma_unmap_page_attrs(a,b,c,r,0) +#endif +#endif /* NEED_DMA_ATTRS_PTR */ + +/* + * NETIF_F_HW_L2FW_DOFFLOAD related functions + * + * Support for NETIF_F_HW_L2FW_DOFFLOAD was first introduced upstream by + * commit a6cc0cfa72e0 ("net: Add layer 2 hardware acceleration operations for + * macvlan devices") + */ +#ifdef NETIF_F_HW_L2FW_DOFFLOAD + +#include + +/* NEED_MACVLAN_ACCEL_PRIV + * + * macvlan_accel_priv is an accessor function that replaced direct access to + * the macvlan->fwd_priv variable. It was introduced in commit 7d775f63470c + * ("macvlan: Rename fwd_priv to accel_priv and add accessor function") + * + * Implement the new wrapper name by simply accessing the older + * macvlan->fwd_priv name. + */ +#ifdef NEED_MACVLAN_ACCEL_PRIV +static inline void *macvlan_accel_priv(struct net_device *dev) +{ + struct macvlan_dev *macvlan = netdev_priv(dev); + + return macvlan->fwd_priv; +} +#endif /* NEED_MACVLAN_ACCEL_PRIV */ + +/* NEED_MACVLAN_RELEASE_L2FW_OFFLOAD + * + * macvlan_release_l2fw_offload was introduced upstream by commit 53cd4d8e4dfb + * ("macvlan: Provide function for interfaces to release HW offload") + * + * Implementing this is straight forward, but we must be careful to use + * fwd_priv instead of accel_priv. Note that both the change to accel_priv and + * introduction of this function happened in the same release. + */ +#ifdef NEED_MACVLAN_RELEASE_L2FW_OFFLOAD +static inline int macvlan_release_l2fw_offload(struct net_device *dev) +{ + struct macvlan_dev *macvlan = netdev_priv(dev); + + macvlan->fwd_priv = NULL; + return dev_uc_add(macvlan->lowerdev, dev->dev_addr); +} +#endif /* NEED_MACVLAN_RELEASE_L2FW_OFFLOAD */ + +/* NEED_MACVLAN_SUPPORTS_DEST_FILTER + * + * macvlan_supports_dest_filter was introduced upstream by commit 6cb1937d4eff + * ("macvlan: Add function to test for destination filtering support") + * + * The implementation doesn't rely on anything new and is trivial to backport + * for kernels that have NETIF_F_HW_L2FW_DOFFLOAD support. + */ +#ifdef NEED_MACVLAN_SUPPORTS_DEST_FILTER +static inline bool macvlan_supports_dest_filter(struct net_device *dev) +{ + struct macvlan_dev *macvlan = netdev_priv(dev); + + return macvlan->mode == MACVLAN_MODE_PRIVATE || + macvlan->mode == MACVLAN_MODE_VEPA || + macvlan->mode == MACVLAN_MODE_BRIDGE; +} +#endif /* NEED_MACVLAN_SUPPORTS_DEST_FILTER */ + +#endif /* NETIF_F_HW_L2FW_DOFFLOAD */ + +/* tc functions */ + +/* NEED_FLOW_INDR_BLOCK_CB_REGISTER + * + * __flow_indr_block_cb_register and __flow_indr_block_cb_unregister were + * added in upstream commit 4e481908c51b ("flow_offload: move tc indirect + * block to flow offload") + * + * This was a simple rename so we can just translate from the old + * naming scheme with a macro. + */ +#ifdef NEED_FLOW_INDR_BLOCK_CB_REGISTER +#define __flow_indr_block_cb_register __tc_indr_block_cb_register +#define __flow_indr_block_cb_unregister __tc_indr_block_cb_unregister +#endif + +/* devlink support */ +#if IS_ENABLED(CONFIG_NET_DEVLINK) + +/* NEED_DEVLINK_FMSG_PUT + * + * devlink_fmsg_put was introduced upstream by commit 346947223bac ("devlink: + * add devlink_fmsg_put() macro") as a way to simplify adding data to + * a devlink health report based on its type. + * + * For older kernels, it is straight forward to re-implement here. Note that + * it does require _Generic support from the compiler. + */ +#ifdef NEED_DEVLINK_FMSG_PUT +#define devlink_fmsg_put(fmsg, name, value) ( \ + _Generic((value), \ + bool : devlink_fmsg_bool_pair_put, \ + u8 : devlink_fmsg_u8_pair_put, \ + u16 : devlink_fmsg_u32_pair_put, \ + u32 : devlink_fmsg_u32_pair_put, \ + u64 : devlink_fmsg_u64_pair_put, \ + int : devlink_fmsg_u32_pair_put, \ + char * : devlink_fmsg_string_pair_put, \ + const char * : devlink_fmsg_string_pair_put) \ + (fmsg, name, (value))) +#endif /* NEED_DEVLINK_FMSG_PUT */ + +/* NEED_DEVLINK_FLASH_UPDATE_STATUS_NOTIFY + * + * devlink_flash_update_status_notify, _begin_notify, and _end_notify were + * added by upstream commit 191ed2024de9 ("devlink: allow driver to update + * progress of flash update") + * + * For older kernels that lack the netlink messages, convert the functions + * into no-ops. + */ +#ifdef NEED_DEVLINK_FLASH_UPDATE_STATUS_NOTIFY +static inline void +devlink_flash_update_begin_notify(struct devlink __always_unused *devlink) +{ +} + +static inline void +devlink_flash_update_end_notify(struct devlink __always_unused *devlink) +{ +} + +static inline void +devlink_flash_update_status_notify(struct devlink __always_unused *devlink, + const char __always_unused *status_msg, + const char __always_unused *component, + unsigned long __always_unused done, + unsigned long __always_unused total) +{ +} +#endif /* NEED_DEVLINK_FLASH_UPDATE_STATUS_NOTIFY */ + +#ifndef HAVE_DEVLINK_FLASH_UPDATE_PARAMS +struct devlink_flash_update_params { + const char *file_name; + const char *component; + u32 overwrite_mask; +}; +#endif /* !HAVE_DEVLINK_FLASH_UPDATE_PARAMS */ + +#ifndef HAVE_DEVLINK_FLASH_UPDATE_PARAMS_OVERWRITE_MASK +#ifndef DEVLINK_FLASH_OVERWRITE_SETTINGS +#define DEVLINK_FLASH_OVERWRITE_SETTINGS BIT(0) +#endif + +#ifndef DEVLINK_FLASH_OVERWRITE_IDENTIFIERS +#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS BIT(1) +#endif + +#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0) +#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(1) +#endif /* HAVE_DEVLINK_FLASH_UPDATE_PARAMS_OVERWRITE_MASK */ + +/* NEED_DEVLINK_FLASH_UPDATE_TIMEOUT_NOTIFY + * + * devlink_flash_update_timeout_notify was added by upstream commit + * f92970c694b3 ("devlink: add timeout information to status_notify"). + * + * For older kernels, just convert timeout notifications into regular status + * notification messages without timeout information. + */ +#ifdef NEED_DEVLINK_FLASH_UPDATE_TIMEOUT_NOTIFY +static inline void +devlink_flash_update_timeout_notify(struct devlink *devlink, + const char *status_msg, + const char *component, + unsigned long __always_unused timeout) +{ + devlink_flash_update_status_notify(devlink, status_msg, component, 0, 0); +} +#endif /* NEED_DEVLINK_FLASH_UPDATE_TIMEOUT_NOTIFY */ + +/* + * NEED_DEVLINK_PORT_ATTRS_SET_STRUCT + * + * HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR + * HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID + * + * devlink_port_attrs_set was introduced by commit b9ffcbaf56d3 ("devlink: + * introduce devlink_port_attrs_set") + * + * It's function signature has changed multiple times over several kernel + * releases: + * + * commit 5ec1380a21bb ("devlink: extend attrs_set for setting port + * flavours") added the ability to set port flavour. (Note that there is no + * official kernel release with devlink_port_attrs_set without the flavour + * argument, as they were introduced in the same series.) + * + * commit bec5267cded2 ("net: devlink: extend port attrs for switch ID") added + * the ability to set the switch ID (HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID) + * + * Finally commit 71ad8d55f8e5 ("devlink: Replace devlink_port_attrs_set + * parameters with a struct") refactored to pass devlink_port_attrs struct + * instead of individual parameters. (!NEED_DEVLINK_PORT_ATTRS_SET_STRUCT) + * + * We want core drivers to just use the latest form that takes + * a devlink_port_attrs structure. Note that this structure did exist as part + * of but was never used directly by driver code prior to the + * function parameter change. For this reason, the implementation always + * relies on _kc_devlink_port_attrs instead of what was defined in the kernel. + */ +#ifdef NEED_DEVLINK_PORT_ATTRS_SET_STRUCT + +#ifndef HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR +enum devlink_port_flavour { + DEVLINK_PORT_FLAVOUR_PHYSICAL, + DEVLINK_PORT_FLAVOUR_CPU, + DEVLINK_PORT_FLAVOUR_DSA, + DEVLINK_PORT_FLAVOUR_PCI_PF, + DEVLINK_PORT_FLAVOUR_PCI_VF, +}; +#endif + +struct _kc_devlink_port_phys_attrs { + u32 port_number; + u32 split_subport_number; +}; + +struct _kc_devlink_port_pci_pf_attrs { + u16 pf; +}; + +struct _kc_devlink_port_pci_vf_attrs { + u16 pf; + u16 vf; +}; + +struct _kc_devlink_port_attrs { + u8 split:1, + splittable:1; + u32 lanes; + enum devlink_port_flavour flavour; + struct netdev_phys_item_id switch_id; + union { + struct _kc_devlink_port_phys_attrs phys; + struct _kc_devlink_port_pci_pf_attrs pci_pf; + struct _kc_devlink_port_pci_vf_attrs pci_vf; + }; +}; + +#define devlink_port_attrs _kc_devlink_port_attrs + +static inline void +_kc_devlink_port_attrs_set(struct devlink_port *devlink_port, + struct _kc_devlink_port_attrs *attrs) +{ +#if defined(HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID) + devlink_port_attrs_set(devlink_port, attrs->flavour, attrs->phys.port_number, + attrs->split, attrs->phys.split_subport_number, + attrs->switch_id.id, attrs->switch_id.id_len); +#elif defined(HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR) + devlink_port_attrs_set(devlink_port, attrs->flavour, attrs->phys.port_number, + attrs->split, attrs->phys.split_subport_number); +#else + if (attrs->split) + devlink_port_split_set(devlink_port, attrs->phys.port_number); +#endif +} + +#define devlink_port_attrs_set _kc_devlink_port_attrs_set + +#endif /* NEED_DEVLINK_PORT_ATTRS_SET_STRUCT */ + +/* + * NEED_DEVLINK_ALLOC_SETS_DEV + * + * Since commit 919d13a7e455 ("devlink: Set device as early as possible"), the + * devlink device pointer is set by devlink_alloc instead of by + * devlink_register. + * + * devlink_alloc now includes the device pointer in its signature, while + * devlink_register no longer includes it. + * + * This implementation provides a replacement for devlink_alloc which will + * take and then silently discard the extra dev pointer. + * + * To use devlink_register, drivers must check + * HAVE_DEVLINK_REGISTER_SETS_DEV. Note that we can't easily provide + * a backport of the change to devlink_register directly. Although the dev + * pointer is accessible from the devlink pointer through the driver private + * section, it is device driver specific and is not easily accessible in + * compat code. + */ +#ifdef NEED_DEVLINK_ALLOC_SETS_DEV +static inline struct devlink * +_kc_devlink_alloc(const struct devlink_ops *ops, size_t priv_size, + struct device * __always_unused dev) +{ + return devlink_alloc(ops, priv_size); +} +#define devlink_alloc _kc_devlink_alloc +#endif /* NEED_DEVLINK_ALLOC_SETS_DEV */ + +#ifdef HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT +#ifdef NEED_DEVLINK_UNLOCKED_RESOURCE +/* + * NEED_DEVLINK_UNLOCKED_RESOURCE + * + * Handle devlink API change introduced in: + * c223d6a4bf ("net: devlink: add unlocked variants of devlink_resource*() + * functions") + * 644a66c60f ("net: devlink: convert reload command to take implicit + * devlink->lock") + * + * devl_resource_size_get() does not take devlink->lock where + * devlink_resource_size_get() takes devlink->lock, but we do not introduce + * locking in the driver as taking the lock in devlink_reload() was added + * upstream in the same version as API change. + * + * We have to rely on distro maintainers properly backporting of both mentioned + * commits for OOT driver to work properly. + * In case of backporting only c223d6a4bf assert inside + * devl_resource_size_get() will trigger kernel WARNING, + * In case of backporting only 644a66c60f devlink_resource_size_get() will + * attempt to take the lock second time. + */ +static inline int devl_resource_size_get(struct devlink *devlink, + u64 resource_id, + u64 *p_resource_size) +{ + return devlink_resource_size_get(devlink, resource_id, p_resource_size); +} +#endif /* NEED_DEVLINK_UNLOCKED_RESOURCE */ +#endif /* HAVE_DEVLINK_RELOAD_ACTION_AND_LIMIT */ + +#ifdef NEED_DEVLINK_TO_DEV +/* + * Commit 2131463 ("devlink: Reduce struct devlink exposure") + * removed devlink struct fields from header to avoid exposure + * and added devlink_to_dev and related functions to access + * them instead. + */ +static inline struct device * +devlink_to_dev(const struct devlink *devlink) +{ + return devlink->dev; +} +#endif /* NEED_DEVLINK_TO_DEV */ + +#ifdef NEED_DEVL_LOCK +static inline void devl_lock(struct devlink *devlink) +{ +} + +static inline void devl_unlock(struct devlink *devlink) +{ +} +#endif /* NEED_DEVL_LOCK */ + +#ifdef NEED_DEVL_RESOURCE_REGISTER +static inline int +devl_resource_register(struct devlink *devlink, const char *resource_name, + u64 resource_size, u64 resource_id, + u64 parent_resource_id, + const struct devlink_resource_size_params *size_params) +{ + int err; + + devl_unlock(devlink); + err = devlink_resource_register(devlink, resource_name, resource_size, + resource_id, parent_resource_id, + size_params); + devl_lock(devlink); + + return err; +} + +static inline void devl_resources_unregister(struct devlink *devlink) +{ + devl_unlock(devlink); +#ifdef NEED_DEVLINK_RESOURCES_UNREGISTER_NO_RESOURCE + devlink_resources_unregister(devlink, NULL); +#else + devlink_resources_unregister(devlink); +#endif /* NEED_DEVLINK_RESOURCES_UNREGISTER_NO_RESOURCE */ + devl_lock(devlink); +} + +static inline void +devl_resource_occ_get_register(struct devlink *devlink, u64 resource_id, + devlink_resource_occ_get_t *occ_get, + void *occ_get_priv) +{ + devl_unlock(devlink); + devlink_resource_occ_get_register(devlink, resource_id, occ_get, + occ_get_priv); + devl_lock(devlink); +} + +static inline void devl_resource_occ_get_unregister(struct devlink *devlink, + u64 resource_id) +{ + devl_unlock(devlink); + devlink_resource_occ_get_unregister(devlink, resource_id); + devl_lock(devlink); +} +#endif /* NEED_DEVL_RESOURCE_REGISTER */ + +#ifdef NEED_DEVL_PORT_REGISTER +static inline int devl_port_register(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index) +{ + int err; + + devl_unlock(devlink); + err = devlink_port_register(devlink, devlink_port, port_index); + devl_lock(devlink); + + return err; +} + +static inline void devl_port_unregister(struct devlink_port *devlink_port) +{ + devl_unlock(devlink_port->devlink); + devlink_port_unregister(devlink_port); + devl_lock(devlink_port->devlink); +} +#endif /* NEED_DEVL_PORT_REGISTER */ + +#ifdef HAVE_DEVLINK_REGIONS +#ifdef NEED_DEVL_REGION_CREATE + +struct _kc_devlink_region { + void *devlink; +}; + +static inline struct devlink_region +*devl_region_create(struct devlink *devlink, + const struct devlink_region_ops *ops, + u32 region_max_snapshots, u64 region_size) +{ + struct devlink_region *region; + + devl_unlock(devlink); +#ifdef NEED_DEVLINK_REGION_CREATE_OPS + region = devlink_region_create(devlink, ops->name, region_max_snapshots, + region_size); +#else + region = devlink_region_create(devlink, ops, region_max_snapshots, + region_size); +#endif /* NEED_DEVLINK_REGION_CREATE_OPS */ + devl_lock(devlink); + + return region; +} + +static inline void devl_region_destroy(struct devlink_region *region) +{ + devl_unlock(((struct _kc_devlink_region *)(region))->devlink); + devlink_region_destroy(region); + devl_lock(((struct _kc_devlink_region *)(region))->devlink); +} +#endif /* NEED_DEVL_REGION_CREATE */ +#endif /* HAVE_DEVLINK_REGIONS */ + +#ifdef NEED_DEVL_PARAMS_REGISTER +static inline int devl_params_register(struct devlink *devlink, + const struct devlink_param *params, + size_t params_count) +{ + int err; + + devl_unlock(devlink); + err = devlink_params_register(devlink, params, params_count); + devl_lock(devlink); + + return err; +} + +static inline void devl_params_unregister(struct devlink *devlink, + const struct devlink_param *params, + size_t params_count) +{ + devl_unlock(devlink); + devlink_params_unregister(devlink, params, params_count); + devl_lock(devlink); +} +#endif /* NEED_DEVL_PARAMS_REGISTER */ + +#ifdef NEED_DEVL_REGISTER +static inline int devl_register(struct devlink *devlink) +{ + devl_unlock(devlink); +#ifdef HAVE_DEVLINK_REGISTER_SETS_DEV + devlink_register(devlink, devlink->dev); +#else + devlink_register(devlink); +#endif /* HAVE_DEVLINK_REGISTER_SETS_DEV */ + devl_lock(devlink); + + return 0; +} + +static inline void devl_unregister(struct devlink *devlink) +{ + devl_unlock(devlink); + devlink_unregister(devlink); + devl_lock(devlink); +} +#endif /* NEED_DEVL_REGISTER */ + +#ifdef HAVE_DEVLINK_HEALTH +#ifdef NEED_DEVL_HEALTH_REPORTER_CREATE + +struct kc_devlink_health_reporter { + struct list_head list; + void *priv; + const struct devlink_health_reporter_ops *ops; + struct devlink *devlink; +}; + +static inline struct devlink_health_reporter * +devl_health_reporter_create(struct devlink *devlink, + const struct devlink_health_reporter_ops *ops, + void *priv) +{ + struct devlink_health_reporter *reporter; + + devl_unlock(devlink); +#ifdef NEED_DEVLINK_HEALTH_DEFAULT_AUTO_RECOVER + reporter = devlink_health_reporter_create(devlink, ops, 0, + !!ops->recover, priv); +#else + reporter = devlink_health_reporter_create(devlink, ops, 0, priv); +#endif /* NEED_DEVLINK_HEALTH_DEFAULT_AUTO_RECOVER */ + devl_lock(devlink); + + return reporter; +} + +static inline void +devl_health_reporter_destroy(struct devlink_health_reporter *reporter) +{ + devl_unlock(((struct kc_devlink_health_reporter *)(reporter))->devlink); + devlink_health_reporter_destroy(reporter); + devl_lock(((struct kc_devlink_health_reporter *)(reporter))->devlink); +} +#endif /* NEED_DEVL_HEALTH_REPORTER_CREATE */ + +#ifdef NEED_DEVL_HEALTH_REPORTER_CREATE_REMOVE_GRACEFUL_PERIOD +/* NEED_DEVL_HEALTH_REPORTER_CREATE_REMOVE_GRACEFUL_PERIOD + * + * Since upstream commit d2b007374551 ("devlink: Move graceful period + * parameter to reporter ops"), the graceful period is defined in the ops + * structure instead of as a parameter to the health reporter. Currently, all + * Intel drivers use a fixed value of zero for the graceful period. Provide + * a wrapper implementation that always passes 0 to the graceful period. If + * a driver should ever need to support a non-zero graceful period, an + * appropriate HAVE_ flag must be implemented and the driver must be careful + * to check and pass the non-zero graceful period on older kernels. + */ +#define devl_health_reporter_create(devlink, ops, priv) \ + devl_health_reporter_create((devlink), (ops), 0, (priv)) + +#endif /* NEED_DEVL_HEALTH_REPORTER_CREATE_REMOVE_GRACEFUL_PERIOD */ + +#ifdef NEED_DEVLINK_FMSG_DUMP_SKB +/** + * devlink_fmsg_dump_skb - Dump sk_buffer structure + * @fmsg: devlink formatted message pointer + * @skb: pointer to skb + * + * Dump diagnostic information about sk_buff structure, like headroom, length, + * tailroom, MAC, etc. + */ +static inline void devlink_fmsg_dump_skb(struct devlink_fmsg *fmsg, + const struct sk_buff *skb) +{ + struct skb_shared_info *sh = skb_shinfo(skb); + struct sock *sk = skb->sk; + bool has_mac, has_trans; + + has_mac = skb_mac_header_was_set(skb); + has_trans = skb_transport_header_was_set(skb); + + devlink_fmsg_pair_nest_start(fmsg, "skb"); + devlink_fmsg_obj_nest_start(fmsg); + devlink_fmsg_put(fmsg, "actual len", skb->len); + devlink_fmsg_put(fmsg, "head len", skb_headlen(skb)); + devlink_fmsg_put(fmsg, "data len", skb->data_len); + devlink_fmsg_put(fmsg, "tail len", skb_tailroom(skb)); + devlink_fmsg_put(fmsg, "MAC", has_mac ? skb->mac_header : -1); + devlink_fmsg_put(fmsg, "MAC len", + has_mac ? skb_mac_header_len(skb) : -1); + devlink_fmsg_put(fmsg, "network hdr", skb->network_header); + devlink_fmsg_put(fmsg, "network hdr len", + has_trans ? skb_network_header_len(skb) : -1); + devlink_fmsg_put(fmsg, "transport hdr", + has_trans ? skb->transport_header : -1); + devlink_fmsg_put(fmsg, "csum", (__force u32)skb->csum); + devlink_fmsg_put(fmsg, "csum_ip_summed", (u8)skb->ip_summed); + devlink_fmsg_put(fmsg, "csum_complete_sw", !!skb->csum_complete_sw); + devlink_fmsg_put(fmsg, "csum_valid", !!skb->csum_valid); + devlink_fmsg_put(fmsg, "csum_level", (u8)skb->csum_level); + devlink_fmsg_put(fmsg, "sw_hash", !!skb->sw_hash); + devlink_fmsg_put(fmsg, "l4_hash", !!skb->l4_hash); + devlink_fmsg_put(fmsg, "proto", ntohs(skb->protocol)); + devlink_fmsg_put(fmsg, "pkt_type", (u8)skb->pkt_type); + devlink_fmsg_put(fmsg, "iif", skb->skb_iif); + + if (sk) { + devlink_fmsg_pair_nest_start(fmsg, "sk"); + devlink_fmsg_obj_nest_start(fmsg); + devlink_fmsg_put(fmsg, "family", sk->sk_type); + devlink_fmsg_put(fmsg, "type", sk->sk_type); + devlink_fmsg_put(fmsg, "proto", sk->sk_protocol); + devlink_fmsg_obj_nest_end(fmsg); + devlink_fmsg_pair_nest_end(fmsg); + } + + devlink_fmsg_obj_nest_end(fmsg); + devlink_fmsg_pair_nest_end(fmsg); + + devlink_fmsg_pair_nest_start(fmsg, "shinfo"); + devlink_fmsg_obj_nest_start(fmsg); + devlink_fmsg_put(fmsg, "tx_flags", sh->tx_flags); + devlink_fmsg_put(fmsg, "nr_frags", sh->nr_frags); + devlink_fmsg_put(fmsg, "gso_size", sh->gso_size); + devlink_fmsg_put(fmsg, "gso_type", sh->gso_type); + devlink_fmsg_put(fmsg, "gso_segs", sh->gso_segs); + devlink_fmsg_obj_nest_end(fmsg); + devlink_fmsg_pair_nest_end(fmsg); +} +#endif /* NEED_DEVLINK_FMSG_DUMP_SKB */ +#endif /* HAVE_DEVLINK_HEALTH */ +#endif /* CONFIG_NET_DEVLINK */ + +#ifdef NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE +/* ida_alloc(), ida_alloc_min(), ida_alloc_max(), ida_alloc_range(), and + * ida_free() were added in commit 5ade60dda43c ("ida: add new API"). + * + * Also, using "0" as the "end" argument (3rd argument) to ida_simple_get() is + * considered the max value, which is why it's used in ida_alloc() and + * ida_alloc_min(). + */ +static inline int ida_alloc(struct ida *ida, gfp_t gfp) +{ + return ida_simple_get(ida, 0, 0, gfp); +} + +static inline int ida_alloc_min(struct ida *ida, unsigned int min, gfp_t gfp) +{ + return ida_simple_get(ida, min, 0, gfp); +} + +static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp) +{ + return ida_simple_get(ida, 0, max, gfp); +} + +static inline int +ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max, gfp_t gfp) +{ + return ida_simple_get(ida, min, max, gfp); +} + +static inline void ida_free(struct ida *ida, unsigned int id) +{ + ida_simple_remove(ida, id); +} +#endif /* NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE */ + +/* dev_printk implementations */ + +/* NEED_DEV_LEVEL_ONCE + * + * The dev_*_once family of printk functions was introduced by commit + * e135303bd5be ("device: Add dev__once variants") + * + * The implementation is very straight forward so we will just implement them + * as-is here. + * + * Note that this assumes all dev_*_once macros exist if dev_level_once was + * found. + */ +#ifdef NEED_DEV_LEVEL_ONCE +#ifdef CONFIG_PRINTK +#define dev_level_once(dev_level, dev, fmt, ...) \ +do { \ + static bool __print_once __read_mostly; \ + \ + if (!__print_once) { \ + __print_once = true; \ + dev_level(dev, fmt, ##__VA_ARGS__); \ + } \ +} while (0) +#else +#define dev_level_once(dev_level, dev, fmt, ...) \ +do { \ + if (0) \ + dev_level(dev, fmt, ##__VA_ARGS__); \ +} while (0) +#endif + +#define dev_emerg_once(dev, fmt, ...) \ + dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__) +#define dev_alert_once(dev, fmt, ...) \ + dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__) +#define dev_crit_once(dev, fmt, ...) \ + dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__) +#define dev_err_once(dev, fmt, ...) \ + dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__) +#define dev_warn_once(dev, fmt, ...) \ + dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__) +#define dev_notice_once(dev, fmt, ...) \ + dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__) +#define dev_info_once(dev, fmt, ...) \ + dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__) +#define dev_dbg_once(dev, fmt, ...) \ + dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__) +#endif /* NEED_DEV_LEVEL_ONCE */ + +#ifdef HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO + +/* NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 + * + * tc_cls_can_offload_and_chain0 was added by upstream commit + * 878db9f0f26d ("pkt_cls: add new tc cls helper to check offload flag and + * chain index"). + * + * This patch backports this function for older kernels by calling + * tc_can_offload() directly. + */ +#ifdef NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 +#include +static inline bool +tc_cls_can_offload_and_chain0(const struct net_device *dev, + struct tc_cls_common_offload *common) +{ + if (!tc_can_offload(dev)) + return false; + if (common->chain_index) + return false; + + return true; +} +#endif /* NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 */ +#endif /* HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO */ + +/* NEED_TC_SETUP_QDISC_MQPRIO + * + * TC_SETUP_QDISC_MQPRIO was added by upstream commit + * 575ed7d39e2f ("net_sch: mqprio: Change TC_SETUP_MQPRIO to + * TC_SETUP_QDISC_MQPRIO"). + * + * For older kernels which are using TC_SETUP_MQPRIO + */ +#ifdef NEED_TC_SETUP_QDISC_MQPRIO +#define TC_SETUP_QDISC_MQPRIO TC_SETUP_MQPRIO +#endif /* NEED_TC_SETUP_QDISC_MQPRIO */ + +#ifdef NEED_TCF_MIRRED_DEV +/* NEED_TCF_MIRRED_DEV + * + * tcf_mirred_dev was introduced by upstream commit 9f8a739e72f1 ("act_mirred: + * get rid of tcfm_ifindex from struct tcf_mirred"), which replaced + * tcf_mirred_ifindex. + */ +#define tcf_mirred_dev(a) \ + rtnl_dereference(to_mirred(a)->tcfm_dev) +#endif /* NEED_TCF_MIRRED_DEV */ + +#ifdef NEED_TCF_MIRRED_EGRESS_REDIRECT +/* NEED_TCF_MIRRED_EGRESS_REDIRECT + * + * is_tcf_mirred_egress_redirect was added by upstream commit 5724b8b56947 + * ("net/sched: tc_mirred: Rename public predicates 'is_tcf_mirred_redirect' + * and 'is_tcf_mirred_mirror'"), and is a simple rename of + * is_tcf_mirred_redirect. + */ +#define is_tcf_mirred_egress_redirect(a) is_tcf_mirred_redirect(a) +#endif /* NEED_TCF_MIRRED_EGRESS_REDIRECT */ + +#ifdef NEED_FLOW_BLOCK_BINDER_TYPE +/* NEED_FLOW_BLOCK_BINDER_TYPE + * + * The TCF_BLOCK_BINDER_TYPE enumerations were renamed by commit 32f8c4093ac3 + * ("net: flow_offload: rename TCF_BLOCK_BINDER_TYPE_* to + * FLOW_BLOCK_BINDER_TYPE_*") + */ +#define FLOW_BLOCK_BINDER_TYPE_UNSPEC TCF_BLOCK_BINDER_TYPE_UNSPEC +#define FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS \ + TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS +#define FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS \ + TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS +#endif /* NEED_FLOW_BLOCK_BINDER_TYPE */ + +#ifdef NEED_FLOW_BLOCK_BIND +/* NEED_FLOW_BLOCK_BIND + * + * The TCF_BLOCK_BIND and TCF_BLOCK_UNBIND were renamed by commit 9c0e189ec988 + * ("net: flow_offload: rename TC_BLOCK_{UN}BIND to FLOW_BLOCK_{UN}BIND") + */ +#define FLOW_BLOCK_BIND TC_BLOCK_BIND +#define FLOW_BLOCK_UNBIND TC_BLOCK_UNBIND +#endif /* NEED_FLOW_BLOCK_BIND */ + +#ifdef NEED_FLOW_BLOCK_CB_SETUP_SIMPLE +/* NEED_FLOW_BLOCK_CB_SETUP_SIMPLE + * + * flow_block_cb_setup_simple was introduced by commit 4e95bc268b91 + * ("net: flow_offload: add flow_block_cb_setup_simple()") along with several + * related macros. + * + * These are only used by drivers if HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO is + * true. + */ +#define FLOW_CLS_REPLACE TC_CLSFLOWER_REPLACE +#define FLOW_CLS_DESTROY TC_CLSFLOWER_DESTROY +#define FLOW_CLS_STATS TC_CLSFLOWER_STATS +#define FLOW_CLS_TMPLT_CREATE TC_CLSFLOWER_TMPLT_CREATE +#define FLOW_CLS_TMPLT_DESTROY TC_CLSFLOWER_TMPLT_DESTROY + +#ifdef HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO +#include + +int _kc_flow_block_cb_setup_simple(struct flow_block_offload *f, + struct list_head *driver_list, + tc_setup_cb_t *cb, + void *cb_ident, void *cb_priv, + bool ingress_only); + +#define flow_block_cb_setup_simple(f, driver_list, cb, cb_ident, cb_priv, \ + ingress_only) \ + _kc_flow_block_cb_setup_simple(f, driver_list, cb, cb_ident, cb_priv, \ + ingress_only) +#endif /* HAVE_TC_CB_AND_SETUP_QDISC_MQPRIO */ +#endif /* NEED_FLOW_BLOCK_CB_SETUP_SIMPLE */ + +/* ART/TSC functions */ +#ifdef HAVE_PTP_CROSSTIMESTAMP +/* NEED_CONVERT_ART_NS_TO_TSC + * + * convert_art_ns_to_tsc was added by upstream commit fc804f65d462 ("x86/tsc: + * Convert ART in nanoseconds to TSC"). + * + * This function is similar to convert_art_to_tsc, but expects the input in + * terms of nanoseconds, rather than ART cycles. We implement this by + * accessing the tsc_khz value and performing the proper calculation. In order + * to access the correct clock object on returning, we use the function + * convert_art_to_tsc, because the art_related_clocksource is inaccessible. + */ +#if defined(CONFIG_X86) && defined(NEED_CONVERT_ART_NS_TO_TSC) +#include + +static inline struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns) +{ + struct system_counterval_t system; + u64 tmp, res, rem; + + rem = do_div(art_ns, USEC_PER_SEC); + + res = art_ns * tsc_khz; + tmp = rem * tsc_khz; + + do_div(tmp, USEC_PER_SEC); + res += tmp; + + system = convert_art_to_tsc(art_ns); + system.cycles = res; + + return system; +} +#endif /* CONFIG_X86 && NEED_CONVERT_ART_NS_TO_TSC */ +#endif /* HAVE_PTP_CROSSTIMESTAMP */ + +/* PTP functions and definitions */ +#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) +#include +#include + +/* PTP_* ioctl flags + * + * PTP_PEROUT_ONE_SHOT and PTP_PEROUT_DUTY_CYCLE were added by commit + * f65b71aa25a6 ("ptp: add ability to configure duty cycle for periodic + * output") + * + * PTP_PEROUT_PHASE was added in commit b6bd41363a1c ("ptp: introduce + * a phase offset in the periodic output request") + * + * PTP_STRICT_FLAGS was added in commit 6138e687c7b6 ("ptp: Introduce strict + * checking of external time stamp options.") + * + * These flags control behavior for the periodic output PTP ioctl. For older + * kernels, we define the flags as 0. This allows bitmask checks on flags to + * work as expected, since these feature flags will become no-ops on kernels + * that lack support. + * + * Drivers can check if the relevant feature is actually supported by using an + * '#if' on the flag instead of an '#ifdef' + */ +#ifndef PTP_PEROUT_PHASE +#define PTP_PEROUT_PHASE 0 +#endif + +#ifndef PTP_PEROUT_DUTY_CYCLE +#define PTP_PEROUT_DUTY_CYCLE 0 +#endif + +#ifndef PTP_STRICT_FLAGS +#define PTP_STRICT_FLAGS 0 +#endif + +#ifndef PTP_PEROUT_PHASE +/* PTP_PEROUT_PHASE + * + * The PTP_PEROUT_PHASE flag was added in commit b6bd41363a1c ("ptp: introduce + * a phase offset in the periodic output request") as a way for userspace to + * request a phase-offset periodic output that starts on some arbitrary + * multiple of the clock period. + * + * For older kernels, define this flag to 0 so that checks for if it is + * enabled will always fail. Drivers should use '#if PTP_PEROUT_PHASE' to + * determine if the kernel has phase support, and use the flag as normal for + * checking supported flags or if the flag is enabled for a given request. + */ +#define PTP_PEROUT_PHASE 0 +#endif + +#endif /* CONFIG_PTP_1588_CLOCK */ + +/* + * NEED_PTP_SYSTEM_TIMESTAMP + * + * Upstream commit 361800876f80 ("ptp: add PTP_SYS_OFFSET_EXTENDED + * ioctl") introduces new ioctl, driver and helper functions. + * + * Required for PhotonOS 3.0 to correctly support backport of + * PTP patches introduced in Linux Kernel version 5.0 on 4.x kernels + */ +#ifdef NEED_PTP_SYSTEM_TIMESTAMP +struct ptp_system_timestamp { + struct timespec64 pre_ts; + struct timespec64 post_ts; +}; + +static inline void +ptp_read_system_prets(struct ptp_system_timestamp *sts) { } + +static inline void +ptp_read_system_postts(struct ptp_system_timestamp *sts) { } +#endif /* !NEED_PTP_SYSTEM_TIMESTAMP */ + +#ifdef NEED_PTP_CLASSIFY_RAW +/* NEED_PTP_CLASSIFY_RAW + * + * The ptp_classify_raw() function was introduced into + * as part of commit 164d8c666521 ("net: ptp: do not reimplement PTP/BPF + * classifier"). + * + * The kernel does provide the classifier BPF program since commit + * 15f0127d1d18 ("net: added a BPF to help drivers detect PTP packets."). + * However, it requires initializing the BPF filter properly and that varies + * depending on the kernel version. + * + * The only current uses for this function in our drivers is to enhance + * debugging messages. Rather than re-implementing the function just return + * PTP_CLASS_NONE indicating that it could not identify any PTP frame. + */ +#include + +static inline unsigned int ptp_classify_raw(struct sk_buff *skb) +{ + return PTP_CLASS_NONE; +} +#endif /* NEED_PTP_CLASSIFY_RAW */ + +#ifdef NEED_PTP_PARSE_HEADER +/* NEED_PTP_PARSE_HEADER + * + * The ptp_parse_header() function was introduced upstream in commit + * bdfbb63c314a ("ptp: Add generic ptp v2 header parsing function"). + * + * Since it is straight forward to implement, do so. + */ +#include + +struct clock_identity { + u8 id[8]; +}; + +struct port_identity { + struct clock_identity clock_identity; + __be16 port_number; +}; + +struct ptp_header { + u8 tsmt; /* transportSpecific | messageType */ + u8 ver; /* reserved | versionPTP */ + __be16 message_length; + u8 domain_number; + u8 reserved1; + u8 flag_field[2]; + __be64 correction; + __be32 reserved2; + struct port_identity source_port_identity; + __be16 sequence_id; + u8 control; + u8 log_message_interval; +} __packed; + +static inline struct ptp_header *ptp_parse_header(struct sk_buff *skb, + unsigned int type) +{ +#if defined(CONFIG_NET_PTP_CLASSIFY) + u8 *ptr = skb_mac_header(skb); + + if (type & PTP_CLASS_VLAN) + ptr += VLAN_HLEN; + + switch (type & PTP_CLASS_PMASK) { + case PTP_CLASS_IPV4: + ptr += IPV4_HLEN(ptr) + UDP_HLEN; + break; + case PTP_CLASS_IPV6: + ptr += IP6_HLEN + UDP_HLEN; + break; + case PTP_CLASS_L2: + break; + default: + return NULL; + } + + ptr += ETH_HLEN; + + /* Ensure that the entire header is present in this packet. */ + if (ptr + sizeof(struct ptp_header) > skb->data + skb->len) + return NULL; + + return (struct ptp_header *)ptr; +#else + return NULL; +#endif +} +#endif /* NEED_PTP_PARSE_HEADER */ + +#ifdef NEED_CPU_LATENCY_QOS_RENAME +/* NEED_CPU_LATENCY_QOS_RENAME + * + * The PM_QOS_CPU_DMA_LATENCY definition was removed in 67b06ba01857 ("PM: + * QoS: Drop PM_QOS_CPU_DMA_LATENCY and rename related functions"). The + * related functions were renamed to use "cpu_latency_qos_" prefix. + * + * Use wrapper functions to map the new API onto the API available in older + * kernels. + */ +#include +static inline void +cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) +{ + pm_qos_add_request(req, PM_QOS_CPU_DMA_LATENCY, value); +} + +static inline void +cpu_latency_qos_update_request(struct pm_qos_request *req, s32 new_value) +{ + pm_qos_update_request(req, new_value); +} + +static inline void +cpu_latency_qos_remove_request(struct pm_qos_request *req) +{ + pm_qos_remove_request(req); +} +#endif /* NEED_CPU_LATENCY_QOS_RENAME */ + +#ifdef NEED_DECLARE_STATIC_KEY_FALSE +/* NEED_DECLARE_STATIC_KEY_FALSE + * + * DECLARE_STATIC_KEY_FALSE was added by upstream commit b8fb03785d4d + * ("locking/static_keys: Provide DECLARE and well as DEFINE macros") + * + * The definition is now necessary to handle the xdpdrv work with more than 64 + * cpus + */ +#ifdef HAVE_STRUCT_STATIC_KEY_FALSE +#define DECLARE_STATIC_KEY_FALSE(name) extern struct static_key_false name +#else +#define DECLARE_STATIC_KEY_FALSE(name) extern struct static_key name +#endif /* HAVE_STRUCT_STATIC_KEY_FALSE */ +#endif /* NEED_DECLARE_STATIC_KEY_FALSE */ + +#ifdef NEED_DEFINE_STATIC_KEY_FALSE +/* NEED_DEFINE_STATIC_KEY_FALSE + * + * DEFINE_STATIC_KEY_FALSE was added by upstream commit 11276d5306b8 + * ("locking/static_keys: Add a new static_key interface") + * + * The definition is now necessary to handle the xdpdrv work with more than 64 + * cpus + */ +#define DEFINE_STATIC_KEY_FALSE(name) \ + struct static_key name = STATIC_KEY_INIT_FALSE +#endif /* NEED_DEFINE_STATIC_KEY_FALSE */ + +#ifdef NEED_STATIC_BRANCH_LIKELY +/* NEED_STATIC_BRANCH_LIKELY + * + * static_branch_likely, static_branch_unlikely, + * static_branch_inc, static_branch_dec was added by upstream commit + * 11276d5306b8 ("locking/static_keys: Add a new + * static_key interface") + * + * The definition is now necessary to handle the xdpdrv work with more than 64 + * cpus + * + * Note that we include all four definitions if static_branch_likely cannot be + * found in . + */ +#define static_branch_likely(x) likely(static_key_enabled(x)) +#define static_branch_unlikely(x) unlikely(static_key_enabled(x)) + +#define static_branch_enable(x) static_key_enable(x) +#define static_branch_inc(x) static_key_slow_inc(x) +#define static_branch_dec(x) static_key_slow_dec(x) + +#endif /* NEED_STATIC_BRANCH_LIKELY */ + +/* PCI related stuff */ + +/* NEED_PCI_AER_CLEAR_NONFATAL_STATUS + * + * 894020fdd88c ("PCI/AER: Rationalize error status register clearing") has + * renamed pci_cleanup_aer_uncorrect_error_status to more sane name. + */ +#ifdef NEED_PCI_AER_CLEAR_NONFATAL_STATUS +#define pci_aer_clear_nonfatal_status pci_cleanup_aer_uncorrect_error_status +#endif /* NEED_PCI_AER_CLEAR_NONFATAL_STATUS */ + +#ifdef NEED_NETDEV_XDP_STRUCT +#define netdev_bpf netdev_xdp +#endif /* NEED_NETDEV_XDP_STRUCT */ + +#ifdef NEED_NO_NETDEV_PROG_XDP_WARN_ACTION +#ifdef HAVE_XDP_SUPPORT +#include +static inline void +_kc_bpf_warn_invalid_xdp_action(__maybe_unused struct net_device *dev, + __maybe_unused struct bpf_prog *prog, u32 act) +{ + bpf_warn_invalid_xdp_action(act); +} + +#define bpf_warn_invalid_xdp_action(dev, prog, act) \ + _kc_bpf_warn_invalid_xdp_action(dev, prog, act) +#endif /* HAVE_XDP_SUPPORT */ +#endif /* HAVE_NETDEV_PROG_XDP_WARN_ACTION */ + +/* NEED_ETH_HW_ADDR_SET + * + * eth_hw_addr_set was added by upstream commit + * 48eab831ae8b ("net: create netdev->dev_addr assignment helpers") + * + * Using eth_hw_addr_set became required in 5.17, when the dev_addr field in + * the netdev struct was constified. See 48eab831ae8b ("net: create + * netdev->dev_addr assignment helpers") + */ +#ifdef NEED_ETH_HW_ADDR_SET +static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr) +{ + ether_addr_copy(dev->dev_addr, addr); +} +#endif /* NEED_ETH_HW_ADDR_SET */ + +#ifdef NEED_ETH_GET_HEADLEN +/* This is missing on pre 3.18 kernels, most notably on 3.10 used for ESX + * certification. + */ + +/* include headers needed for get_headlen function */ +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) +#include +#endif +#ifdef HAVE_SCTP +#include +#endif +u32 eth_get_headlen(unsigned char *data, unsigned int max_len) +{ + union { + unsigned char *network; + /* l2 headers */ + struct ethhdr *eth; + struct vlan_hdr *vlan; + /* l3 headers */ + struct iphdr *ipv4; + struct ipv6hdr *ipv6; + } hdr; + __be16 proto; + u8 nexthdr = 0; /* default to not TCP */ + u8 hlen; + + /* this should never happen, but better safe than sorry */ + if (max_len < ETH_HLEN) + return max_len; + + /* initialize network frame pointer */ + hdr.network = data; + + /* set first protocol and move network header forward */ + proto = hdr.eth->h_proto; + hdr.network += ETH_HLEN; + +again: + switch (proto) { + /* handle any vlan tag if present */ + case __constant_htons(ETH_P_8021AD): + case __constant_htons(ETH_P_8021Q): + if ((hdr.network - data) > (max_len - VLAN_HLEN)) + return max_len; + + proto = hdr.vlan->h_vlan_encapsulated_proto; + hdr.network += VLAN_HLEN; + goto again; + /* handle L3 protocols */ + case __constant_htons(ETH_P_IP): + if ((hdr.network - data) > (max_len - sizeof(struct iphdr))) + return max_len; + + /* access ihl as a u8 to avoid unaligned access on ia64 */ + hlen = (hdr.network[0] & 0x0F) << 2; + + /* verify hlen meets minimum size requirements */ + if (hlen < sizeof(struct iphdr)) + return hdr.network - data; + + /* record next protocol if header is present */ + if (!(hdr.ipv4->frag_off & htons(IP_OFFSET))) + nexthdr = hdr.ipv4->protocol; + + hdr.network += hlen; + break; +#ifdef NETIF_F_TSO6 + case __constant_htons(ETH_P_IPV6): + if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr))) + return max_len; + + /* record next protocol */ + nexthdr = hdr.ipv6->nexthdr; + hdr.network += sizeof(struct ipv6hdr); + break; +#endif /* NETIF_F_TSO6 */ +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + case __constant_htons(ETH_P_FCOE): + hdr.network += FCOE_HEADER_LEN; + break; +#endif + default: + return hdr.network - data; + } + + /* finally sort out L4 */ + switch (nexthdr) { + case IPPROTO_TCP: + if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) + return max_len; + + /* access doff as a u8 to avoid unaligned access on ia64 */ + hdr.network += max_t(u8, sizeof(struct tcphdr), + (hdr.network[12] & 0xF0) >> 2); + + break; + case IPPROTO_UDP: + case IPPROTO_UDPLITE: + hdr.network += sizeof(struct udphdr); + break; +#ifdef HAVE_SCTP + case IPPROTO_SCTP: + hdr.network += sizeof(struct sctphdr); + break; +#endif + } + + /* + * If everything has gone correctly hdr.network should be the + * data section of the packet and will be the end of the header. + * If not then it probably represents the end of the last recognized + * header. + */ + return min_t(unsigned int, hdr.network - data, max_len); +} +#endif /* NEED_ETH_GET_HEADLEN */ + +/* NEED_ETH_GET_HEADLEN_NET_DEVICE_ARG + * + * + * eth_get_headlen was modified by upstream commit + * 59753ce8b196 ("ethernet: constify eth_get_headlen()'s data argument") + * c43f1255b866 ("net: pass net_device argument to the eth_get_headlen") + * + * This allows core driver code to simply call eth_get_headlen with all + * 3 parameters, and have kcompat automatically drop it depending on what + * the kernel supports. + + * For kernels older than 3.18, eth_get_headlen didn't exist. + */ + +#ifdef NEED_ETH_GET_HEADLEN_NET_DEVICE_ARG +static inline u32 +__kc_eth_get_headlen(const struct net_device __always_unused *dev, + void *data, unsigned int len) +{ + return eth_get_headlen(data, len); +} + +#define eth_get_headlen(dev, data, len) __kc_eth_get_headlen(dev, data, len) +#endif /* NEED_ETH_GET_HEADLEN_NET_DEVICE_ARG */ + +#ifdef NEED_JIFFIES_64_TIME_IS_MACROS +/* NEED_JIFFIES_64_TIME_IS_MACROS + * + * The jiffies64 time_is_* macros were introduced upstream by 3740dcdf8a77 + * ("jiffies: add time comparison functions for 64 bit jiffies") in Linux 4.9. + * + * Support for 64-bit jiffies has been available since the initial import of + * Linux into git in 2005, so its safe to just implement the macros as-is + * here. + */ +#define time_is_before_jiffies64(a) time_after64(get_jiffies_64(), a) +#define time_is_after_jiffies64(a) time_before64(get_jiffies_64(), a) +#define time_is_before_eq_jiffies64(a) time_after_eq64(get_jiffies_64(), a) +#define time_is_after_eq_jiffies64(a) time_before_eq64(get_jiffies_64(), a) +#endif /* NEED_JIFFIES_64_TIME_IS_MACROS */ + +#ifdef NEED_INDIRECT_CALL_WRAPPER_MACROS +/* NEED_INDIRECT_CALL_WRAPPER_MACROS + * + * The INDIRECT_CALL_* macros were introduced upstream as upstream commit + * 283c16a2dfd3 ("indirect call wrappers: helpers to speed-up indirect calls + * of builtin") which landed in Linux 5.0 + * + * These are easy to implement directly. + */ +#ifdef CONFIG_RETPOLINE +#define INDIRECT_CALL_1(f, f1, ...) \ + ({ \ + likely(f == f1) ? f1(__VA_ARGS__) : f(__VA_ARGS__); \ + }) +#define INDIRECT_CALL_2(f, f2, f1, ...) \ + ({ \ + likely(f == f2) ? f2(__VA_ARGS__) : \ + INDIRECT_CALL_1(f, f1, __VA_ARGS__); \ + }) + +#define INDIRECT_CALLABLE_DECLARE(f) f +#define INDIRECT_CALLABLE_SCOPE +#else /* !CONFIG_RETPOLINE */ +#define INDIRECT_CALL_1(f, f1, ...) f(__VA_ARGS__) +#define INDIRECT_CALL_2(f, f2, f1, ...) f(__VA_ARGS__) +#define INDIRECT_CALLABLE_DECLARE(f) +#define INDIRECT_CALLABLE_SCOPE static +#endif /* CONFIG_RETPOLINE */ +#endif /* NEED_INDIRECT_CALL_WRAPPER_MACROS */ + +#ifdef NEED_INDIRECT_CALL_3_AND_4 +/* NEED_INDIRECT_CALL_3_AND_4 + * Support for the 3 and 4 call variants was added in upstream commit + * e678e9ddea96 ("indirect_call_wrapper: extend indirect wrapper to support up + * to 4 calls") + * + * These are easy to implement directly. + */ + +#ifdef CONFIG_RETPOLINE +#define INDIRECT_CALL_3(f, f3, f2, f1, ...) \ + ({ \ + likely(f == f3) ? f3(__VA_ARGS__) : \ + INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__); \ + }) +#define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...) \ + ({ \ + likely(f == f4) ? f4(__VA_ARGS__) : \ + INDIRECT_CALL_3(f, f3, f2, f1, __VA_ARGS__); \ + }) +#else /* !CONFIG_RETPOLINE */ +#define INDIRECT_CALL_3(f, f3, f2, f1, ...) f(__VA_ARGS__) +#define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...) f(__VA_ARGS__) +#endif /* CONFIG_RETPOLINE */ +#endif /* NEED_INDIRECT_CALL_3_AND_4 */ + +#ifdef NEED_EXPORT_INDIRECT_CALLABLE +/* NEED_EXPORT_INDIRECT_CALLABLE + * + * Support for EXPORT_INDIRECT_CALLABLE was added in upstream commit + * 0053859496ba ("net: add EXPORT_INDIRECT_CALLABLE wrapper") + * + * These are easy to implement directly. + */ +#ifdef CONFIG_RETPOLINE +#define EXPORT_INDIRECT_CALLABLE(f) EXPORT_SYMBOL(f) +#else +#define EXPORT_INDIRECT_CALLABLE(f) +#endif /* CONFIG_RETPOLINE */ +#endif /* NEED_EXPORT_INDIRECT_CALLABLE */ + +/* NEED_DEVM_KASPRINTF and NEED_DEVM_KVASPRINTF + * + * devm_kvasprintf and devm_kasprintf were added by commit + * 75f2a4ead5d5 ("devres: Add devm_kasprintf and devm_kvasprintf API") + * in Linux 3.17. + */ +#ifdef NEED_DEVM_KVASPRINTF +__printf(3, 0) char *devm_kvasprintf(struct device *dev, gfp_t gfp, + const char *fmt, va_list ap); +#endif /* NEED_DEVM_KVASPRINTF */ + +#ifdef NEED_DEVM_KASPRINTF +__printf(3, 4) char *devm_kasprintf(struct device *dev, gfp_t gfp, + const char *fmt, ...); +#endif /* NEED_DEVM_KASPRINTF */ + +#ifdef NEED_XSK_UMEM_GET_RX_FRAME_SIZE +#ifdef HAVE_AF_XDP_ZC_SUPPORT +#ifndef xsk_umem_get_rx_frame_size +static inline u32 _xsk_umem_get_rx_frame_size(struct xdp_umem *umem) +{ + return umem->chunk_size_nohr - XDP_PACKET_HEADROOM; +} + +#define xsk_umem_get_rx_frame_size _xsk_umem_get_rx_frame_size +#endif /* xsk_umem_get_rx_frame_size */ +#endif /* HAVE_AF_XDP_ZC_SUPPORT */ +#endif + +#ifdef NEED_XSK_BUFF_POOL_RENAME +#define XDP_SETUP_XSK_POOL XDP_SETUP_XSK_UMEM +#define xsk_get_pool_from_qid xdp_get_umem_from_qid +#define xsk_pool_get_rx_frame_size xsk_umem_get_rx_frame_size +#define xsk_pool_set_rxq_info xsk_buff_set_rxq_info +#define xsk_pool_dma_unmap xsk_buff_dma_unmap +#define xsk_pool_dma_map xsk_buff_dma_map +#define xsk_tx_peek_desc xsk_umem_consume_tx +#define xsk_tx_release xsk_umem_consume_tx_done +#define xsk_tx_completed xsk_umem_complete_tx +#define xsk_uses_need_wakeup xsk_umem_uses_need_wakeup +#endif /* NEED_XSK_BUFF_POOL_RENAME */ + +#ifdef NEED_PCI_IOV_VF_ID +/* NEED_PCI_IOV_VF_ID + * + * pci_iov_vf_id were added by commit 21ca9fb62d468 ("PCI/IOV: + * Add pci_iov_vf_id() to get VF index") in Linux 5.18 + */ +int _kc_pci_iov_vf_id(struct pci_dev *dev); +#define pci_iov_vf_id _kc_pci_iov_vf_id +#endif /* NEED_PCI_IOV_VF_ID */ + +/* NEED_MUL_U64_U64_DIV_U64 + * + * mul_u64_u64_div_u64 was introduced in Linux 5.9 as part of commit + * 3dc167ba5729 ("sched/cputime: Improve cputime_adjust()") + */ +#ifdef NEED_MUL_U64_U64_DIV_U64 +u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div); +#endif /* NEED_MUL_U64_U64_DIV_U64 */ + +/* NEED_ROUNDUP_U64 and NEED_DIV_U64_ROUND_UP and NEED_DIV_U64_ROUND_CLOSEST + * + * roundup_u64 and DIV_U64_FOUND_UP were introduced by commit 1d4ce389da2b + * ("ice: add and use roundup_u64 instead of open coding equivalent"). They + * are straight forward to re-implement here. + */ +#ifdef NEED_DIV_U64_ROUND_UP +#define DIV_U64_ROUND_UP(ll, d) \ + ({ u32 _tmp = (d); div_u64((ll) + _tmp - 1, _tmp); }) +#endif /* NEED_DIV_U64_ROUND_UP */ + +#ifdef NEED_ROUNDUP_U64 +static inline u64 roundup_u64(u64 x, u32 y) +{ + return DIV_U64_ROUND_UP(x, y) * y; +} +#endif /* NEED_ROUNDUP_U64 */ + +#ifdef NEED_DIV_U64_ROUND_CLOSEST +#define DIV_U64_ROUND_CLOSEST(dividend, divisor) \ + ({ u32 _tmp = (divisor); div_u64((u64)(dividend) + _tmp / 2, _tmp); }) +#endif /* NEED_DIV_U64_ROUND_CLOSEST */ + +#ifdef NEED_LINKMODE_ZERO +static inline void linkmode_zero(unsigned long *dst) +{ + bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + +static inline void linkmode_copy(unsigned long *dst, const unsigned long *src) +{ + bitmap_copy(dst, src, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + +static inline void linkmode_and(unsigned long *dst, const unsigned long *a, + const unsigned long *b) +{ + bitmap_and(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + +static inline void linkmode_or(unsigned long *dst, const unsigned long *a, + const unsigned long *b) +{ + bitmap_or(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + +static inline bool linkmode_empty(const unsigned long *src) +{ + return bitmap_empty(src, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + +static inline int linkmode_andnot(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2) +{ + return bitmap_andnot(dst, src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + +static inline void linkmode_set_bit(int nr, volatile unsigned long *addr) +{ + __set_bit(nr, addr); +} + +static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr) +{ + __clear_bit(nr, addr); +} + +static inline void linkmode_change_bit(int nr, volatile unsigned long *addr) +{ + __change_bit(nr, addr); +} + +static inline int linkmode_test_bit(int nr, volatile unsigned long *addr) +{ + return test_bit(nr, addr); +} + +static inline int linkmode_equal(const unsigned long *src1, + const unsigned long *src2) +{ + return bitmap_equal(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS); +} +#else /* !NEED_LINKMODE_ZERO */ +#include +#endif /* NEED_LINKMODE_ZERO */ + +#ifdef NEED_LINKMODE_SET_BIT_ARRAY +static inline void linkmode_set_bit_array(const int *array, int array_size, + unsigned long *addr) +{ + int i; + + for (i = 0; i < array_size; i++) + linkmode_set_bit(array[i], addr); +} +#endif /* NEED_LINKMODE_SET_BIT_ARRAY */ + +#ifdef NEED_ETHTOOL_LINK_MODE_BIT_INDICES +/* Link mode bit indices */ +enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0, + ETHTOOL_LINK_MODE_10baseT_Full_BIT = 1, + ETHTOOL_LINK_MODE_100baseT_Half_BIT = 2, + ETHTOOL_LINK_MODE_100baseT_Full_BIT = 3, + ETHTOOL_LINK_MODE_1000baseT_Half_BIT = 4, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT = 5, + ETHTOOL_LINK_MODE_Autoneg_BIT = 6, + ETHTOOL_LINK_MODE_TP_BIT = 7, + ETHTOOL_LINK_MODE_AUI_BIT = 8, + ETHTOOL_LINK_MODE_MII_BIT = 9, + ETHTOOL_LINK_MODE_FIBRE_BIT = 10, + ETHTOOL_LINK_MODE_BNC_BIT = 11, + ETHTOOL_LINK_MODE_10000baseT_Full_BIT = 12, + ETHTOOL_LINK_MODE_Pause_BIT = 13, + ETHTOOL_LINK_MODE_Asym_Pause_BIT = 14, + ETHTOOL_LINK_MODE_2500baseX_Full_BIT = 15, + ETHTOOL_LINK_MODE_Backplane_BIT = 16, + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT = 17, + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT = 18, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT = 19, + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT = 20, + ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT = 21, + ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT = 22, + ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT = 23, + ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT = 24, + ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT = 25, + ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT = 26, + ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT = 27, + ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT = 28, + ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT = 29, + ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT = 30, +#ifdef ETHTOOL_GLINKSETTINGS + ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 31, + ETHTOOL_LINK_MODE_25000baseKR_Full_BIT = 32, + ETHTOOL_LINK_MODE_25000baseSR_Full_BIT = 33, + ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT = 34, + ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT = 35, + ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT = 36, + ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT = 37, + ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT = 38, + ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 39, + ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT = 40, + ETHTOOL_LINK_MODE_1000baseX_Full_BIT = 41, + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT = 42, + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT = 43, + ETHTOOL_LINK_MODE_10000baseLR_Full_BIT = 44, + ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT = 45, + ETHTOOL_LINK_MODE_10000baseER_Full_BIT = 46, + ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47, + ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48, + + ETHTOOL_LINK_MODE_FEC_NONE_BIT = 49, + ETHTOOL_LINK_MODE_FEC_RS_BIT = 50, + ETHTOOL_LINK_MODE_FEC_BASER_BIT = 51, + + __ETHTOOL_LINK_MODE_LAST + = ETHTOOL_LINK_MODE_FEC_BASER_BIT, +#else + + /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit + * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_* + * macro for bits > 31. The only way to use indices > 31 is to + * use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. + */ + + __ETHTOOL_LINK_MODE_LAST + = ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, +#endif /* !ETHTOOL_GLINKSETTINGS */ +}; +#endif /* NEED_ETHTOOL_LINK_MODE_BIT_INDICES */ + +#if defined(NEED_FLOW_MATCH) && defined(HAVE_TC_SETUP_CLSFLOWER) +/* NEED_FLOW_MATCH + * + * flow_match*, FLOW_DISSECTOR_MATCH, flow_rule*, flow_rule_match_key, and + * tc_cls_flower_offload_flow_rule were added by commit + * 8f2566225ae2 ("flow_offload: add flow_rule and flow_match structures and use + * them") in Linux 5.1. + */ + +#include + +struct flow_match { + struct flow_dissector *dissector; + void *mask; + void *key; +}; + +struct flow_match_basic { + struct flow_dissector_key_basic *key, *mask; +}; + +struct flow_match_control { + struct flow_dissector_key_control *key, *mask; +}; + +struct flow_match_eth_addrs { + struct flow_dissector_key_eth_addrs *key, *mask; +}; + +#ifndef HAVE_TC_FLOWER_VLAN_IN_TAGS +struct flow_match_vlan { + struct flow_dissector_key_vlan *key, *mask; +}; +#endif /* HAVE_TC_FLOWER_VLAN_IN_TAGS */ + +struct flow_match_ipv4_addrs { + struct flow_dissector_key_ipv4_addrs *key, *mask; +}; + +struct flow_match_ipv6_addrs { + struct flow_dissector_key_ipv6_addrs *key, *mask; +}; + +#ifdef HAVE_FLOW_DISSECTOR_KEY_IP +struct flow_match_ip { + struct flow_dissector_key_ip *key, *mask; +}; +#endif /* HAVE_FLOW_DISSECTOR_KEY_IP */ + +struct flow_match_ports { + struct flow_dissector_key_ports *key, *mask; +}; + +#ifdef HAVE_TC_FLOWER_ENC +struct flow_match_enc_keyid { + struct flow_dissector_key_keyid *key, *mask; +}; +#endif /* HAVE_TC_FLOWER_ENC */ + +struct flow_rule { + struct flow_match match; +#if 0 + /* In 5.1+ kernels, action is a member of struct flow_rule but is + * not compatible with how we kcompat tc_cls_flower_offload_flow_rule + * below. By not declaring it here, any driver that attempts to use + * action as an element of struct flow_rule will fail to compile + * instead of silently trying to access memory that shouldn't be. + */ + struct flow_action action; +#endif +}; + +static inline struct flow_rule * +tc_cls_flower_offload_flow_rule(struct tc_cls_flower_offload *tc_flow_cmd) +{ + return (struct flow_rule *)&tc_flow_cmd->dissector; +} + +static inline bool flow_rule_match_key(const struct flow_rule *rule, + enum flow_dissector_key_id key) +{ + return dissector_uses_key(rule->match.dissector, key); +} + +#define FLOW_DISSECTOR_MATCH(__rule, __type, __out) \ + const struct flow_match *__m = &(__rule)->match; \ + struct flow_dissector *__d = (__m)->dissector; \ + \ + (__out)->key = skb_flow_dissector_target(__d, __type, (__m)->key); \ + (__out)->mask = skb_flow_dissector_target(__d, __type, (__m)->mask); \ + +static inline void +flow_rule_match_basic(const struct flow_rule *rule, + struct flow_match_basic *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_BASIC, out); +} + +static inline void +flow_rule_match_control(const struct flow_rule *rule, + struct flow_match_control *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_CONTROL, out); +} + +static inline void +flow_rule_match_eth_addrs(const struct flow_rule *rule, + struct flow_match_eth_addrs *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS, out); +} + +#ifndef HAVE_TC_FLOWER_VLAN_IN_TAGS +static inline void +flow_rule_match_vlan(const struct flow_rule *rule, struct flow_match_vlan *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_VLAN, out); +} +#endif /* HAVE_TC_FLOWER_VLAN_IN_TAGS */ + +static inline void +flow_rule_match_ipv4_addrs(const struct flow_rule *rule, + struct flow_match_ipv4_addrs *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS, out); +} + +static inline void +flow_rule_match_ipv6_addrs(const struct flow_rule *rule, + struct flow_match_ipv6_addrs *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS, out); +} + +#ifdef HAVE_FLOW_DISSECTOR_KEY_IP +static inline void +flow_rule_match_ip(const struct flow_rule *rule, struct flow_match_ip *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_IP, out); +} +#endif /* HAVE_FLOW_DISSECTOR_KEY_IP */ + +static inline void +flow_rule_match_ports(const struct flow_rule *rule, + struct flow_match_ports *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_PORTS, out); +} + +#ifdef HAVE_TC_FLOWER_ENC +static inline void +flow_rule_match_enc_control(const struct flow_rule *rule, + struct flow_match_control *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_CONTROL, out); +} + +static inline void +flow_rule_match_enc_ipv4_addrs(const struct flow_rule *rule, + struct flow_match_ipv4_addrs *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, out); +} + +static inline void +flow_rule_match_enc_ipv6_addrs(const struct flow_rule *rule, + struct flow_match_ipv6_addrs *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, out); +} + +#ifdef HAVE_FLOW_DISSECTOR_KEY_IP +#ifdef HAVE_FLOW_DISSECTOR_KEY_ENC_IP +static inline void +flow_rule_match_enc_ip(const struct flow_rule *rule, struct flow_match_ip *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_IP, out); +} +#endif /* HAVE_FLOW_DISSECTOR_KEY_ENC_IP */ +#endif /* HAVE_FLOW_DISSECTOR_KEY_IP */ + +static inline void +flow_rule_match_enc_ports(const struct flow_rule *rule, + struct flow_match_ports *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_PORTS, out); +} + +static inline void +flow_rule_match_enc_keyid(const struct flow_rule *rule, + struct flow_match_enc_keyid *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_KEYID, out); +} +#endif /* HAVE_TC_FLOWER_ENC */ +#endif /* NEED_FLOW_MATCH && HAVE_TC_SETUP_CLSFLOWER */ + +/* bitfield / bitmap */ + +/* NEED_BITMAP_COPY_CLEAR_TAIL + * + * backport + * c724f193619c ("bitmap: new bitmap_copy_safe and bitmap_{from,to}_arr32") + */ +#ifdef NEED_BITMAP_COPY_CLEAR_TAIL +/* Copy bitmap and clear tail bits in last word */ +static inline void +bitmap_copy_clear_tail(unsigned long *dst, const unsigned long *src, unsigned int nbits) +{ + bitmap_copy(dst, src, nbits); + if (nbits % BITS_PER_LONG) + dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits); +} +#endif /* NEED_BITMAP_COPY_CLEAR_TAIL */ + +/* NEED_BITMAP_FROM_ARR32 + * + * backport + * c724f193619c ("bitmap: new bitmap_copy_safe and bitmap_{from,to}_arr32") + */ +#ifdef NEED_BITMAP_FROM_ARR32 +#if BITS_PER_LONG == 64 +/** + * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap + * @bitmap: array of unsigned longs, the destination bitmap + * @buf: array of u32 (in host byte order), the source bitmap + * @nbits: number of bits in @bitmap + */ +static inline void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf, + unsigned int nbits) +{ + unsigned int i, halfwords; + + halfwords = DIV_ROUND_UP(nbits, 32); + for (i = 0; i < halfwords; i++) { + bitmap[i/2] = (unsigned long) buf[i]; + if (++i < halfwords) + bitmap[i/2] |= ((unsigned long) buf[i]) << 32; + } + + /* Clear tail bits in last word beyond nbits. */ + if (nbits % BITS_PER_LONG) + bitmap[(halfwords - 1) / 2] &= BITMAP_LAST_WORD_MASK(nbits); +} +#else /* BITS_PER_LONG == 64 */ +/* + * On 32-bit systems bitmaps are represented as u32 arrays internally, and + * therefore conversion is not needed when copying data from/to arrays of u32. + */ +#define bitmap_from_arr32(bitmap, buf, nbits) \ + bitmap_copy_clear_tail((unsigned long *) (bitmap), \ + (const unsigned long *) (buf), (nbits)) +#endif /* BITS_PER_LONG == 64 */ +#endif /* NEED_BITMAP_FROM_ARR32 */ + +/* NEED_BITMAP_TO_ARR32 + * + * backport + * c724f193619c ("bitmap: new bitmap_copy_safe and bitmap_{from,to}_arr32") + */ +#ifdef NEED_BITMAP_TO_ARR32 +#if BITS_PER_LONG == 64 +/** + * bitmap_to_arr32 - copy the contents of bitmap to a u32 array of bits + * @buf: array of u32 (in host byte order), the dest bitmap + * @bitmap: array of unsigned longs, the source bitmap + * @nbits: number of bits in @bitmap + */ +static inline void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, + unsigned int nbits) +{ + unsigned int i, halfwords; + + halfwords = DIV_ROUND_UP(nbits, 32); + for (i = 0; i < halfwords; i++) { + buf[i] = (u32) (bitmap[i/2] & UINT_MAX); + if (++i < halfwords) + buf[i] = (u32) (bitmap[i/2] >> 32); + } + + /* Clear tail bits in last element of array beyond nbits. */ + if (nbits % BITS_PER_LONG) + buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31)); +} +#else +/* + * On 32-bit systems bitmaps are represented as u32 arrays internally, and + * therefore conversion is not needed when copying data from/to arrays of u32. + */ +#define bitmap_to_arr32(buf, bitmap, nbits) \ + bitmap_copy_clear_tail((unsigned long *) (buf), \ + (const unsigned long *) (bitmap), (nbits)) +#endif /* BITS_PER_LONG == 64 */ +#endif /* NEED_BITMAP_TO_ARR32 */ + +#ifndef HAVE_INCLUDE_BITFIELD +/* linux/bitfield.h has been added in Linux 4.9 in upstream commit + * 3e9b3112ec74 ("add basic register-field manipulation macros") + */ +#define __bf_shf(x) (__builtin_ffsll(x) - 1) + +#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ + ({ \ + BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ + _pfx "mask is not constant"); \ + BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ + BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ + ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ + _pfx "value too large for the field"); \ + BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ + _pfx "type of reg too small for mask"); \ + __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ + (1ULL << __bf_shf(_mask))); \ + }) + +/** + * FIELD_PREP() - prepare a bitfield element + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP() masks and shifts up the value. The result should + * be combined with other fields of the bitfield using logical OR. + */ +#define FIELD_PREP(_mask, _val) \ + ({ \ + __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ + ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ + }) + +/** + * FIELD_GET() - extract a bitfield element + * @_mask: shifted mask defining the field's length and position + * @_reg: value of entire bitfield + * + * FIELD_GET() extracts the field specified by @_mask from the + * bitfield passed in as @_reg by masking and shifting it down. + */ +#define FIELD_GET(_mask, _reg) \ + ({ \ + __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ + (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ + }) +#endif /* HAVE_INCLUDE_BITFIELD */ + +#ifdef NEED_BITFIELD_FIELD_MAX +/* linux/bitfield.h has FIELD_MAX added to it in Linux 5.7 in upstream + * commit e31a50162feb ("bitfield.h: add FIELD_MAX() and field_max()") + */ +/** + * FIELD_MAX() - produce the maximum value representable by a field + * @_mask: shifted mask defining the field's length and position + * + * FIELD_MAX() returns the maximum value that can be held in the field + * specified by @_mask. + */ +#define FIELD_MAX(_mask) \ + ({ \ + __BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_MAX: "); \ + (typeof(_mask))((_mask) >> __bf_shf(_mask)); \ + }) +#endif /* HAVE_BITFIELD_FIELD_MAX */ + +#ifdef NEED_BITFIELD_FIELD_FIT +/** + * FIELD_FIT() - check if value fits in the field + * @_mask: shifted mask defining the field's length and position + * @_val: value to test against the field + * + * Return: true if @_val can fit inside @_mask, false if @_val is too big. + */ +#define FIELD_FIT(_mask, _val) \ + ({ \ + __BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_FIT: "); \ + !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ + }) +#endif /* NEED_BITFIELD_FIELD_FIT */ + +#ifdef NEED_BITFIELD_FIELD_MASK +/** + * linux/bitfield.h has field_mask() along with *_encode_bits() in 4.16: + * 00b0c9b82663 ("Add primitives for manipulating bitfields both in host and fixed-endian.") + * + */ +extern void __compiletime_error("value doesn't fit into mask") +__field_overflow(void); +extern void __compiletime_error("bad bitfield mask") +__bad_mask(void); +static __always_inline u64 field_multiplier(u64 field) +{ + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) + __bad_mask(); + return field & -field; +} +static __always_inline u64 field_mask(u64 field) +{ + return field / field_multiplier(field); +} +#define ____MAKE_OP(type,base,to,from) \ +static __always_inline __##type type##_encode_bits(base v, base field) \ +{ \ + if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ + __field_overflow(); \ + return to((v & field_mask(field)) * field_multiplier(field)); \ +} \ +static __always_inline __##type type##_replace_bits(__##type old, \ + base val, base field) \ +{ \ + return (old & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline void type##p_replace_bits(__##type *p, \ + base val, base field) \ +{ \ + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline base type##_get_bits(__##type v, base field) \ +{ \ + return (from(v) & field)/field_multiplier(field); \ +} +#define __MAKE_OP(size) \ + ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \ + ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \ + ____MAKE_OP(u##size,u##size,,) +__MAKE_OP(16) +__MAKE_OP(32) +__MAKE_OP(64) +#undef __MAKE_OP +#undef ____MAKE_OP +#endif + +#ifdef NEED_BUILD_BUG_ON +/* Force a compilation error if a constant expression is not a power of 2 */ +#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \ + BUILD_BUG_ON(((n) & ((n) - 1)) != 0) + +/** + * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied + * error message. + * @condition: the condition which the compiler should know is false. + * + * See BUILD_BUG_ON for description. + */ +#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) + +/** + * BUILD_BUG_ON - break compile if a condition is true. + * @condition: the condition which the compiler should know is false. + * + * If you have some code which relies on certain constants being equal, or + * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to + * detect if someone changes it. + */ +#define BUILD_BUG_ON(condition) \ + BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) +#endif /* NEED_BUILD_BUG_ON */ + +#ifdef NEED_IN_TASK +#define in_hardirq() (hardirq_count()) +#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) +#define in_task() (!(in_nmi() | in_hardirq() | \ + in_serving_softirq())) +#endif /* NEED_IN_TASK */ + +/* + * NEED_NETIF_NAPI_ADD_NO_WEIGHT + * + * Upstream commit b48b89f9c189 ("net: drop the weight argument from + * netif_napi_add") removes weight argument from function call. + * + * Our drivers always used default weight, which is 64. + * + * Define NEED_NETIF_NAPI_ADD_NO_WEIGHT on kernels 3.10+ to use old + * implementation. Undef for 6.1+ where new function was introduced. + * RedHat 9.2 required using no weight parameter option. + */ +#ifdef NEED_NETIF_NAPI_ADD_NO_WEIGHT +static inline void +_kc_netif_napi_add(struct net_device *dev, struct napi_struct *napi, + int (*poll)(struct napi_struct *, int)) +{ + return netif_napi_add(dev, napi, poll, NAPI_POLL_WEIGHT); +} + +/* RHEL7 complains about redefines. Undef first, then define compat wrapper */ +#ifdef netif_napi_add +#undef netif_napi_add +#endif +#define netif_napi_add _kc_netif_napi_add +#endif /* NEED_NETIF_NAPI_ADD_NO_WEIGHT */ + +/* + * NEED_ETHTOOL_SPRINTF + * + * Upstream commit 7888fe53b706 ("ethtool: Add common function for filling out + * strings") introduced ethtool_sprintf, which landed in Linux v5.13 + * + * The function implementation is moved to kcompat.c since the compiler + * complains it can never be inlined for the function with variable argument + * lists. + */ +#ifdef NEED_ETHTOOL_SPRINTF +__printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...); +#endif /* NEED_ETHTOOL_SPRINTF */ + +/* + * NEED_SYSFS_MATCH_STRING + * + * Upstream commit e1fe7b6a7b37 ("lib/string: add sysfs_match_string helper") + * introduced a helper for looking up strings in an array - it's pure algo stuff + * that is easy to backport if needed. + * Instead of covering sysfs_streq() by yet another flag just copy it. + */ +#ifdef NEED_SYSFS_MATCH_STRING +/* + * sysfs_streq - return true if strings are equal, modulo trailing newline + * @s1: one string + * @s2: another string + * + * This routine returns true iff two strings are equal, treating both + * NUL and newline-then-NUL as equivalent string terminations. It's + * geared for use with sysfs input strings, which generally terminate + * with newlines but are compared against values without newlines. + */ +static inline bool _kc_sysfs_streq(const char *s1, const char *s2) +{ + while (*s1 && *s1 == *s2) { + s1++; + s2++; + } + + if (*s1 == *s2) + return true; + if (!*s1 && *s2 == '\n' && !s2[1]) + return true; + if (*s1 == '\n' && !s1[1] && !*s2) + return true; + return false; +} + +/* + * __sysfs_match_string - matches given string in an array + * @array: array of strings + * @n: number of strings in the array or -1 for NULL terminated arrays + * @str: string to match with + * + * Returns index of @str in the @array or -EINVAL, just like match_string(). + * Uses sysfs_streq instead of strcmp for matching. + * + * This routine will look for a string in an array of strings up to the + * n-th element in the array or until the first NULL element. + * + * Historically the value of -1 for @n, was used to search in arrays that + * are NULL terminated. However, the function does not make a distinction + * when finishing the search: either @n elements have been compared OR + * the first NULL element was found. + */ +static inline int _kc___sysfs_match_string(const char * const *array, size_t n, + const char *str) +{ + const char *item; + int index; + + for (index = 0; index < n; index++) { + item = array[index]; + if (!item) + break; + if (sysfs_streq(item, str)) + return index; + } + + return -EINVAL; +} + +#define sysfs_match_string(_a, _s) \ + _kc___sysfs_match_string(_a, ARRAY_SIZE(_a), _s) + +#endif /* NEED_SYSFS_MATCH_STRING */ + +/* + * NEED_SYSFS_EMIT + * + * Upstream introduced following function in + * commit 2efc459d06f1 ("sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output") + * + * The function implementation is moved to kcompat.c since the compiler + * complains it can never be inlined for the function with variable argument + * lists. + */ +#ifdef NEED_SYSFS_EMIT +__printf(2, 3) int sysfs_emit(char *buf, const char *fmt, ...); +#endif /* NEED_SYSFS_EMIT */ + +/* + * HAVE_U64_STATS_FETCH_BEGIN_IRQ + * HAVE_U64_STATS_FETCH_RETRY_IRQ + * + * Upstream commit 44b0c2957adc ("u64_stats: Streamline the implementation") + * marks u64_stats_fetch_begin_irq() and u64_stats_fetch_retry_irq() + * as obsolete. Their functionality is combined with: u64_stats_fetch_begin() + * and u64_stats_fetch_retry(). + * + * Upstream commit dec5efcffad4 ("u64_stat: Remove the obsolete fetch_irq() + * variants.") removes u64_stats_fetch_begin_irq() and + * u64_stats_fetch_retry_irq(). + * + * Map u64_stats_fetch_begin() and u64_stats_fetch_retry() to the _irq() + * variants on the older kernels to allow the same driver code working on + * both old and new kernels. + */ +#ifdef HAVE_U64_STATS_FETCH_BEGIN_IRQ +#define u64_stats_fetch_begin _kc_u64_stats_fetch_begin + +static inline unsigned int +_kc_u64_stats_fetch_begin(const struct u64_stats_sync *syncp) +{ + return u64_stats_fetch_begin_irq(syncp); +} +#endif /* HAVE_U64_STATS_FETCH_BEGIN_IRQ */ + +#ifdef HAVE_U64_STATS_FETCH_RETRY_IRQ +#define u64_stats_fetch_retry _kc_u64_stats_fetch_retry + +static inline bool +_kc_u64_stats_fetch_retry(const struct u64_stats_sync *syncp, + unsigned int start) +{ + return u64_stats_fetch_retry_irq(syncp, start); +} +#endif /* HAVE_U64_STATS_FETCH_RETRY_IRQ */ + +/* + * NEED_U64_STATS_READ + * NEED_U64_STATS_SET + * + * Upstream commit 316580b69d0 ("u64_stats: provide u64_stats_t type") + * introduces the u64_stats_t data type and other helper APIs to read, + * add and increment the stats, in Linux v5.5. Support them on older kernels + * as well. + * + * Upstream commit f2efdb179289 ("u64_stats: Introduce u64_stats_set()") + * introduces u64_stats_set API to set the u64_stats_t variable with the + * value provided, in Linux v5.16. Add support for older kernels. + */ +#ifdef NEED_U64_STATS_READ +#if BITS_PER_LONG == 64 +#include + +typedef struct { + local64_t v; +} u64_stats_t; + +static inline u64 u64_stats_read(u64_stats_t *p) +{ + return local64_read(&p->v); +} + +static inline void u64_stats_add(u64_stats_t *p, unsigned long val) +{ + local64_add(val, &p->v); +} + +static inline void u64_stats_inc(u64_stats_t *p) +{ + local64_inc(&p->v); +} +#else +typedef struct { + u64 v; +} u64_stats_t; + +static inline u64 u64_stats_read(u64_stats_t *p) +{ + return p->v; +} + +static inline void u64_stats_add(u64_stats_t *p, unsigned long val) +{ + p->v += val; +} + +static inline void u64_stats_inc(u64_stats_t *p) +{ + p->v++; +} +#endif /* BITS_PER_LONG == 64 */ +#endif /* NEED_U64_STATS_READ */ + +#ifdef NEED_U64_STATS_SET +#if BITS_PER_LONG == 64 +static inline void u64_stats_set(u64_stats_t *p, u64 val) +{ + local64_set(&p->v, val); +} +#else +static inline void u64_stats_set(u64_stats_t *p, u64 val) +{ + p->v = val; +} +#endif /* BITS_PER_LONG == 64 */ +#endif /* NEED_U64_STATS_SET */ + +/* + * NEED_DEVM_KFREE + * NEED_DEVM_KZALLOC + * + * Upstream commit 9ac7849e35f7 ("devres: device resource management") + * Implement device resource management to allocate and free the resource + * for driver + */ +#ifdef NEED_DEVM_KFREE +#define devm_kfree(dev, p) kfree(p) +#else +/* Since commit 0571967dfb5d ("devres: constify p in devm_kfree()") the + * devm_kfree function has accepted a const void * parameter. Since commit + * cad064f1bd52 ("devres: handle zero size in devm_kmalloc()"), it has also + * accepted a NULL pointer safely. However, the null pointer acceptance is in + * devres.c and thus cannot be checked by kcompat-generator.sh. To handle + * this, unconditionally replace devm_kfree with a variant that both accepts + * a const void * pointer and handles a NULL value correctly. + */ +static inline void _kc_devm_kfree(struct device *dev, const void *p) +{ + if (p) + devm_kfree(dev, (void *)p); +} +#define devm_kfree _kc_devm_kfree +#endif /* NEED_DEVM_KFREE */ + +#ifdef NEED_DEVM_KZALLOC +#define devm_kzalloc(dev, size, flags) kzalloc(size, flags) +#endif /* NEED_DEVM_KZALLOC */ + +#ifdef NEED_DEVM_KCALLOC +/* NEED_DEVM_KCALLOC + * + * Since commit 64c862a839a8 ("devres: add kernel standard devm_k.alloc + * functions"), the kernel has provided several devres variants of the + * standard allocation functions. + */ +#define devm_kcalloc(dev, cnt, size, flags) \ + devm_kzalloc(dev, array_size((cnt), (size)), flags) +#endif /* NEED_DEVM_KCALLOC */ + +#ifdef NEED_DEVM_KSTRDUP +/* NEED_DEVM_KSTRDUP + * + * devm_kstrdup was introduced upstream by commit e31108cad3de ("devres: + * introduce API "devm_kstrdup""). + */ +char *_kc_devm_kstrdup(struct device *dev, const char *s, gfp_t gfp); +#define devm_kstrdup(dev, s, gfp) _kc_devm_kstrdup(dev, s, gfp) +#endif /* NEED_DEVM_KSTRDUP */ + +#ifdef NEED_DEVM_KMEMDUP +/* NEED_DEVM_KMEMDUP + * + * devm_kmemdup was introduced upstream by commit 3046365bb470 ("devres: + * introduce API "devm_kmemdup"). + */ +void *_kc_devm_kmemdup(struct device *dev, const void *src, size_t len, + gfp_t gfp); +#define devm_kmemdup _kc_devm_kmemdup +#endif /* NEED_DEVM_KMEMDUP */ + +/* NEED_DIFF_BY_SCALED_PPM + * + * diff_by_scaled_ppm and adjust_by_scaled_ppm were introduced in + * kernel 6.1 by upstream commit 1060707e3809 ("ptp: introduce helpers + * to adjust by scaled parts per million"). + */ +#ifdef NEED_DIFF_BY_SCALED_PPM +static inline bool +diff_by_scaled_ppm(u64 base, long scaled_ppm, u64 *diff) +{ + bool negative = false; + + if (scaled_ppm < 0) { + negative = true; + scaled_ppm = -scaled_ppm; + } + + *diff = mul_u64_u64_div_u64(base, (u64)scaled_ppm, + 1000000ULL << 16); + + return negative; +} + +static inline u64 +adjust_by_scaled_ppm(u64 base, long scaled_ppm) +{ + u64 diff; + + if (diff_by_scaled_ppm(base, scaled_ppm, &diff)) + return base - diff; + + return base + diff; +} +#endif /* NEED_DIFF_BY_SCALED_PPM */ + +#ifndef HAVE_PCI_MSIX_CAN_ALLOC_DYN +static inline bool pci_msix_can_alloc_dyn(struct pci_dev __always_unused *dev) +{ + return false; +} +#endif /* !HAVE_PCI_MSIX_CAN_ALLOC_DYN */ + +#if !defined(HAVE_PCI_MSIX_ALLOC_IRQ_AT) && !defined(HAVE_PCI_MSIX_FREE_IRQ) +struct msi_map { + int index; + int virq; +}; +#endif /* !HAVE_PCI_MSIX_ALLOC_IRQ_AT && !HAVE_PCI_MSIX_FREE_IRQ */ + +#ifndef HAVE_PCI_MSIX_ALLOC_IRQ_AT +#define MSI_ANY_INDEX UINT_MAX +struct irq_affinity_desc; + +static inline struct msi_map +pci_msix_alloc_irq_at(struct pci_dev __always_unused *dev, + unsigned int __always_unused index, + const struct irq_affinity_desc __always_unused *affdesc) +{ + struct msi_map map = { .index = -ENOTSUPP }; + return map; +} +#endif /* !HAVE_PCI_MSIX_ALLOC_IRQ_AT */ + +#ifndef HAVE_PCI_MSIX_FREE_IRQ +static inline void +pci_msix_free_irq(struct pci_dev __always_unused *dev, + struct msi_map __always_unused map) +{ +} +#endif /* !HAVE_PCI_MSIX_FREE_IRQ */ + +#ifdef NEED_PCIE_PTM_ENABLED +/* NEED_PCIE_PTM_ENABLED + * + * pcie_ptm_enabled was added by upstream commit 014408cd624e + * ("PCI: Add pcie_ptm_enabled()"). + * + * It is easy to implement directly. + */ +static inline bool pcie_ptm_enabled(struct pci_dev *dev) +{ +#if defined(HAVE_STRUCT_PCI_DEV_PTM_ENABLED) && defined(CONFIG_PCIE_PTM) + if (!dev) + return false; + + return dev->ptm_enabled; +#else /* !HAVE_STRUCT_PCI_DEV_PTM_ENABLED || !CONFIG_PCIE_PTM */ + return false; +#endif /* HAVE_STRUCT_PCI_DEV_PTM_ENBED && CONFIG_PCIE_PTM */ +} +#endif /* NEED_PCIE_PTM_ENABLED */ + +/* NEED_PCI_ENABLE_PTM + * + * commit ac6c26da29c1 made this function private + * commit 1d71eb53e451 made this function public again + * This declares/defines the function for kernels missing it in linux/pci.h + */ +#ifdef NEED_PCI_ENABLE_PTM +#ifdef CONFIG_PCIE_PTM +int pci_enable_ptm(struct pci_dev *dev, u8 *granularity); +#else +static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) +{ return -EINVAL; } +#endif /* CONFIG_PCIE_PTM */ +#endif /* NEED_PCI_ENABLE_PTM */ + +#ifdef NEED_PCI_DISABLE_PTM +/* NEED_PCI_DISABLE_PTM + * + * This declares/defines the function for kernels missing it in linux/pci.h + */ +void pci_disable_ptm(struct pci_dev *dev); +#endif /* NEED_PCI_DISABLE_PTM */ + +/* NEED_PCIE_FLR + * NEED_PCIE_FLR_RETVAL + * + * pcie_flr() was added in the past, but wasn't generally available until 4.12 + * commit a60a2b73ba69 (4.12) made this function available as an extern + * commit 91295d79d658 (4.17) made this function return int instead of void + + * This declares/defines the function for kernels missing it or needing a + * retval in linux/pci.h + */ +#ifdef NEED_PCIE_FLR +static inline int pcie_flr(struct pci_dev *dev) +{ + u32 cap; + + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); + if (!(cap & PCI_EXP_DEVCAP_FLR)) + return -ENOTTY; + + if (!pci_wait_for_pending_transaction(dev)) + dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n"); + + pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); + msleep(100); + return 0; +} +#endif /* NEED_PCIE_FLR */ +#ifdef NEED_PCIE_FLR_RETVAL +static inline int _kc_pcie_flr(struct pci_dev *dev) +{ + pcie_flr(dev); + return 0; +} +#define pcie_flr(dev) _kc_pcie_flr((dev)) +#endif /* NEED_PCIE_FLR_RETVAL */ + +/* NEED_DEV_PAGE_IS_REUSABLE + * + * dev_page_is_reusable was introduced by + * commit bc38f30f8dbc ("net: introduce common dev_page_is_reusable()") + * + * This function is trivial to re-implement in full. + */ +#ifdef NEED_DEV_PAGE_IS_REUSABLE +static inline bool dev_page_is_reusable(struct page *page) +{ + return likely(page_to_nid(page) == numa_mem_id() && + !page_is_pfmemalloc(page)); +} +#endif /* NEED_DEV_PAGE_IS_REUSABLE */ + +#ifdef NEED_NAPI_ALLOC_SKB +static inline +struct sk_buff *kc_napi_alloc_skb(struct napi_struct *napi, unsigned int len) +{ + return __napi_alloc_skb(napi, len, GFP_ATOMIC | __GFP_NOWARN); +} + +#define napi_alloc_skb(napi, len) kc_napi_alloc_skb(napi, len) +#endif /* NEED_NAPI_ALLOC_SKB */ + +/* NEED_NAPI_BUILD_SKB + * + * napi_build_skb was introduced by + * commit f450d539c05a: ("skbuff: introduce {,__}napi_build_skb() which reuses NAPI cache heads") + * + * This function is a more efficient version of build_skb(). + */ +#ifdef NEED_NAPI_BUILD_SKB +static inline +struct sk_buff *napi_build_skb(void *data, unsigned int frag_size) +{ + return build_skb(data, frag_size); +} +#endif /* NEED_NAPI_BUILD_SKB */ + +/* NEED_DEBUGFS_LOOKUP + * + * Old RHELs (7.2-7.4) do not have this backported. Create a stub and always + * return NULL. Should not affect important features workflow and allows the + * driver to compile on older kernels. + */ +#ifdef NEED_DEBUGFS_LOOKUP + +#include + +static inline struct dentry * +debugfs_lookup(const char *name, struct dentry *parent) +{ + return NULL; +} +#endif /* NEED_DEBUGFS_LOOKUP */ + +/* NEED_DEBUGFS_LOOKUP_AND_REMOVE + * + * Upstream commit dec9b2f1e0455("debugfs: add debugfs_lookup_and_remove()") + * + * Should work the same as upstream equivalent. + */ +#ifdef NEED_DEBUGFS_LOOKUP_AND_REMOVE + +#include + +static inline void +debugfs_lookup_and_remove(const char *name, struct dentry *parent) +{ + struct dentry *dentry; + + dentry = debugfs_lookup(name, parent); + if (!dentry) + return; + + debugfs_remove(dentry); + dput(dentry); +} +#endif /* NEED_DEBUGFS_LOOKUP_AND_REMOVE */ + +/* NEED_FS_FILE_DENTRY + * + * this is simple impl of file_dentry() (introduced in v4.6, backported to + * stable mainline 4.5 and 4.6 kernels) + * + * prior to file_dentry() existence logic of this function was open-coded, + * and if given kernel has had not backported it, then "oversimplification bugs" + * are present there anyway. + */ +#ifdef NEED_FS_FILE_DENTRY +static inline struct dentry *file_dentry(const struct file *file) +{ + return file->f_path.dentry; +} +#endif /* NEED_FS_FILE_DENTRY */ + +/* NEED_CLASS_CREATE_WITHOUT_OWNER + * + * Upstream removed owner argument form helper macro class_create in + * 1aaba11da9aa ("remove module * from class_create()") + * + * In dcfbb67e48a2 ("use lock_class_key already present in struct subsys_private") + * the macro was removed completely. + * + * class_create no longer has owner/module param as it was not used. + */ +#ifdef NEED_CLASS_CREATE_WITHOUT_OWNER +static inline struct class *_kc_class_create(const char *name) +{ + return class_create(THIS_MODULE, name); +} +#ifdef class_create +#undef class_create +#endif +#define class_create _kc_class_create +#endif /* NEED_CLASS_CREATE_WITHOUT_OWNER */ + +/* NEED_LOWER_16_BITS and NEED_UPPER_16_BITS + * + * Upstream commit 03cb4473be92 ("ice: add low level PTP clock access + * functions") introduced the lower_16_bits() and upper_16_bits() macros. They + * are straight forward to implement if missing. + */ +#ifdef NEED_LOWER_16_BITS +#define lower_16_bits(n) ((u16)((n) & 0xffff)) +#endif /* NEED_LOWER_16_BITS */ + +#ifdef NEED_UPPER_16_BITS +#define upper_16_bits(n) ((u16)((n) >> 16)) +#endif /* NEED_UPPER_16_BITS */ + +#ifdef NEED_HWMON_CHANNEL_INFO +#define HWMON_CHANNEL_INFO(stype, ...) \ + (&(struct hwmon_channel_info) { \ + .type = hwmon_##stype, \ + .config = (u32 []) { \ + __VA_ARGS__, 0 \ + } \ + }) +#endif /* NEED_HWMON_CHANNEL_INFO */ + +/* NEED_ASSIGN_BIT + * + * Upstream commit 5307e2ad69ab ("bitops: Introduce assign_bit()") added helper + * assign_bit() to replace if check for setting/clearing bits. + */ +#ifdef NEED_ASSIGN_BIT +static inline void assign_bit(long nr, unsigned long *addr, bool value) +{ + if (value) + set_bit(nr, addr); + else + clear_bit(nr, addr); +} +#endif /* NEED_ASSIGN_BIT */ + +/* + * __has_builtin is supported on gcc >= 10, clang >= 3 and icc >= 21. + * In the meantime, to support gcc < 10, we implement __has_builtin + * by hand. + */ +#ifndef __has_builtin +#define __has_builtin(x) (0) +#endif + +/* NEED___STRUCT_SIZE + * + * 9f7d69c5cd23 ("fortify: Convert to struct vs member helpers") of kernel v6.2 + * has added two following macros, one of them used by DEFINE_FLEX() + */ +#ifdef NEED___STRUCT_SIZE +/* + * When the size of an allocated object is needed, use the best available + * mechanism to find it. (For cases where sizeof() cannot be used.) + */ +#if __has_builtin(__builtin_dynamic_object_size) +#define __struct_size(p) __builtin_dynamic_object_size(p, 0) +#define __member_size(p) __builtin_dynamic_object_size(p, 1) +#else +#define __struct_size(p) __builtin_object_size(p, 0) +#define __member_size(p) __builtin_object_size(p, 1) +#endif +#endif /* NEED___STRUCT_SIZE */ + +/* NEED_KREALLOC_ARRAY + * + * krealloc_array was added by upstream commit + * f0dbd2bd1c22 ("mm: slab: provide krealloc_array()"). + * + * For older kernels, add a new API wrapper around krealloc(). + */ +#ifdef NEED_KREALLOC_ARRAY +static inline void *__must_check krealloc_array(void *p, + size_t new_n, + size_t new_size, + gfp_t flags) +{ + size_t bytes; + + if (unlikely(check_mul_overflow(new_n, new_size, &bytes))) + return NULL; + + return krealloc(p, bytes, flags); +} +#endif /* NEED_KREALLOC_ARRAY */ + +/* NEED_KMEM_CACHE_ALLOC_LRU + * + * Added in commit 88f2ef73fd66 ("mm: introduce kmem_cache_alloc_lru"), + * later changed to macro. + * + * This improves memory usage, and fallbacks to old impl when lru is NULL, + * or just when non "_lru" variant is called. We will do that. + */ +#ifdef NEED_KMEM_CACHE_ALLOC_LRU +static inline void * +kmem_cache_alloc_lru(struct kmem_cache *s, struct list_lru *lru, gfp_t gfpflags) +{ + return kmem_cache_alloc(s, gfpflags); +} +#endif /* NEED_KMEM_CACHE_ALLOC_LRU */ + +/* NEED_XDP_DO_FLUSH + * + * Upstream commit 1d233886dd90 ("xdp: Use bulking for non-map XDP_REDIRECT + * and consolidate code paths") replaced xdp_do_flush_map with xdp_do_flush + * and 7f04bd109d4c ("net: Tree wide: Replace xdp_do_flush_map() with + * xdp_do_flush()") cleaned up related code. + */ +#ifdef NEED_XDP_DO_FLUSH +static inline void xdp_do_flush(void) +{ + xdp_do_flush_map(); +} +#endif /* NEED_XDP_DO_FLUSH */ + +#ifdef NEED_XDP_FEATURES +enum netdev_xdp_act { + NETDEV_XDP_ACT_BASIC = 1, + NETDEV_XDP_ACT_REDIRECT = 2, + NETDEV_XDP_ACT_NDO_XMIT = 4, + NETDEV_XDP_ACT_XSK_ZEROCOPY = 8, + NETDEV_XDP_ACT_HW_OFFLOAD = 16, + NETDEV_XDP_ACT_RX_SG = 32, + NETDEV_XDP_ACT_NDO_XMIT_SG = 64, + + NETDEV_XDP_ACT_MASK = 127, +}; + +typedef u32 xdp_features_t; + +static inline void +xdp_set_features_flag(struct net_device *dev, xdp_features_t val) +{ +} + +static inline void xdp_clear_features_flag(struct net_device *dev) +{ +} + +static inline void +xdp_features_set_redirect_target(struct net_device *dev, bool support_sg) +{ +} + +static inline void xdp_features_clear_redirect_target(struct net_device *dev) +{ +} +#endif /* NEED_XDP_FEATURES */ + +#ifdef NEED_FIND_NEXT_BIT_WRAP +/* NEED_FIND_NEXT_BIT_WRAP + * + * The find_next_bit_wrap function was added by commit 6cc18331a987 + * ("lib/find_bit: add find_next{,_and}_bit_wrap") + * + * For older kernels, define find_next_bit_wrap function that calls + * find_next_bit function and find_first_bit macro. + */ +static inline +unsigned long find_next_bit_wrap(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned long bit = find_next_bit(addr, size, offset); + + if (bit < size) + return bit; + + bit = find_first_bit(addr, offset); + return bit < offset ? bit : size; +} +#endif /* NEED_FIND_NEXT_BIT_WRAP */ + +#ifdef NEED_IS_CONSTEXPR +/* __is_constexpr() macro has moved acros 3 upstream kernel headers: + * commit 3c8ba0d61d04 ("kernel.h: Retain constant expression output for max()/min()") + * introduced it in kernel.h, for kernel v4.17 + * commit b296a6d53339 ("kernel.h: split out min()/max() et al. helpers") moved + * it to minmax.h; + * commit f747e6667ebb ("linux/bits.h: fix compilation error with GENMASK") + * moved it to its current location of const.h + */ +/* + * This returns a constant expression while determining if an argument is + * a constant expression, most importantly without evaluating the argument. + * Glory to Martin Uecker + */ +#define __is_constexpr(x) \ + (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) +#endif /* NEED_IS_CONSTEXPR */ + +/* NEED_DECLARE_FLEX_ARRAY + * + * Upstream commit 3080ea5553 ("stddef: Introduce DECLARE_FLEX_ARRAY() helper") + * introduces DECLARE_FLEX_ARRAY to support flexible arrays in unions or + * alone in a structure. + */ +#ifdef NEED_DECLARE_FLEX_ARRAY +#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ + struct { \ + struct { } __empty_ ## NAME; \ + TYPE NAME[]; \ + } +#endif /* NEED_DECLARE_FLEX_ARRAY */ + +#ifdef NEED_LIST_COUNT_NODES +/* list_count_nodes was added as part of the list.h API by commit 4d70c74659d9 + * ("i915: Move list_count() to list.h as list_count_nodes() for broader use") + * This landed in Linux v6.3 + * + * Its straightforward to directly implement the basic loop. + */ +static inline size_t list_count_nodes(struct list_head *head) +{ + struct list_head *pos; + size_t count = 0; + + list_for_each(pos, head) + count++; + + return count; +} +#endif /* NEED_LIST_COUNT_NODES */ +#ifdef NEED_STATIC_ASSERT +/* + * NEED_STATIC_ASSERT Introduced with upstream commit 6bab69c6501 + * ("build_bug.h: add wrapper for _Static_assert") + * * Available for kernels >= 5.1 + * + * Macro for _Static_assert GCC keyword (C11) + */ +#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr) +#define __static_assert(expr, msg, ...) _Static_assert(expr, msg) +#endif /* NEED_STATIC_ASSERT */ + +#ifdef NEED_ETH_TYPE_VLAN +#include +/** + * eth_type_vlan was added in commit fe19c4f971a5 ("lan: Check for vlan ethernet + * types for 8021.q or 802.1ad"). + * + * eth_type_vlan - check for valid vlan ether type. + * @ethertype: ether type to check + * + * Returns true if the ether type is a vlan ether type. + */ +static inline bool eth_type_vlan(__be16 ethertype) +{ + switch (ethertype) { + case htons(ETH_P_8021Q): + case htons(ETH_P_8021AD): + return true; + default: + return false; + } +} +#endif /* NEED_ETH_TYPE_VLAN */ + +#ifdef NEED___STRUCT_GROUP +/** + * __struct_group() - Create a mirrored named and anonyomous struct + * + * @TAG: The tag name for the named sub-struct (usually empty) + * @NAME: The identifier name of the mirrored sub-struct + * @ATTRS: Any struct attributes (usually empty) + * @MEMBERS: The member declarations for the mirrored structs + * + * Used to create an anonymous union of two structs with identical layout + * and size: one anonymous and one named. The former's members can be used + * normally without sub-struct naming, and the latter can be used to + * reason about the start, end, and size of the group of struct members. + * The named struct can also be explicitly tagged for layer reuse, as well + * as both having struct attributes appended. + */ +#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ + union { \ + struct { MEMBERS } ATTRS; \ + struct TAG { MEMBERS } ATTRS NAME; \ + } +#endif /* NEED___STRUCT_GROUP */ + +#ifdef NEED_STRUCT_GROUP +/** + * struct_group() - Wrap a set of declarations in a mirrored struct + * + * @NAME: The identifier name of the mirrored sub-struct + * @MEMBERS: The member declarations for the mirrored structs + * + * Used to create an anonymous union of two structs with identical + * layout and size: one anonymous and one named. The former can be + * used normally without sub-struct naming, and the latter can be + * used to reason about the start, end, and size of the group of + * struct members. + */ +#define struct_group(NAME, MEMBERS...) \ + __struct_group(/* no tag */, NAME, /* no attrs */, MEMBERS) + +/** + * struct_group_tagged() - Create a struct_group with a reusable tag + * + * @TAG: The tag name for the named sub-struct + * @NAME: The identifier name of the mirrored sub-struct + * @MEMBERS: The member declarations for the mirrored structs + * + * Used to create an anonymous union of two structs with identical + * layout and size: one anonymous and one named. The former can be + * used normally without sub-struct naming, and the latter can be + * used to reason about the start, end, and size of the group of + * struct members. Includes struct tag argument for the named copy, + * so the specified layout can be reused later. + */ +#define struct_group_tagged(TAG, NAME, MEMBERS...) \ + __struct_group(TAG, NAME, /* no attrs */, MEMBERS) +#endif /* NEED_STRUCT_GROUP */ + +#ifdef NEED_READ_POLL_TIMEOUT +/* + * 5f5323a14cad ("iopoll: introduce read_poll_timeout macro") + * Added in kernel 5.8 + */ +#define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \ + sleep_before_read, args...) \ +({ \ + u64 __timeout_us = (timeout_us); \ + unsigned long __sleep_us = (sleep_us); \ + ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ + might_sleep_if((__sleep_us) != 0); \ + if (sleep_before_read && __sleep_us) \ + usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ + for (;;) { \ + (val) = op(args); \ + if (cond) \ + break; \ + if (__timeout_us && \ + ktime_compare(ktime_get(), __timeout) > 0) { \ + (val) = op(args); \ + break; \ + } \ + if (__sleep_us) \ + usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ + cpu_relax(); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +#endif /* NEED_READ_POLL_TIMEOUT */ +#ifdef NEED_READ_POLL_TIMEOUT_ATOMIC +#define read_poll_timeout_atomic(op, val, cond, delay_us, timeout_us, \ + delay_before_read, args...) \ +({ \ + u64 __timeout_us = (timeout_us); \ + s64 __left_ns = __timeout_us * NSEC_PER_USEC; \ + unsigned long __delay_us = (delay_us); \ + u64 __delay_ns = __delay_us * NSEC_PER_USEC; \ + if (delay_before_read && __delay_us) { \ + udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ + for (;;) { \ + (val) = op(args); \ + if (cond) \ + break; \ + if (__timeout_us && __left_ns < 0) { \ + (val) = op(args); \ + break; \ + } \ + if (__delay_us) { \ + udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ + cpu_relax(); \ + if (__timeout_us) \ + __left_ns--; \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) +#endif /* NEED_READ_POLL_TIMEOUT_ATOMIC */ +#if !defined(NEED_READ_POLL_TIMEOUT) || !defined(NEED_READ_POLL_TIMEOUT_ATOMIC) +#include +#endif /* !NEED_READ_POLL_TIMEOUT || !NEED_READ_POLL_TIMEOUT_ATOMIC */ + +#ifndef HAVE_DPLL_LOCK_STATUS_ERROR +/* Copied from include/uapi/linux/dpll.h to have common dpll status enums + * between sysfs and dpll subsystem based solutions. + * cf4f0f1e1c465 ("dpll: extend uapi by lock status error attribute") + * Added in kernel 6.9 + */ +enum dpll_lock_status_error { + DPLL_LOCK_STATUS_ERROR_NONE = 1, + DPLL_LOCK_STATUS_ERROR_UNDEFINED, + DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN, + DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH, + + /* private: */ + __DPLL_LOCK_STATUS_ERROR_MAX, + DPLL_LOCK_STATUS_ERROR_MAX = (__DPLL_LOCK_STATUS_ERROR_MAX - 1) +}; + +#endif /* HAVE_DPLL_LOCK_STATUS_ERROR */ + +#ifdef NEED_DPLL_NETDEV_PIN_SET +#define dpll_netdev_pin_set netdev_dpll_pin_set +#define dpll_netdev_pin_clear netdev_dpll_pin_clear +#endif /* NEED_DPLL_NETDEV_PIN_SET */ + +#ifdef NEED_RADIX_TREE_EMPTY +static inline bool radix_tree_empty(struct radix_tree_root *root) +{ + return !root->rnode; +} +#endif /* NEED_RADIX_TREE_EMPTY */ + +#ifdef NEED_SET_SCHED_FIFO +/* + * 7318d4cc14c8 ("sched: Provide sched_set_fifo()") + * Added in kernel 5.9, + * converted to a macro for kcompat + */ +#include + +#ifdef NEED_SCHED_PARAM +#include +#endif /* NEED_SCHED_PARAM */ +#ifdef NEED_RT_H +#include +#else/* NEED_RT_H */ +#include +#endif /* NEED_RT_H */ +#define sched_set_fifo(p) \ +({ \ + struct sched_param sp = { .sched_priority = MAX_RT_PRIO / 2 }; \ + \ + WARN_ON_ONCE(sched_setscheduler_nocheck((p), SCHED_FIFO,&sp) != 0);\ +}) +#endif /* NEED_SET_SCHED_FIFO */ + +#ifndef HAVE_ETHTOOL_KEEE +#ifndef __ETHTOOL_DECLARE_LINK_MODE_MASK +#define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \ + DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS) +#endif /* __ETHTOOL_DECLARE_LINK_MODE_MASK */ +struct ethtool_keee { + __ETHTOOL_DECLARE_LINK_MODE_MASK(supported); + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised); + __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertised); + u32 tx_lpi_timer; + bool tx_lpi_enabled; + bool eee_active; + bool eee_enabled; +}; + +void eee_to_keee(struct ethtool_keee *keee, + const struct ethtool_eee *eee); + +void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, + u32 legacy_u32); +bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, + const unsigned long *src); +bool ethtool_eee_use_linkmodes(const struct ethtool_keee *eee); + +void keee_to_eee(struct ethtool_eee *eee, + const struct ethtool_keee *keee); + +#ifndef HAVE_MII_EEE_CAP1_MOD_LINKMODE +#include +#define _kc_linkmode_mod_bit(_nr, _addr, set) do {\ + const int nr = _nr; \ + unsigned long *addr = _addr; \ + if (set) \ + set_bit(nr, addr); \ + else \ + clear_bit(nr, addr); \ + } while (false) + +static inline void mii_eee_cap1_mod_linkmode_t(unsigned long *adv, u32 val) +{ + _kc_linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, + adv, val & MDIO_EEE_100TX); + _kc_linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + adv, val & MDIO_EEE_1000T); + _kc_linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + adv, val & MDIO_EEE_10GT); + _kc_linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + adv, val & MDIO_EEE_1000KX); + _kc_linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + adv, val & MDIO_EEE_10GKX4); + _kc_linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + adv, val & MDIO_EEE_10GKR); +} + +static inline u32 linkmode_to_mii_eee_cap1_t(unsigned long *adv) +{ + u32 result = 0; + + if (test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, adv)) + result |= MDIO_EEE_100TX; + if (test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, adv)) + result |= MDIO_EEE_1000T; + if (test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, adv)) + result |= MDIO_EEE_10GT; + if (test_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, adv)) + result |= MDIO_EEE_1000KX; + if (test_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, adv)) + result |= MDIO_EEE_10GKX4; + if (test_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, adv)) + result |= MDIO_EEE_10GKR; + + return result; +} +#endif /* !HAVE_MII_EEE_CAP1_MOD_LINKMODE */ +#endif /* !HAVE_ETHTOOL_KEEE */ + +#ifdef HAVE_ASSIGN_STR_2_PARAMS +#define _kc__assign_str(dst, src) __assign_str(dst, src) +#else +#define _kc__assign_str(dst, src) __assign_str(dst) +#endif + +#if defined(NEED_DIM_END_SAMPLE_BY_POINTER) && defined(HAVE_CONFIG_DIMLIB) +#include + +/* Since commit 61bf0009a765 ("dim: pass dim_sample to net_dim() by reference") + * the net_dim function has accepted a const struct dim_sample * parameter + * instead of passing struct dim_sample by value. + */ +static inline void _kc_net_dim(struct dim *dim, + const struct dim_sample *end_sample) +{ + if (end_sample) + net_dim(dim, *end_sample); +} + +#define net_dim(_dim, _dim_sample) _kc_net_dim(_dim, _dim_sample) +#endif + +#ifdef NEED_XSK_BUFF_DMA_SYNC_FOR_CPU_NO_POOL +#include +static inline void +_kc_xsk_buff_dma_sync_for_cpu(struct xdp_buff *xdp) +{ + struct xdp_buff_xsk *xskb = container_of(xdp, struct xdp_buff_xsk, xdp); + + xsk_buff_dma_sync_for_cpu(xdp, xskb->pool); +} + +#define xsk_buff_dma_sync_for_cpu(xdp) \ + _kc_xsk_buff_dma_sync_for_cpu(xdp) +#endif /* NEED_XSK_BUFF_DMA_SYNC_FOR_CPU_NO_POOL */ + +#ifdef NEED_XDP_CONVERT_BUFF_TO_FRAME +#define xdp_convert_buff_to_frame convert_to_xdp_frame +#endif + +#ifdef NEED_STR_ENABLED_DISABLED +static inline const char *str_enable_disable(bool v) +{ + return v ? "enable" : "disable"; +} + +static inline const char *str_enabled_disabled(bool v) +{ + return v ? "enabled" : "disabled"; +} + +static inline const char *str_read_write(bool v) +{ + return v ? "read" : "write"; +} + +static inline const char *str_on_off(bool v) +{ + return v ? "on" : "off"; +} + +static inline const char *str_yes_no(bool v) +{ + return v ? "yes" : "no"; +} +#endif /* NEED_STR_ENABLED_DISABLED */ +#if !defined(HAVE_LINUX_REFCOUNT_TYPES_HEADER) && !defined(HAVE_LINUX_REFCOUNT_HEADER) + + typedef struct refcount_struct { + atomic_t refs; + } refcount_t; +#endif /* HAVE_LINUX_REFCOUNT_TYPES_HEADER && HAVE_LINUX_REFCOUNT_HEADER */ + +#ifdef NEED_TIMER_DELETE +#define timer_delete del_timer +#define timer_delete_sync del_timer_sync +#endif /* NEED_TIMER_DELETE */ + +/* Since commit 3652117f8548 ("eventfd: simplify eventfd_signal()") the + * eventfd_signal() function only takes a single argument. The second + * argument was only ever passed as 1. + */ +#ifdef NEED_EVENTFD_SIGNAL_NO_COUNTER +static inline +void _kc_eventfd_signal(struct eventfd_ctx *ctx) +{ + eventfd_signal(ctx, 1); +} +#define eventfd_signal(ctx) _kc_eventfd_signal(ctx) +#endif /* NEED_EVENTFD_SIGNAL_NO_COUNTER */ + +#ifdef NEED_TIMER_CONTAINER_OF +#define timer_container_of(var, callback_timer, timer_fieldname) \ + from_timer(var, callback_timer, timer_fieldname) +#endif /* NEED_TIMER_CONTAINER_OF */ + +/* + * Some legacy kernels lack TCP_MIN_MSS in . Provide a portable + * lower bound so driver code can validate MSS (e.g., avoid zero/tiny values). + */ +#ifndef TCP_MIN_MSS +#define TCP_MIN_MSS 88U +#endif + +#endif /* _KCOMPAT_IMPL_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_kthread.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_kthread.h new file mode 100644 index 0000000000..75adfa7c33 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_kthread.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _KCOMPAT_KTHREAD_H_ +#define _KCOMPAT_KTHREAD_H_ + +/* Kernels since 4.9 have supported delayed work items for kthreads. In order + * to allow seamless transition from old to new kernels, this header defines + * a set of macros to switch out kthread usage with a work queue on the older + * kernels that do not have support for kthread_delayed_work. + */ +#ifdef HAVE_KTHREAD_DELAYED_API +#include +#else /* HAVE_KTHREAD_DELAYED_API */ +#include +#undef kthread_work +#define kthread_work work_struct +#undef kthread_delayed_work +#define kthread_delayed_work delayed_work +#undef kthread_worker +#define kthread_worker workqueue_struct +#undef kthread_queue_work +#define kthread_queue_work(worker, work) queue_work(worker, work) +#undef kthread_queue_delayed_work +#define kthread_queue_delayed_work(worker, dwork, delay) \ + queue_delayed_work(worker, dwork, delay) +#undef kthread_init_work +#define kthread_init_work(work, fn) INIT_WORK(work, fn) +#undef kthread_init_delayed_work +#define kthread_init_delayed_work(dwork, fn) \ + INIT_DELAYED_WORK(dwork, fn) +#undef kthread_flush_worker +#define kthread_flush_worker(worker) flush_workqueue(worker) +#undef kthread_cancel_work_sync +#define kthread_cancel_work_sync(work) cancel_work_sync(work) +#undef kthread_cancel_delayed_work_sync +#define kthread_cancel_delayed_work_sync(dwork) \ + cancel_delayed_work_sync(dwork) +#undef kthread_create_worker +#define kthread_create_worker(flags, namefmt, ...) \ + alloc_workqueue(namefmt, 0, 0, ##__VA_ARGS__) +#undef kthread_destroy_worker +#define kthread_destroy_worker(worker) destroy_workqueue(worker) +#endif /* !HAVE_KTHREAD_DELAYED_API */ + +#endif /* _KCOMPAT_KTHREAD_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_overflow.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_overflow.h new file mode 100644 index 0000000000..1d882c9dc9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_overflow.h @@ -0,0 +1,493 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +#ifndef __LINUX_OVERFLOW_H +#define __LINUX_OVERFLOW_H + +#include +#include +#include + +/* + * prior to commit 54d50897d544 ("linux/kernel.h: split *_MAX and *_MIN macros into ") + * SIZE_MAX was part of kernel.h, which we don't want to include so early on, + * + * on old RHELs size_t is also unknown at this point, so just include types.h + */ +#include +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +/* + * In the fallback code below, we need to compute the minimum and + * maximum values representable in a given type. These macros may also + * be useful elsewhere, so we provide them outside the + * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block. + * + * It would seem more obvious to do something like + * + * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0) + * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0) + * + * Unfortunately, the middle expressions, strictly speaking, have + * undefined behaviour, and at least some versions of gcc warn about + * the type_max expression (but not if -fsanitize=undefined is in + * effect; in that case, the warning is deferred to runtime...). + * + * The slightly excessive casting in type_min is to make sure the + * macros also produce sensible values for the exotic type _Bool. [The + * overflow checkers only almost work for _Bool, but that's + * a-feature-not-a-bug, since people shouldn't be doing arithmetic on + * _Bools. Besides, the gcc builtins don't allow _Bool* as third + * argument.] + * + * Idea stolen from + * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html - + * credit to Christian Biere. + */ +/* The is_signed_type macro is redefined in a few places in various kernel + * headers. If this header is included at the same time as one of those, we + * will generate compilation warnings. Since we can't fix every old kernel, + * rename is_signed_type for this file to _kc_is_signed_type. This prevents + * the macro name collision, and should be safe since our drivers do not + * directly call the macro. + */ +#define _kc_is_signed_type(type) (((type)(-1)) < (type)1) +#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - _kc_is_signed_type(type))) +#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) +#define type_min(T) ((T)((T)-type_max(T)-(T)1)) + +/* + * Avoids triggering -Wtype-limits compilation warning, + * while using unsigned data types to check a < 0. + */ +#define is_non_negative(a) ((a) > 0 || (a) == 0) +#define is_negative(a) (!(is_non_negative(a))) + +#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW +/* commit 9b80e4c4ddac ("overflow: Add __must_check attribute to check_*() + * helpers") added __must_check_overflow + * + * Allows for effectively applying __must_check to a macro so we can have + * both the type-agnostic benefits of the macros while also being able to + * enforce that the return value is, in fact, checked. + */ +static inline bool __must_check __must_check_overflow(bool overflow) +{ + return unlikely(overflow); +} + +/* + * For simplicity and code hygiene, the fallback code below insists on + * a, b and *d having the same type (similar to the min() and max() + * macros), whereas gcc's type-generic overflow checkers accept + * different types. Hence we don't just make check_add_overflow an + * alias for __builtin_add_overflow, but add type checks similar to + * below. + */ +#define check_add_overflow(a, b, d) \ + __must_check_overflow(__builtin_add_overflow(a, b, d)) + +#define check_sub_overflow(a, b, d) \ + __must_check_overflow(__builtin_sub_overflow(a, b, d)) + +#define check_mul_overflow(a, b, d) \ + __must_check_overflow(__builtin_mul_overflow(a, b, d)) + +#else +#ifndef __CHECKER__ + +/* Checking for unsigned overflow is relatively easy without causing UB. */ +#define __unsigned_add_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = __a + __b; \ + *__d < __a; \ +}) +#define __unsigned_sub_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = __a - __b; \ + __a < __b; \ +}) +/* + * If one of a or b is a compile-time constant, this avoids a division. + */ +#define __unsigned_mul_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = __a * __b; \ + __builtin_constant_p(__b) ? \ + __b > 0 && __a > type_max(typeof(__a)) / __b : \ + __a > 0 && __b > type_max(typeof(__b)) / __a; \ +}) + +/* + * For signed types, detecting overflow is much harder, especially if + * we want to avoid UB. But the interface of these macros is such that + * we must provide a result in *d, and in fact we must produce the + * result promised by gcc's builtins, which is simply the possibly + * wrapped-around value. Fortunately, we can just formally do the + * operations in the widest relevant unsigned type (u64) and then + * truncate the result - gcc is smart enough to generate the same code + * with and without the (u64) casts. + */ + +/* + * Adding two signed integers can overflow only if they have the same + * sign, and overflow has happened iff the result has the opposite + * sign. + */ +#define __signed_add_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = (u64)__a + (u64)__b; \ + (((~(__a ^ __b)) & (*__d ^ __a)) \ + & type_min(typeof(__a))) != 0; \ +}) + +/* + * Subtraction is similar, except that overflow can now happen only + * when the signs are opposite. In this case, overflow has happened if + * the result has the opposite sign of a. + */ +#define __signed_sub_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = (u64)__a - (u64)__b; \ + ((((__a ^ __b)) & (*__d ^ __a)) \ + & type_min(typeof(__a))) != 0; \ +}) + +/* + * Signed multiplication is rather hard. gcc always follows C99, so + * division is truncated towards 0. This means that we can write the + * overflow check like this: + * + * (a > 0 && (b > MAX/a || b < MIN/a)) || + * (a < -1 && (b > MIN/a || b < MAX/a) || + * (a == -1 && b == MIN) + * + * The redundant casts of -1 are to silence an annoying -Wtype-limits + * (included in -Wextra) warning: When the type is u8 or u16, the + * __b_c_e in check_mul_overflow obviously selects + * __unsigned_mul_overflow, but unfortunately gcc still parses this + * code and warns about the limited range of __b. + */ + +#define __signed_mul_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + typeof(a) __tmax = type_max(typeof(a)); \ + typeof(a) __tmin = type_min(typeof(a)); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = (u64)__a * (u64)__b; \ + (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \ + (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \ + (__b == (typeof(__b))-1 && __a == __tmin); \ +}) + + +#define check_add_overflow(a, b, d) \ + __builtin_choose_expr(_kc_is_signed_type(typeof(a)), \ + __signed_add_overflow(a, b, d), \ + __unsigned_add_overflow(a, b, d)) + +#define check_sub_overflow(a, b, d) \ + __builtin_choose_expr(_kc_is_signed_type(typeof(a)), \ + __signed_sub_overflow(a, b, d), \ + __unsigned_sub_overflow(a, b, d)) + +#define check_mul_overflow(a, b, d) \ + __builtin_choose_expr(_kc_is_signed_type(typeof(a)), \ + __signed_mul_overflow(a, b, d), \ + __unsigned_mul_overflow(a, b, d)) + +#endif /* __CHECKER__ */ +#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ + +/** check_shl_overflow() - Calculate a left-shifted value and check overflow + * + * @a: Value to be shifted + * @s: How many bits left to shift + * @d: Pointer to where to store the result + * + * Computes *@d = (@a << @s) + * + * Returns true if '*d' cannot hold the result or when 'a << s' doesn't + * make sense. Example conditions: + * - 'a << s' causes bits to be lost when stored in *d. + * - 's' is garbage (e.g. negative) or so large that the result of + * 'a << s' is guaranteed to be 0. + * - 'a' is negative. + * - 'a << s' sets the sign bit, if any, in '*d'. + * + * '*d' will hold the results of the attempted shift, but is not + * considered "safe for use" if false is returned. + */ +#define check_shl_overflow(a, s, d) ({ \ + typeof(a) _a = a; \ + typeof(s) _s = s; \ + typeof(d) _d = d; \ + u64 _a_full = _a; \ + unsigned int _to_shift = \ + _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \ + *_d = (_a_full << _to_shift); \ + (_to_shift != _s || *_d < 0 || _a < 0 || \ + (*_d >> _to_shift) != _a); \ +}) + +#define __overflows_type_constexpr(x, T) ( \ + is_unsigned_type(typeof(x)) ? \ + (x) > type_max(typeof(T)) : \ + is_unsigned_type(typeof(T)) ? \ + (x) < 0 || (x) > type_max(typeof(T)) : \ + (x) < type_min(typeof(T)) || (x) > type_max(typeof(T))) + +#define __overflows_type(x, T) ({ \ + typeof(T) v = 0; \ + check_add_overflow((x), v, &v); \ +}) + +/** + * overflows_type - helper for checking the overflows between value, variables, + * or data type + * + * @n: source constant value or variable to be checked + * @T: destination variable or data type proposed to store @x + * + * Compares the @x expression for whether or not it can safely fit in + * the storage of the type in @T. @x and @T can have different types. + * If @x is a constant expression, this will also resolve to a constant + * expression. + * + * Returns: true if overflow can occur, false otherwise. + */ +#define overflows_type(n, T) \ + __builtin_choose_expr(__is_constexpr(n), \ + __overflows_type_constexpr(n, T), \ + __overflows_type(n, T)) + +/** + * castable_to_type - like __same_type(), but also allows for casted literals + * + * @n: variable or constant value + * @T: variable or data type + * + * Unlike the __same_type() macro, this allows a constant value as the + * first argument. If this value would not overflow into an assignment + * of the second argument's type, it returns true. Otherwise, this falls + * back to __same_type(). + */ +#define castable_to_type(n, T) \ + __builtin_choose_expr(__is_constexpr(n), \ + !__overflows_type_constexpr(n, T), \ + __same_type(n, T)) + +/** + * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX + * @factor1: first factor + * @factor2: second factor + * + * Returns: calculate @factor1 * @factor2, both promoted to size_t, + * with any overflow causing the return value to be SIZE_MAX. The + * lvalue must be size_t to avoid implicit type conversion. + */ +static inline size_t __must_check size_mul(size_t factor1, size_t factor2) +{ + size_t bytes; + + if (check_mul_overflow(factor1, factor2, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * size_add() - Calculate size_t addition with saturation at SIZE_MAX + * @addend1: first addend + * @addend2: second addend + * + * Returns: calculate @addend1 + @addend2, both promoted to size_t, + * with any overflow causing the return value to be SIZE_MAX. The + * lvalue must be size_t to avoid implicit type conversion. + */ +static inline size_t __must_check size_add(size_t addend1, size_t addend2) +{ + size_t bytes; + + if (check_add_overflow(addend1, addend2, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX + * @minuend: value to subtract from + * @subtrahend: value to subtract from @minuend + * + * Returns: calculate @minuend - @subtrahend, both promoted to size_t, + * with any overflow causing the return value to be SIZE_MAX. For + * composition with the size_add() and size_mul() helpers, neither + * argument may be SIZE_MAX (or the result with be forced to SIZE_MAX). + * The lvalue must be size_t to avoid implicit type conversion. + */ +static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) +{ + size_t bytes; + + if (minuend == SIZE_MAX || subtrahend == SIZE_MAX || + check_sub_overflow(minuend, subtrahend, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * array_size() - Calculate size of 2-dimensional array. + * + * @a: dimension one + * @b: dimension two + * + * Calculates size of 2-dimensional array: @a * @b. + * + * Returns: number of bytes needed to represent the array or SIZE_MAX on + * overflow. + */ +#define array_size(a, b) size_mul(a, b) + +/** + * array3_size() - Calculate size of 3-dimensional array. + * + * @a: dimension one + * @b: dimension two + * @c: dimension three + * + * Calculates size of 3-dimensional array: @a * @b * @c. + * + * Returns: number of bytes needed to represent the array or SIZE_MAX on + * overflow. + */ +#define array3_size(a, b, c) size_mul(size_mul(a, b), c) + +/** + * flex_array_size() - Calculate size of a flexible array member + * within an enclosing structure. + * @p: Pointer to the structure. + * @member: Name of the flexible array member. + * @count: Number of elements in the array. + * + * Calculates size of a flexible array of @count number of @member + * elements, at the end of structure @p. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define flex_array_size(p, member, count) \ + __builtin_choose_expr(__is_constexpr(count), \ + (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ + size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) + +/** + * struct_size() - Calculate size of structure with trailing flexible array. + * @p: Pointer to the structure. + * @member: Name of the array member. + * @count: Number of elements in the array. + * + * Calculates size of memory needed for structure of @p followed by an + * array of @count number of @member elements. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define struct_size(p, member, count) \ + __builtin_choose_expr(__is_constexpr(count), \ + sizeof(*(p)) + flex_array_size(p, member, count), \ + size_add(sizeof(*(p)), flex_array_size(p, member, count))) + +/** + * struct_size_t() - Calculate size of structure with trailing flexible array + * @type: structure type name. + * @member: Name of the array member. + * @count: Number of elements in the array. + * + * Calculates size of memory needed for structure @type followed by an + * array of @count number of @member elements. Prefer using struct_size() + * when possible instead, to keep calculations associated with a specific + * instance variable of type @type. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define struct_size_t(type, member, count) \ + struct_size((type *)NULL, member, count) + +/** + * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family. + * Enables caller macro to pass (different) initializer. + * + * @type: structure type name, including "struct" keyword. + * @name: Name for a variable to define. + * @member: Name of the array member. + * @count: Number of elements in the array; must be compile-time const. + * @initializer: initializer expression (could be empty for no init). + */ +#define _DEFINE_FLEX(type, name, member, count, initializer) \ + _Static_assert(__builtin_constant_p(count), \ + "onstack flex array members require compile-time const count"); \ + union { \ + u8 bytes[struct_size_t(type, member, count)]; \ + type obj; \ + } name##_u initializer; \ + type *name = (type *)&name##_u + +/** + * DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member, when it does not have a __counted_by annotation. + * + * @type: structure type name, including "struct" keyword. + * @name: Name for a variable to define. + * @member: Name of the array member. + * @count: Number of elements in the array; must be compile-time const. + * + * Define a zeroed, on-stack, instance of @type structure with a trailing + * flexible array member. + * Use __struct_size(@name) to get compile-time size of it afterwards. + */ +#define DEFINE_RAW_FLEX(type, name, member, count) \ + _DEFINE_FLEX(type, name, member, count, = {}) + +/** + * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing + * flexible array member. + * + * @type: structure type name, including "struct" keyword. + * @name: Name for a variable to define. + * @member: Name of the array member. + * @count: Number of elements in the array; must be compile-time const. + * + * Define a zeroed, on-stack, instance of @type structure with a trailing + * flexible array member. + * Use __struct_size(@name) to get compile-time size of it afterwards. + */ +#define DEFINE_FLEX(type, name, member, count) \ + _DEFINE_FLEX(type, name, member, count, = {}) + +#endif /* __LINUX_OVERFLOW_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.c new file mode 100644 index 0000000000..c8b68b0c22 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.c @@ -0,0 +1,476 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/* Copyright 2016-2018 NXP + * Copyright (c) 2018-2019, Vladimir Oltean + */ +#include "kcompat.h" +#include "kcompat_packing.h" + +#include +#include +#ifdef HAVE_LINUX_BITS_HEADER +#include +#endif +#include +#include +#include + +#define __pack_fields(pbuf, pbuflen, ustruct, fields, num_fields, quirks) \ + ({ \ + for (size_t i = 0; i < (num_fields); i++) { \ + typeof(&(fields)[0]) field = &(fields)[i]; \ + u64 uval; \ + \ + uval = ustruct_field_to_u64(ustruct, field->offset, field->size); \ + \ + __pack(pbuf, uval, field->startbit, field->endbit, \ + pbuflen, quirks); \ + } \ + }) + +#define __unpack_fields(pbuf, pbuflen, ustruct, fields, num_fields, quirks) \ + ({ \ + for (size_t i = 0; i < (num_fields); i++) { \ + typeof(&(fields)[0]) field = &fields[i]; \ + u64 uval; \ + \ + __unpack(pbuf, &uval, field->startbit, field->endbit, \ + pbuflen, quirks); \ + \ + u64_to_ustruct_field(ustruct, field->offset, field->size, uval); \ + } \ + }) + +/** + * calculate_box_addr - Determine physical location of byte in buffer + * @box: Index of byte within buffer seen as a logical big-endian big number + * @len: Size of buffer in bytes + * @quirks: mask of QUIRK_LSW32_IS_FIRST and QUIRK_LITTLE_ENDIAN + * + * Function interprets the buffer as a @len byte sized big number, and returns + * the physical offset of the @box logical octet within it. Internally, it + * treats the big number as groups of 4 bytes. If @len is not a multiple of 4, + * the last group may be shorter. + * + * @QUIRK_LSW32_IS_FIRST gives the ordering of groups of 4 octets relative to + * each other. If set, the most significant group of 4 octets is last in the + * buffer (and may be truncated if @len is not a multiple of 4). + * + * @QUIRK_LITTLE_ENDIAN gives the ordering of bytes within each group of 4. + * If set, the most significant byte is last in the group. If @len takes the + * form of 4k+3, the last group will only be able to represent 24 bits, and its + * most significant octet is byte 2. + * + * Return: the physical offset into the buffer corresponding to the logical box. + */ +static size_t calculate_box_addr(size_t box, size_t len, u8 quirks) +{ + size_t offset_of_group, offset_in_group, this_group = box / 4; + size_t group_size; + + if (quirks & QUIRK_LSW32_IS_FIRST) + offset_of_group = this_group * 4; + else + offset_of_group = len - ((this_group + 1) * 4); + + group_size = min(4, len - offset_of_group); + + if (quirks & QUIRK_LITTLE_ENDIAN) + offset_in_group = box - this_group * 4; + else + offset_in_group = group_size - (box - this_group * 4) - 1; + + return offset_of_group + offset_in_group; +} + +static void __pack(void *pbuf, u64 uval, size_t startbit, size_t endbit, + size_t pbuflen, u8 quirks) +{ + /* Logical byte indices corresponding to the + * start and end of the field. + */ + int plogical_first_u8 = startbit / BITS_PER_BYTE; + int plogical_last_u8 = endbit / BITS_PER_BYTE; + int value_width = startbit - endbit + 1; + int box; + + /* Check if "uval" fits in "value_width" bits. + * The test only works for value_width < 64, but in the latter case, + * any 64-bit uval will surely fit. + */ + WARN(value_width < 64 && uval >= (1ull << value_width), + "Cannot store 0x%llx inside bits %zu-%zu - will truncate\n", + uval, startbit, endbit); + + /* Iterate through an idealistic view of the pbuf as an u64 with + * no quirks, u8 by u8 (aligned at u8 boundaries), from high to low + * logical bit significance. "box" denotes the current logical u8. + */ + for (box = plogical_first_u8; box >= plogical_last_u8; box--) { + /* Bit indices into the currently accessed 8-bit box */ + size_t box_start_bit, box_end_bit, box_addr; + u8 box_mask; + /* Corresponding bits from the unpacked u64 parameter */ + size_t proj_start_bit, proj_end_bit; + u64 proj_mask; + u64 pval; + + /* This u8 may need to be accessed in its entirety + * (from bit 7 to bit 0), or not, depending on the + * input arguments startbit and endbit. + */ + if (box == plogical_first_u8) + box_start_bit = startbit % BITS_PER_BYTE; + else + box_start_bit = 7; + if (box == plogical_last_u8) + box_end_bit = endbit % BITS_PER_BYTE; + else + box_end_bit = 0; + + /* We have determined the box bit start and end. + * Now we calculate where this (masked) u8 box would fit + * in the unpacked (CPU-readable) u64 - the u8 box's + * projection onto the unpacked u64. Though the + * box is u8, the projection is u64 because it may fall + * anywhere within the unpacked u64. + */ + proj_start_bit = ((box * BITS_PER_BYTE) + box_start_bit) - endbit; + proj_end_bit = ((box * BITS_PER_BYTE) + box_end_bit) - endbit; + proj_mask = GENMASK_ULL(proj_start_bit, proj_end_bit); + box_mask = GENMASK(box_start_bit, box_end_bit); + + /* Determine the offset of the u8 box inside the pbuf, + * adjusted for quirks. The adjusted box_addr will be used for + * effective addressing inside the pbuf (so it's not + * logical any longer). + */ + box_addr = calculate_box_addr(box, pbuflen, quirks); + + /* Write to pbuf, read from uval */ + pval = uval & proj_mask; + pval >>= proj_end_bit; + pval <<= box_end_bit; + + if (quirks & QUIRK_MSB_ON_THE_RIGHT) { + pval = bitrev8(pval); + box_mask = bitrev8(box_mask); + } + + ((u8 *)pbuf)[box_addr] &= ~box_mask; + ((u8 *)pbuf)[box_addr] |= pval; + } +} + +/** + * pack - Pack u64 number into bitfield of buffer. + * + * @pbuf: Pointer to a buffer holding the packed value. + * @uval: CPU-readable unpacked value to pack. + * @startbit: The index (in logical notation, compensated for quirks) where + * the packed value starts within pbuf. Must be larger than, or + * equal to, endbit. + * @endbit: The index (in logical notation, compensated for quirks) where + * the packed value ends within pbuf. Must be smaller than, or equal + * to, startbit. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming + * correct usage, return code may be discarded. The @pbuf memory will + * be modified on success. + */ +int pack(void *pbuf, u64 uval, size_t startbit, size_t endbit, size_t pbuflen, + u8 quirks) +{ + /* startbit is expected to be larger than endbit, and both are + * expected to be within the logically addressable range of the buffer. + */ + if (unlikely(startbit < endbit || startbit >= BITS_PER_BYTE * pbuflen)) + /* Invalid function call */ + return -EINVAL; + + if (unlikely(startbit - endbit >= 64)) + return -ERANGE; + + __pack(pbuf, uval, startbit, endbit, pbuflen, quirks); + + return 0; +} + +static void __unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit, + size_t pbuflen, u8 quirks) +{ + /* Logical byte indices corresponding to the + * start and end of the field. + */ + int plogical_first_u8 = startbit / BITS_PER_BYTE; + int plogical_last_u8 = endbit / BITS_PER_BYTE; + int box; + + /* Initialize parameter */ + *uval = 0; + + /* Iterate through an idealistic view of the pbuf as an u64 with + * no quirks, u8 by u8 (aligned at u8 boundaries), from high to low + * logical bit significance. "box" denotes the current logical u8. + */ + for (box = plogical_first_u8; box >= plogical_last_u8; box--) { + /* Bit indices into the currently accessed 8-bit box */ + size_t box_start_bit, box_end_bit, box_addr; + u8 box_mask; + /* Corresponding bits from the unpacked u64 parameter */ + size_t proj_start_bit, proj_end_bit; + u64 proj_mask; + u64 pval; + + /* This u8 may need to be accessed in its entirety + * (from bit 7 to bit 0), or not, depending on the + * input arguments startbit and endbit. + */ + if (box == plogical_first_u8) + box_start_bit = startbit % BITS_PER_BYTE; + else + box_start_bit = 7; + if (box == plogical_last_u8) + box_end_bit = endbit % BITS_PER_BYTE; + else + box_end_bit = 0; + + /* We have determined the box bit start and end. + * Now we calculate where this (masked) u8 box would fit + * in the unpacked (CPU-readable) u64 - the u8 box's + * projection onto the unpacked u64. Though the + * box is u8, the projection is u64 because it may fall + * anywhere within the unpacked u64. + */ + proj_start_bit = ((box * BITS_PER_BYTE) + box_start_bit) - endbit; + proj_end_bit = ((box * BITS_PER_BYTE) + box_end_bit) - endbit; + proj_mask = GENMASK_ULL(proj_start_bit, proj_end_bit); + box_mask = GENMASK(box_start_bit, box_end_bit); + + /* Determine the offset of the u8 box inside the pbuf, + * adjusted for quirks. The adjusted box_addr will be used for + * effective addressing inside the pbuf (so it's not + * logical any longer). + */ + box_addr = calculate_box_addr(box, pbuflen, quirks); + + /* Read from pbuf, write to uval */ + pval = ((u8 *)pbuf)[box_addr]; + + if (quirks & QUIRK_MSB_ON_THE_RIGHT) + pval = bitrev8(pval); + + pval &= box_mask; + + pval >>= box_end_bit; + pval <<= proj_end_bit; + *uval &= ~proj_mask; + *uval |= pval; + } +} + +/** + * unpack - Unpack u64 number from packed buffer. + * + * @pbuf: Pointer to a buffer holding the packed value. + * @uval: Pointer to an u64 holding the unpacked value. + * @startbit: The index (in logical notation, compensated for quirks) where + * the packed value starts within pbuf. Must be larger than, or + * equal to, endbit. + * @endbit: The index (in logical notation, compensated for quirks) where + * the packed value ends within pbuf. Must be smaller than, or equal + * to, startbit. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming + * correct usage, return code may be discarded. The @uval will be + * modified on success. + */ +int unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit, + size_t pbuflen, u8 quirks) +{ + /* width of the field to access in the pbuf */ + u64 value_width; + + /* startbit is expected to be larger than endbit, and both are + * expected to be within the logically addressable range of the buffer. + */ + if (startbit < endbit || startbit >= BITS_PER_BYTE * pbuflen) + /* Invalid function call */ + return -EINVAL; + + value_width = startbit - endbit + 1; + if (value_width > 64) + return -ERANGE; + + __unpack(pbuf, uval, startbit, endbit, pbuflen, quirks); + + return 0; +} + +/** + * packing - Convert numbers (currently u64) between a packed and an unpacked + * format. Unpacked means laid out in memory in the CPU's native + * understanding of integers, while packed means anything else that + * requires translation. + * + * @pbuf: Pointer to a buffer holding the packed value. + * @uval: Pointer to an u64 holding the unpacked value. + * @startbit: The index (in logical notation, compensated for quirks) where + * the packed value starts within pbuf. Must be larger than, or + * equal to, endbit. + * @endbit: The index (in logical notation, compensated for quirks) where + * the packed value ends within pbuf. Must be smaller than, or equal + * to, startbit. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @op: If PACK, then uval will be treated as const pointer and copied (packed) + * into pbuf, between startbit and endbit. + * If UNPACK, then pbuf will be treated as const pointer and the logical + * value between startbit and endbit will be copied (unpacked) to uval. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Note: this is deprecated, prefer to use pack() or unpack() in new code. + * + * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming + * correct usage, return code may be discarded. + * If op is PACK, pbuf is modified. + * If op is UNPACK, uval is modified. + */ +int packing(void *pbuf, u64 *uval, int startbit, int endbit, size_t pbuflen, + enum packing_op op, u8 quirks) +{ + if (op == PACK) + return pack(pbuf, *uval, startbit, endbit, pbuflen, quirks); + + return unpack(pbuf, uval, startbit, endbit, pbuflen, quirks); +} + +static u64 ustruct_field_to_u64(const void *ustruct, size_t field_offset, + size_t field_size) +{ + switch (field_size) { + case 1: + return *((u8 *)(ustruct + field_offset)); + case 2: + return *((u16 *)(ustruct + field_offset)); + case 4: + return *((u32 *)(ustruct + field_offset)); + default: + return *((u64 *)(ustruct + field_offset)); + } +} + +static void u64_to_ustruct_field(void *ustruct, size_t field_offset, + size_t field_size, u64 uval) +{ + switch (field_size) { + case 1: + *((u8 *)(ustruct + field_offset)) = uval; + break; + case 2: + *((u16 *)(ustruct + field_offset)) = uval; + break; + case 4: + *((u32 *)(ustruct + field_offset)) = uval; + break; + default: + *((u64 *)(ustruct + field_offset)) = uval; + break; + } +} + +/** + * pack_fields_u8 - Pack array of fields + * + * @pbuf: Pointer to a buffer holding the packed value. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @ustruct: Pointer to CPU-readable structure holding the unpacked value. + * It is expected (but not checked) that this has the same data type + * as all struct packed_field_u8 definitions. + * @fields: Array of packed_field_u8 field definition. They must not overlap. + * @num_fields: Length of @fields array. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Use the pack_fields() macro instead of calling this directly. + */ +void pack_fields_u8(void *pbuf, size_t pbuflen, const void *ustruct, + const struct packed_field_u8 *fields, size_t num_fields, + u8 quirks) +{ + __pack_fields(pbuf, pbuflen, ustruct, fields, num_fields, quirks); +} + +/** + * pack_fields_u16 - Pack array of fields + * + * @pbuf: Pointer to a buffer holding the packed value. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @ustruct: Pointer to CPU-readable structure holding the unpacked value. + * It is expected (but not checked) that this has the same data type + * as all struct packed_field_u16 definitions. + * @fields: Array of packed_field_u16 field definitions. They must not overlap. + * @num_fields: Length of @fields array. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Use the pack_fields() macro instead of calling this directly. + */ +void pack_fields_u16(void *pbuf, size_t pbuflen, const void *ustruct, + const struct packed_field_u16 *fields, size_t num_fields, + u8 quirks) +{ + __pack_fields(pbuf, pbuflen, ustruct, fields, num_fields, quirks); +} + +/** + * unpack_fields_u8 - Unpack array of fields + * + * @pbuf: Pointer to a buffer holding the packed value. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @ustruct: Pointer to CPU-readable structure holding the unpacked value. + * It is expected (but not checked) that this has the same data type + * as all struct packed_field_u8 definitions. + * @fields: Array of packed_field_u8 field definitions. They must not overlap. + * @num_fields: Length of @fields array. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Use the unpack_fields() macro instead of calling this directly. + */ +void unpack_fields_u8(const void *pbuf, size_t pbuflen, void *ustruct, + const struct packed_field_u8 *fields, size_t num_fields, + u8 quirks) +{ + __unpack_fields(pbuf, pbuflen, ustruct, fields, num_fields, quirks); +} + +/** + * unpack_fields_u16 - Unpack array of fields + * + * @pbuf: Pointer to a buffer holding the packed value. + * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf. + * @ustruct: Pointer to CPU-readable structure holding the unpacked value. + * It is expected (but not checked) that this has the same data type + * as all struct packed_field_u16 definitions. + * @fields: Array of packed_field_u16 field definitions. They must not overlap. + * @num_fields: Length of @fields array. + * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and + * QUIRK_MSB_ON_THE_RIGHT. + * + * Use the unpack_fields() macro instead of calling this directly. + */ +void unpack_fields_u16(const void *pbuf, size_t pbuflen, void *ustruct, + const struct packed_field_u16 *fields, size_t num_fields, + u8 quirks) +{ + __unpack_fields(pbuf, pbuflen, ustruct, fields, num_fields, quirks); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.h new file mode 100644 index 0000000000..d0e0764065 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_packing.h @@ -0,0 +1,466 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2016-2018 NXP + * Copyright (c) 2018-2019, Vladimir Oltean + */ +#ifndef _KCOMPAT_PACKING_H_ +#define _KCOMPAT_PACKING_H_ + +#include +#include + +#define GEN_PACKED_FIELD_STRUCT(__type) \ + struct packed_field_ ## __type { \ + __type startbit; \ + __type endbit; \ + __type offset; \ + __type size; \ + } + +/* struct packed_field_u8. Use with bit offsets < 256, buffers < 32B and + * unpacked structures < 256B. + */ +GEN_PACKED_FIELD_STRUCT(u8); + +/* struct packed_field_u16. Use with bit offsets < 65536, buffers < 8KB and + * unpacked structures < 64KB. + */ +GEN_PACKED_FIELD_STRUCT(u16); + +#define PACKED_FIELD(start, end, struct_name, struct_field) \ +{ \ + (start), \ + (end), \ + offsetof(struct_name, struct_field), \ + sizeof_field(struct_name, struct_field), \ +} + +#define CHECK_PACKED_FIELD_OVERLAP(fields, index1, index2) ({ \ + typeof(&(fields)[0]) __f = (fields); \ + typeof(__f[0]) _f1 = __f[index1]; typeof(__f[0]) _f2 = __f[index2]; \ + const bool _ascending = __f[0].startbit < __f[1].startbit; \ + BUILD_BUG_ON_MSG(_ascending && _f1.startbit >= _f2.startbit, \ + __stringify(fields) " field " __stringify(index2) \ + " breaks ascending order"); \ + BUILD_BUG_ON_MSG(!_ascending && _f1.startbit <= _f2.startbit, \ + __stringify(fields) " field " __stringify(index2) \ + " breaks descending order"); \ + BUILD_BUG_ON_MSG(max(_f1.endbit, _f2.endbit) <= \ + min(_f1.startbit, _f2.startbit), \ + __stringify(fields) " field " __stringify(index2) \ + " overlaps with previous field"); \ +}) + +#define CHECK_PACKED_FIELD(fields, index) ({ \ + typeof(&(fields)[0]) _f = (fields); \ + typeof(_f[0]) __f = _f[index]; \ + BUILD_BUG_ON_MSG(__f.startbit < __f.endbit, \ + __stringify(fields) " field " __stringify(index) \ + " start bit must not be smaller than end bit"); \ + BUILD_BUG_ON_MSG(__f.size != 1 && __f.size != 2 && \ + __f.size != 4 && __f.size != 8, \ + __stringify(fields) " field " __stringify(index) \ + " has unsupported unpacked storage size"); \ + BUILD_BUG_ON_MSG(__f.startbit - __f.endbit >= BITS_PER_BYTE * __f.size, \ + __stringify(fields) " field " __stringify(index) \ + " exceeds unpacked storage size"); \ + __builtin_choose_expr(index != 0, \ + CHECK_PACKED_FIELD_OVERLAP(fields, index - 1, index), \ + 1); \ +}) + +/* Note that the packed fields may be either in ascending or descending order. + * Thus, we must check that both the first and last field wit within the + * packed buffer size. + */ +#define CHECK_PACKED_FIELDS_SIZE(fields, pbuflen) ({ \ + typeof(&(fields)[0]) _f = (fields); \ + typeof(pbuflen) _len = (pbuflen); \ + const size_t num_fields = ARRAY_SIZE(fields); \ + BUILD_BUG_ON_MSG(!__builtin_constant_p(_len), \ + __stringify(fields) " pbuflen " __stringify(pbuflen) \ + " must be a compile time constant"); \ + BUILD_BUG_ON_MSG(_f[0].startbit >= BITS_PER_BYTE * _len, \ + __stringify(fields) " first field exceeds packed buffer size"); \ + BUILD_BUG_ON_MSG(_f[num_fields - 1].startbit >= BITS_PER_BYTE * _len, \ + __stringify(fields) " last field exceeds packed buffer size"); \ +}) + +#define QUIRK_MSB_ON_THE_RIGHT BIT(0) +#define QUIRK_LITTLE_ENDIAN BIT(1) +#define QUIRK_LSW32_IS_FIRST BIT(2) + +enum packing_op { + PACK, + UNPACK, +}; + +int packing(void *pbuf, u64 *uval, int startbit, int endbit, size_t pbuflen, + enum packing_op op, u8 quirks); + +int pack(void *pbuf, u64 uval, size_t startbit, size_t endbit, size_t pbuflen, + u8 quirks); + +int unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit, + size_t pbuflen, u8 quirks); + +void pack_fields_u8(void *pbuf, size_t pbuflen, const void *ustruct, + const struct packed_field_u8 *fields, size_t num_fields, + u8 quirks); + +void pack_fields_u16(void *pbuf, size_t pbuflen, const void *ustruct, + const struct packed_field_u16 *fields, size_t num_fields, + u8 quirks); + +void unpack_fields_u8(const void *pbuf, size_t pbuflen, void *ustruct, + const struct packed_field_u8 *fields, size_t num_fields, + u8 quirks); + +void unpack_fields_u16(const void *pbuf, size_t pbuflen, void *ustruct, + const struct packed_field_u16 *fields, size_t num_fields, + u8 quirks); + +/* Do not hand-edit the following packed field check macros! + * + * They are generated using scripts/gen_packed_field_checks.c, which may be + * built via "make scripts_gen_packed_field_checks". If larger macro sizes are + * needed in the future, please use this program to re-generate the macros and + * insert them here. + */ + +#define CHECK_PACKED_FIELDS_1(fields) \ + CHECK_PACKED_FIELD(fields, 0) + +#define CHECK_PACKED_FIELDS_2(fields) do { \ + CHECK_PACKED_FIELDS_1(fields); \ + CHECK_PACKED_FIELD(fields, 1); \ +} while (0) + +#define CHECK_PACKED_FIELDS_3(fields) do { \ + CHECK_PACKED_FIELDS_2(fields); \ + CHECK_PACKED_FIELD(fields, 2); \ +} while (0) + +#define CHECK_PACKED_FIELDS_4(fields) do { \ + CHECK_PACKED_FIELDS_3(fields); \ + CHECK_PACKED_FIELD(fields, 3); \ +} while (0) + +#define CHECK_PACKED_FIELDS_5(fields) do { \ + CHECK_PACKED_FIELDS_4(fields); \ + CHECK_PACKED_FIELD(fields, 4); \ +} while (0) + +#define CHECK_PACKED_FIELDS_6(fields) do { \ + CHECK_PACKED_FIELDS_5(fields); \ + CHECK_PACKED_FIELD(fields, 5); \ +} while (0) + +#define CHECK_PACKED_FIELDS_7(fields) do { \ + CHECK_PACKED_FIELDS_6(fields); \ + CHECK_PACKED_FIELD(fields, 6); \ +} while (0) + +#define CHECK_PACKED_FIELDS_8(fields) do { \ + CHECK_PACKED_FIELDS_7(fields); \ + CHECK_PACKED_FIELD(fields, 7); \ +} while (0) + +#define CHECK_PACKED_FIELDS_9(fields) do { \ + CHECK_PACKED_FIELDS_8(fields); \ + CHECK_PACKED_FIELD(fields, 8); \ +} while (0) + +#define CHECK_PACKED_FIELDS_10(fields) do { \ + CHECK_PACKED_FIELDS_9(fields); \ + CHECK_PACKED_FIELD(fields, 9); \ +} while (0) + +#define CHECK_PACKED_FIELDS_11(fields) do { \ + CHECK_PACKED_FIELDS_10(fields); \ + CHECK_PACKED_FIELD(fields, 10); \ +} while (0) + +#define CHECK_PACKED_FIELDS_12(fields) do { \ + CHECK_PACKED_FIELDS_11(fields); \ + CHECK_PACKED_FIELD(fields, 11); \ +} while (0) + +#define CHECK_PACKED_FIELDS_13(fields) do { \ + CHECK_PACKED_FIELDS_12(fields); \ + CHECK_PACKED_FIELD(fields, 12); \ +} while (0) + +#define CHECK_PACKED_FIELDS_14(fields) do { \ + CHECK_PACKED_FIELDS_13(fields); \ + CHECK_PACKED_FIELD(fields, 13); \ +} while (0) + +#define CHECK_PACKED_FIELDS_15(fields) do { \ + CHECK_PACKED_FIELDS_14(fields); \ + CHECK_PACKED_FIELD(fields, 14); \ +} while (0) + +#define CHECK_PACKED_FIELDS_16(fields) do { \ + CHECK_PACKED_FIELDS_15(fields); \ + CHECK_PACKED_FIELD(fields, 15); \ +} while (0) + +#define CHECK_PACKED_FIELDS_17(fields) do { \ + CHECK_PACKED_FIELDS_16(fields); \ + CHECK_PACKED_FIELD(fields, 16); \ +} while (0) + +#define CHECK_PACKED_FIELDS_18(fields) do { \ + CHECK_PACKED_FIELDS_17(fields); \ + CHECK_PACKED_FIELD(fields, 17); \ +} while (0) + +#define CHECK_PACKED_FIELDS_19(fields) do { \ + CHECK_PACKED_FIELDS_18(fields); \ + CHECK_PACKED_FIELD(fields, 18); \ +} while (0) + +#define CHECK_PACKED_FIELDS_20(fields) do { \ + CHECK_PACKED_FIELDS_19(fields); \ + CHECK_PACKED_FIELD(fields, 19); \ +} while (0) + +#define CHECK_PACKED_FIELDS_21(fields) do { \ + CHECK_PACKED_FIELDS_20(fields); \ + CHECK_PACKED_FIELD(fields, 20); \ +} while (0) + +#define CHECK_PACKED_FIELDS_22(fields) do { \ + CHECK_PACKED_FIELDS_21(fields); \ + CHECK_PACKED_FIELD(fields, 21); \ +} while (0) + +#define CHECK_PACKED_FIELDS_23(fields) do { \ + CHECK_PACKED_FIELDS_22(fields); \ + CHECK_PACKED_FIELD(fields, 22); \ +} while (0) + +#define CHECK_PACKED_FIELDS_24(fields) do { \ + CHECK_PACKED_FIELDS_23(fields); \ + CHECK_PACKED_FIELD(fields, 23); \ +} while (0) + +#define CHECK_PACKED_FIELDS_25(fields) do { \ + CHECK_PACKED_FIELDS_24(fields); \ + CHECK_PACKED_FIELD(fields, 24); \ +} while (0) + +#define CHECK_PACKED_FIELDS_26(fields) do { \ + CHECK_PACKED_FIELDS_25(fields); \ + CHECK_PACKED_FIELD(fields, 25); \ +} while (0) + +#define CHECK_PACKED_FIELDS_27(fields) do { \ + CHECK_PACKED_FIELDS_26(fields); \ + CHECK_PACKED_FIELD(fields, 26); \ +} while (0) + +#define CHECK_PACKED_FIELDS_28(fields) do { \ + CHECK_PACKED_FIELDS_27(fields); \ + CHECK_PACKED_FIELD(fields, 27); \ +} while (0) + +#define CHECK_PACKED_FIELDS_29(fields) do { \ + CHECK_PACKED_FIELDS_28(fields); \ + CHECK_PACKED_FIELD(fields, 28); \ +} while (0) + +#define CHECK_PACKED_FIELDS_30(fields) do { \ + CHECK_PACKED_FIELDS_29(fields); \ + CHECK_PACKED_FIELD(fields, 29); \ +} while (0) + +#define CHECK_PACKED_FIELDS_31(fields) do { \ + CHECK_PACKED_FIELDS_30(fields); \ + CHECK_PACKED_FIELD(fields, 30); \ +} while (0) + +#define CHECK_PACKED_FIELDS_32(fields) do { \ + CHECK_PACKED_FIELDS_31(fields); \ + CHECK_PACKED_FIELD(fields, 31); \ +} while (0) + +#define CHECK_PACKED_FIELDS_33(fields) do { \ + CHECK_PACKED_FIELDS_32(fields); \ + CHECK_PACKED_FIELD(fields, 32); \ +} while (0) + +#define CHECK_PACKED_FIELDS_34(fields) do { \ + CHECK_PACKED_FIELDS_33(fields); \ + CHECK_PACKED_FIELD(fields, 33); \ +} while (0) + +#define CHECK_PACKED_FIELDS_35(fields) do { \ + CHECK_PACKED_FIELDS_34(fields); \ + CHECK_PACKED_FIELD(fields, 34); \ +} while (0) + +#define CHECK_PACKED_FIELDS_36(fields) do { \ + CHECK_PACKED_FIELDS_35(fields); \ + CHECK_PACKED_FIELD(fields, 35); \ +} while (0) + +#define CHECK_PACKED_FIELDS_37(fields) do { \ + CHECK_PACKED_FIELDS_36(fields); \ + CHECK_PACKED_FIELD(fields, 36); \ +} while (0) + +#define CHECK_PACKED_FIELDS_38(fields) do { \ + CHECK_PACKED_FIELDS_37(fields); \ + CHECK_PACKED_FIELD(fields, 37); \ +} while (0) + +#define CHECK_PACKED_FIELDS_39(fields) do { \ + CHECK_PACKED_FIELDS_38(fields); \ + CHECK_PACKED_FIELD(fields, 38); \ +} while (0) + +#define CHECK_PACKED_FIELDS_40(fields) do { \ + CHECK_PACKED_FIELDS_39(fields); \ + CHECK_PACKED_FIELD(fields, 39); \ +} while (0) + +#define CHECK_PACKED_FIELDS_41(fields) do { \ + CHECK_PACKED_FIELDS_40(fields); \ + CHECK_PACKED_FIELD(fields, 40); \ +} while (0) + +#define CHECK_PACKED_FIELDS_42(fields) do { \ + CHECK_PACKED_FIELDS_41(fields); \ + CHECK_PACKED_FIELD(fields, 41); \ +} while (0) + +#define CHECK_PACKED_FIELDS_43(fields) do { \ + CHECK_PACKED_FIELDS_42(fields); \ + CHECK_PACKED_FIELD(fields, 42); \ +} while (0) + +#define CHECK_PACKED_FIELDS_44(fields) do { \ + CHECK_PACKED_FIELDS_43(fields); \ + CHECK_PACKED_FIELD(fields, 43); \ +} while (0) + +#define CHECK_PACKED_FIELDS_45(fields) do { \ + CHECK_PACKED_FIELDS_44(fields); \ + CHECK_PACKED_FIELD(fields, 44); \ +} while (0) + +#define CHECK_PACKED_FIELDS_46(fields) do { \ + CHECK_PACKED_FIELDS_45(fields); \ + CHECK_PACKED_FIELD(fields, 45); \ +} while (0) + +#define CHECK_PACKED_FIELDS_47(fields) do { \ + CHECK_PACKED_FIELDS_46(fields); \ + CHECK_PACKED_FIELD(fields, 46); \ +} while (0) + +#define CHECK_PACKED_FIELDS_48(fields) do { \ + CHECK_PACKED_FIELDS_47(fields); \ + CHECK_PACKED_FIELD(fields, 47); \ +} while (0) + +#define CHECK_PACKED_FIELDS_49(fields) do { \ + CHECK_PACKED_FIELDS_48(fields); \ + CHECK_PACKED_FIELD(fields, 48); \ +} while (0) + +#define CHECK_PACKED_FIELDS_50(fields) do { \ + CHECK_PACKED_FIELDS_49(fields); \ + CHECK_PACKED_FIELD(fields, 49); \ +} while (0) + +#define CHECK_PACKED_FIELDS(fields) \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 1, ({ CHECK_PACKED_FIELDS_1(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 2, ({ CHECK_PACKED_FIELDS_2(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 3, ({ CHECK_PACKED_FIELDS_3(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 4, ({ CHECK_PACKED_FIELDS_4(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 5, ({ CHECK_PACKED_FIELDS_5(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 6, ({ CHECK_PACKED_FIELDS_6(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 7, ({ CHECK_PACKED_FIELDS_7(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 8, ({ CHECK_PACKED_FIELDS_8(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 9, ({ CHECK_PACKED_FIELDS_9(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 10, ({ CHECK_PACKED_FIELDS_10(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 11, ({ CHECK_PACKED_FIELDS_11(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 12, ({ CHECK_PACKED_FIELDS_12(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 13, ({ CHECK_PACKED_FIELDS_13(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 14, ({ CHECK_PACKED_FIELDS_14(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 15, ({ CHECK_PACKED_FIELDS_15(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 16, ({ CHECK_PACKED_FIELDS_16(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 17, ({ CHECK_PACKED_FIELDS_17(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 18, ({ CHECK_PACKED_FIELDS_18(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 19, ({ CHECK_PACKED_FIELDS_19(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 20, ({ CHECK_PACKED_FIELDS_20(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 21, ({ CHECK_PACKED_FIELDS_21(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 22, ({ CHECK_PACKED_FIELDS_22(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 23, ({ CHECK_PACKED_FIELDS_23(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 24, ({ CHECK_PACKED_FIELDS_24(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 25, ({ CHECK_PACKED_FIELDS_25(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 26, ({ CHECK_PACKED_FIELDS_26(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 27, ({ CHECK_PACKED_FIELDS_27(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 28, ({ CHECK_PACKED_FIELDS_28(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 29, ({ CHECK_PACKED_FIELDS_29(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 30, ({ CHECK_PACKED_FIELDS_30(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 31, ({ CHECK_PACKED_FIELDS_31(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 32, ({ CHECK_PACKED_FIELDS_32(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 33, ({ CHECK_PACKED_FIELDS_33(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 34, ({ CHECK_PACKED_FIELDS_34(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 35, ({ CHECK_PACKED_FIELDS_35(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 36, ({ CHECK_PACKED_FIELDS_36(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 37, ({ CHECK_PACKED_FIELDS_37(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 38, ({ CHECK_PACKED_FIELDS_38(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 39, ({ CHECK_PACKED_FIELDS_39(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 40, ({ CHECK_PACKED_FIELDS_40(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 41, ({ CHECK_PACKED_FIELDS_41(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 42, ({ CHECK_PACKED_FIELDS_42(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 43, ({ CHECK_PACKED_FIELDS_43(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 44, ({ CHECK_PACKED_FIELDS_44(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 45, ({ CHECK_PACKED_FIELDS_45(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 46, ({ CHECK_PACKED_FIELDS_46(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 47, ({ CHECK_PACKED_FIELDS_47(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 48, ({ CHECK_PACKED_FIELDS_48(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 49, ({ CHECK_PACKED_FIELDS_49(fields); }), \ + __builtin_choose_expr(ARRAY_SIZE(fields) == 50, ({ CHECK_PACKED_FIELDS_50(fields); }), \ + ({ BUILD_BUG_ON_MSG(1, "CHECK_PACKED_FIELDS() must be regenerated to support array sizes larger than 50."); }) \)))))))))))))))))))))))))))))))))))))))))))))))))) + +/* End of generated content */ + +#define pack_fields(pbuf, pbuflen, ustruct, fields, quirks) \ + ({ \ + CHECK_PACKED_FIELDS(fields); \ + CHECK_PACKED_FIELDS_SIZE((fields), (pbuflen)); \ + __builtin_choose_expr(__builtin_types_compatible_p(typeof(*fields), struct packed_field_u8), \ + pack_fields_u8((pbuf), (pbuflen), (ustruct), \ + (const struct packed_field_u8 *)(fields), \ + ARRAY_SIZE(fields), (quirks)), \ + __builtin_choose_expr(__builtin_types_compatible_p(typeof(*fields), struct packed_field_u16), \ + pack_fields_u16((pbuf), (pbuflen), (ustruct), \ + (const struct packed_field_u16 *)(fields), \ + ARRAY_SIZE(fields), (quirks)), \ + ({ BUILD_BUG_ON_MSG(1, "pack_fields called with an unrecognized fields array type."); (void)0; }))); \ + }) + +#define unpack_fields(pbuf, pbuflen, ustruct, fields, quirks) \ + ({ \ + CHECK_PACKED_FIELDS(fields); \ + CHECK_PACKED_FIELDS_SIZE((fields), (pbuflen)); \ + __builtin_choose_expr(__builtin_types_compatible_p(typeof(*fields), struct packed_field_u8), \ + unpack_fields_u8((pbuf), (pbuflen), (ustruct), \ + (const struct packed_field_u8 *)(fields), \ + ARRAY_SIZE(fields), (quirks)), \ + __builtin_choose_expr(__builtin_types_compatible_p(typeof(*fields), struct packed_field_u16), \ + unpack_fields_u16((pbuf), (pbuflen), (ustruct), \ + (const struct packed_field_u16 *)(fields), \ + ARRAY_SIZE(fields), (quirks)), \ + ({ BUILD_BUG_ON_MSG(1, "unpack_fields called with an unrecognized fields array type."); (void)0; }))); \ + }) + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.c new file mode 100644 index 0000000000..2ae4ccb3aa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.c @@ -0,0 +1,1134 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2020 - 2023 Intel Corporation. */ + +/* This is taken from upstream "lib/pldmfw/pldmfw.c" */ + +#include "kcompat.h" + +#ifdef HAVE_LINUX_UNALIGNED_HEADER +#include +#else /* HAVE_LINUX_UNALIGNED_HEADER */ +#include +#endif /* !HAVE_LINUX_UNALIGNED_HEADER */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat_pldmfw.h" + +#if IS_ENABLED(CONFIG_PLDMFW) +#error "CONFIG_PLDMFW is enabled, use builtin lib/pldmfw instead." +#endif + +/* This section is taken from upstream "lib/pldmfw/pldmfw_private.h" */ + +/* The following data structures define the layout of a firmware binary + * following the "PLDM For Firmware Update Specification", DMTF standard + * #DSP0267. + * + * pldmfw.c uses these structures to implement a simple engine that will parse + * a fw binary file in this format and perform a firmware update for a given + * device. + * + * Due to the variable sized data layout, alignment of fields within these + * structures is not guaranteed when reading. For this reason, all multi-byte + * field accesses should be done using the unaligned access macros. + * Additionally, the standard specifies that multi-byte fields are in + * LittleEndian format. + * + * The structure definitions are not made public, in order to keep direct + * accesses within code that is prepared to deal with the limitation of + * unaligned access. + */ + +/* UUID for PLDM firmware packages: f018878c-cb7d-4943-9800-a02f059aca02 */ +static const uuid_t pldm_firmware_header_id = + UUID_INIT(0xf018878c, 0xcb7d, 0x4943, + 0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02); + +/* Revision number of the PLDM header format this code supports */ +#define PACKAGE_HEADER_FORMAT_REVISION 0x01 + +/* timestamp104 structure defined in PLDM Base specification */ +#define PLDM_TIMESTAMP_SIZE 13 +struct __pldm_timestamp { + u8 b[PLDM_TIMESTAMP_SIZE]; +}; + +/* Package Header Information */ +struct __pldm_header { + uuid_t id; /* PackageHeaderIdentifier */ + u8 revision; /* PackageHeaderFormatRevision */ + __le16 size; /* PackageHeaderSize */ + struct __pldm_timestamp release_date; /* PackageReleaseDateTime */ + __le16 component_bitmap_len; /* ComponentBitmapBitLength */ + u8 version_type; /* PackageVersionStringType */ + u8 version_len; /* PackageVersionStringLength */ + + /* + * DSP0267 also includes the following variable length fields at the + * end of this structure: + * + * PackageVersionString, length is version_len. + * + * The total size of this section is + * sizeof(pldm_header) + version_len; + */ + u8 version_string[]; /* PackageVersionString */ +} __packed __aligned(1); + +/* Firmware Device ID Record */ +struct __pldmfw_record_info { + __le16 record_len; /* RecordLength */ + u8 descriptor_count; /* DescriptorCount */ + __le32 device_update_flags; /* DeviceUpdateOptionFlags */ + u8 version_type; /* ComponentImageSetVersionType */ + u8 version_len; /* ComponentImageSetVersionLength */ + __le16 package_data_len; /* FirmwareDevicePackageDataLength */ + + /* + * DSP0267 also includes the following variable length fields at the + * end of this structure: + * + * ApplicableComponents, length is component_bitmap_len from header + * ComponentImageSetVersionString, length is version_len + * RecordDescriptors, a series of TLVs with 16bit type and length + * FirmwareDevicePackageData, length is package_data_len + * + * The total size of each record is + * sizeof(pldmfw_record_info) + + * component_bitmap_len (converted to bytes!) + + * version_len + + * + + * package_data_len + */ + u8 variable_record_data[]; +} __packed __aligned(1); + +/* Firmware Descriptor Definition */ +struct __pldmfw_desc_tlv { + __le16 type; /* DescriptorType */ + __le16 size; /* DescriptorSize */ + u8 data[]; /* DescriptorData */ +} __aligned(1); + +/* Firmware Device Identification Area */ +struct __pldmfw_record_area { + u8 record_count; /* DeviceIDRecordCount */ + /* This is not a struct type because the size of each record varies */ + u8 records[]; +} __aligned(1); + +/* Individual Component Image Information */ +struct __pldmfw_component_info { + __le16 classification; /* ComponentClassfication */ + __le16 identifier; /* ComponentIdentifier */ + __le32 comparison_stamp; /* ComponentComparisonStamp */ + __le16 options; /* componentOptions */ + __le16 activation_method; /* RequestedComponentActivationMethod */ + __le32 location_offset; /* ComponentLocationOffset */ + __le32 size; /* ComponentSize */ + u8 version_type; /* ComponentVersionStringType */ + u8 version_len; /* ComponentVersionStringLength */ + + /* + * DSP0267 also includes the following variable length fields at the + * end of this structure: + * + * ComponentVersionString, length is version_len + * + * The total size of this section is + * sizeof(pldmfw_component_info) + version_len; + */ + u8 version_string[]; /* ComponentVersionString */ +} __packed __aligned(1); + +/* Component Image Information Area */ +struct __pldmfw_component_area { + __le16 component_image_count; + /* This is not a struct type because the component size varies */ + u8 components[]; +} __aligned(1); + +/** + * pldm_first_desc_tlv + * @start: byte offset of the start of the descriptor TLVs + * + * Converts the starting offset of the descriptor TLVs into a pointer to the + * first descriptor. + */ +#define pldm_first_desc_tlv(start) \ + ((const struct __pldmfw_desc_tlv *)(start)) + +/** + * pldm_desc_tlv_member + * @desc: pointer to a descriptor TLV + * @member: name of member to give pointer to + * + * Yields pointer to @member within, possibly unaligned, @desc + */ +#define pldm_desc_tlv_member(desc, member) \ + ((const u8 *)(desc) + offsetof(struct __pldmfw_desc_tlv, member)) + +/** + * pldm_next_desc_tlv + * @desc: pointer to a descriptor TLV + * + * Finds the pointer to the next descriptor following a given descriptor + */ +#define pldm_next_desc_tlv(desc) \ + ({ const void *desc_ = (desc); \ + ((const struct __pldmfw_desc_tlv *)( \ + pldm_desc_tlv_member(desc_, data) \ + + get_unaligned_le16(pldm_desc_tlv_member(desc_, size)))); }) + +/** + * pldm_for_each_desc_tlv + * @i: variable to store descriptor index + * @desc: variable to store descriptor pointer + * @start: byte offset of the start of the descriptors + * @count: the number of descriptors + * + * for loop macro to iterate over all of the descriptors of a given PLDM + * record. + */ +#define pldm_for_each_desc_tlv(i, desc, start, count) \ + for ((i) = 0, (desc) = pldm_first_desc_tlv(start); \ + (i) < (count); \ + (i)++, (desc) = pldm_next_desc_tlv(desc)) + +/** + * pldm_first_record + * @start: byte offset of the start of the PLDM records + * + * Converts a starting offset of the PLDM records into a pointer to the first + * record. + */ +#define pldm_first_record(start) \ + ((const struct __pldmfw_record_info *)(start)) + +/** + * pldm_next_record + * @record: pointer to a PLDM record + * + * Finds a pointer to the next record following a given record + */ +#define pldm_next_record(record) \ + ((const struct __pldmfw_record_info *) \ + ((const u8 *)(record) + get_unaligned_le16(&(record)->record_len))) + +/** + * pldm_for_each_record + * @i: variable to store record index + * @record: variable to store record pointer + * @start: byte offset of the start of the records + * @count: the number of records + * + * for loop macro to iterate over all of the records of a PLDM file. + */ +#define pldm_for_each_record(i, record, start, count) \ + for ((i) = 0, (record) = pldm_first_record(start); \ + (i) < (count); \ + (i)++, (record) = pldm_next_record(record)) + +/** + * pldm_first_component + * @start: byte offset of the start of the PLDM components + * + * Convert a starting offset of the PLDM components into a pointer to the + * first component + */ +#define pldm_first_component(start) \ + ((const struct __pldmfw_component_info *)(start)) + +/** + * pldm_next_component + * @component: pointer to a PLDM component + * + * Finds a pointer to the next component following a given component + */ +#define pldm_next_component(component) \ + ((const struct __pldmfw_component_info *)((component)->version_string + \ + (component)->version_len)) + +/** + * pldm_for_each_component + * @i: variable to store component index + * @component: variable to store component pointer + * @start: byte offset to the start of the first component + * @count: the number of components + * + * for loop macro to iterate over all of the components of a PLDM file. + */ +#define pldm_for_each_component(i, component, start, count) \ + for ((i) = 0, (component) = pldm_first_component(start); \ + (i) < (count); \ + (i)++, (component) = pldm_next_component(component)) + +/* End of lib/pldmfw/pldmfw_private.h */ + +/* Internal structure used to store details about the PLDM image file as it is + * being validated and processed. + */ +struct pldmfw_priv { + struct pldmfw *context; + const struct firmware *fw; + + /* current offset of firmware image */ + size_t offset; + + struct list_head records; + struct list_head components; + + /* PLDM Firmware Package Header */ + const struct __pldm_header *header; + u16 total_header_size; + + /* length of the component bitmap */ + u16 component_bitmap_len; + u16 bitmap_size; + + /* Start of the component image information */ + u16 component_count; + const u8 *component_start; + + /* Start pf the firmware device id records */ + const u8 *record_start; + u8 record_count; + + /* The CRC at the end of the package header */ + u32 header_crc; + + struct pldmfw_record *matching_record; +}; + +/** + * pldm_check_fw_space - Verify that the firmware image has space left + * @data: pointer to private data + * @offset: offset to start from + * @length: length to check for + * + * Verify that the firmware data can hold a chunk of bytes with the specified + * offset and length. + * + * Returns: zero on success, or -EFAULT if the image does not have enough + * space left to fit the expected length. + */ +static int +pldm_check_fw_space(struct pldmfw_priv *data, size_t offset, size_t length) +{ + size_t expected_size = offset + length; + struct device *dev = data->context->dev; + + if (data->fw->size < expected_size) { + dev_dbg(dev, "Firmware file size smaller than expected. Got %zu bytes, needed %zu bytes\n", + data->fw->size, expected_size); + return -EFAULT; + } + + return 0; +} + +/** + * pldm_move_fw_offset - Move the current firmware offset forward + * @data: pointer to private data + * @bytes_to_move: number of bytes to move the offset forward by + * + * Check that there is enough space past the current offset, and then move the + * offset forward by this ammount. + * + * Returns: zero on success, or -EFAULT if the image is too small to fit the + * expected length. + */ +static int +pldm_move_fw_offset(struct pldmfw_priv *data, size_t bytes_to_move) +{ + int err; + + err = pldm_check_fw_space(data, data->offset, bytes_to_move); + if (err) + return err; + + data->offset += bytes_to_move; + + return 0; +} + +/** + * pldm_parse_header - Validate and extract details about the PLDM header + * @data: pointer to private data + * + * Performs initial basic verification of the PLDM image, up to the first + * firmware record. + * + * This includes the following checks and extractions + * + * * Verify that the UUID at the start of the header matches the expected + * value as defined in the DSP0267 PLDM specification + * * Check that the revision is 0x01 + * * Extract the total header_size and verify that the image is large enough + * to contain at least the length of this header + * * Extract the size of the component bitmap length + * * Extract a pointer to the start of the record area + * + * Returns: zero on success, or a negative error code on failure. + */ +static int pldm_parse_header(struct pldmfw_priv *data) +{ + const struct __pldmfw_record_area *record_area; + struct device *dev = data->context->dev; + const struct __pldm_header *header; + size_t header_size; + int err; + + err = pldm_move_fw_offset(data, sizeof(*header)); + if (err) + return err; + + header = (const struct __pldm_header *)data->fw->data; + data->header = header; + + if (!uuid_equal(&header->id, &pldm_firmware_header_id)) { + dev_dbg(dev, "Invalid package header identifier. Expected UUID %pUB, but got %pUB\n", + &pldm_firmware_header_id, &header->id); + return -EINVAL; + } + + if (header->revision != PACKAGE_HEADER_FORMAT_REVISION) { + dev_dbg(dev, "Invalid package header revision. Expected revision %u but got %u\n", + PACKAGE_HEADER_FORMAT_REVISION, header->revision); + return -EOPNOTSUPP; + } + + data->total_header_size = get_unaligned_le16(&header->size); + header_size = data->total_header_size - sizeof(*header); + + err = pldm_check_fw_space(data, data->offset, header_size); + if (err) + return err; + + data->component_bitmap_len = + get_unaligned_le16(&header->component_bitmap_len); + + if (data->component_bitmap_len % 8 != 0) { + dev_dbg(dev, "Invalid component bitmap length. The length is %u, which is not a multiple of 8\n", + data->component_bitmap_len); + return -EINVAL; + } + + data->bitmap_size = data->component_bitmap_len / 8; + + err = pldm_move_fw_offset(data, header->version_len); + if (err) + return err; + + /* extract a pointer to the record area, which just follows the main + * PLDM header data. + */ + record_area = (const struct __pldmfw_record_area *)(data->fw->data + + data->offset); + + err = pldm_move_fw_offset(data, sizeof(*record_area)); + if (err) + return err; + + data->record_count = record_area->record_count; + data->record_start = record_area->records; + + return 0; +} + +/** + * pldm_check_desc_tlv_len - Check that the length matches expectation + * @data: pointer to image details + * @type: the descriptor type + * @size: the length from the descriptor header + * + * If the descriptor type is one of the documented descriptor types according + * to the standard, verify that the provided length matches. + * + * If the type is not recognized or is VENDOR_DEFINED, return zero. + * + * Returns: zero on success, or -EINVAL if the specified size of a standard + * TLV does not match the expected value defined for that TLV. + */ +static int +pldm_check_desc_tlv_len(struct pldmfw_priv *data, u16 type, u16 size) +{ + struct device *dev = data->context->dev; + u16 expected_size; + + switch (type) { + case PLDM_DESC_ID_PCI_VENDOR_ID: + case PLDM_DESC_ID_PCI_DEVICE_ID: + case PLDM_DESC_ID_PCI_SUBVENDOR_ID: + case PLDM_DESC_ID_PCI_SUBDEV_ID: + expected_size = 2; + break; + case PLDM_DESC_ID_PCI_REVISION_ID: + expected_size = 1; + break; + case PLDM_DESC_ID_PNP_VENDOR_ID: + expected_size = 3; + break; + case PLDM_DESC_ID_IANA_ENTERPRISE_ID: + case PLDM_DESC_ID_ACPI_VENDOR_ID: + case PLDM_DESC_ID_PNP_PRODUCT_ID: + case PLDM_DESC_ID_ACPI_PRODUCT_ID: + expected_size = 4; + break; + case PLDM_DESC_ID_UUID: + expected_size = 16; + break; + case PLDM_DESC_ID_VENDOR_DEFINED: + return 0; + default: + /* Do not report an error on an unexpected TLV */ + dev_dbg(dev, "Found unrecognized TLV type 0x%04x\n", type); + return 0; + } + + if (size != expected_size) { + dev_dbg(dev, "Found TLV type 0x%04x with unexpected length. Got %u bytes, but expected %u bytes\n", + type, size, expected_size); + return -EINVAL; + } + + return 0; +} + +/** + * pldm_parse_desc_tlvs - Check and skip past a number of TLVs + * @data: pointer to private data + * @record: pointer to the record this TLV belongs too + * @desc_count: descriptor count + * + * From the current offset, read and extract the descriptor TLVs, updating the + * current offset each time. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int +pldm_parse_desc_tlvs(struct pldmfw_priv *data, struct pldmfw_record *record, u8 desc_count) +{ + const struct __pldmfw_desc_tlv *__desc; + const u8 *desc_start; + u8 i; + + desc_start = data->fw->data + data->offset; + + pldm_for_each_desc_tlv(i, __desc, desc_start, desc_count) { + struct pldmfw_desc_tlv *desc; + int err; + u16 type, size; + + err = pldm_move_fw_offset(data, sizeof(*__desc)); + if (err) + return err; + + type = get_unaligned_le16(pldm_desc_tlv_member(__desc, type)); + + /* According to DSP0267, this only includes the data field */ + size = get_unaligned_le16(pldm_desc_tlv_member(__desc, size)); + + err = pldm_check_desc_tlv_len(data, type, size); + if (err) + return err; + + /* check that we have space and move the offset forward */ + err = pldm_move_fw_offset(data, size); + if (err) + return err; + + desc = (struct pldmfw_desc_tlv *)kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->type = type; + desc->size = size; + desc->data = pldm_desc_tlv_member(__desc, data); + + list_add_tail(&desc->entry, &record->descs); + } + + return 0; +} + +/** + * pldm_parse_one_record - Verify size of one PLDM record + * @data: pointer to image details + * @__record: pointer to the record to check + * + * This function checks that the record size does not exceed either the size + * of the firmware file or the total length specified in the header section. + * + * It also verifies that the recorded length of the start of the record + * matches the size calculated by adding the static structure length, the + * component bitmap length, the version string length, the length of all + * descriptor TLVs, and the length of the package data. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int +pldm_parse_one_record(struct pldmfw_priv *data, + const struct __pldmfw_record_info *__record) +{ + struct pldmfw_record *record; + size_t measured_length; + int err; + const u8 *bitmap_ptr; + u16 record_len; + int i; + + /* Make a copy and insert it into the record list */ + record = (struct pldmfw_record *)kzalloc(sizeof(*record), GFP_KERNEL); + if (!record) + return -ENOMEM; + + INIT_LIST_HEAD(&record->descs); + list_add_tail(&record->entry, &data->records); + + /* Then check that we have space and move the offset */ + err = pldm_move_fw_offset(data, sizeof(*__record)); + if (err) + return err; + + record_len = get_unaligned_le16(&__record->record_len); + record->package_data_len = get_unaligned_le16(&__record->package_data_len); + record->version_len = __record->version_len; + record->version_type = __record->version_type; + + bitmap_ptr = data->fw->data + data->offset; + + /* check that we have space for the component bitmap length */ + err = pldm_move_fw_offset(data, data->bitmap_size); + if (err) + return err; + + record->component_bitmap_len = data->component_bitmap_len; + record->component_bitmap = bitmap_zalloc(record->component_bitmap_len, + GFP_KERNEL); + if (!record->component_bitmap) + return -ENOMEM; + + for (i = 0; i < data->bitmap_size; i++) + bitmap_set_value8(record->component_bitmap, bitmap_ptr[i], i * 8); + + record->version_string = data->fw->data + data->offset; + + err = pldm_move_fw_offset(data, record->version_len); + if (err) + return err; + + /* Scan through the descriptor TLVs and find the end */ + err = pldm_parse_desc_tlvs(data, record, __record->descriptor_count); + if (err) + return err; + + record->package_data = data->fw->data + data->offset; + + err = pldm_move_fw_offset(data, record->package_data_len); + if (err) + return err; + + measured_length = data->offset - ((const u8 *)__record - data->fw->data); + if (measured_length != record_len) { + dev_dbg(data->context->dev, "Unexpected record length. Measured record length is %zu bytes, expected length is %u bytes\n", + measured_length, record_len); + return -EFAULT; + } + + return 0; +} + +/** + * pldm_parse_records - Locate the start of the component area + * @data: pointer to private data + * + * Extract the record count, and loop through each record, searching for the + * component area. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int pldm_parse_records(struct pldmfw_priv *data) +{ + const struct __pldmfw_component_area *component_area; + const struct __pldmfw_record_info *record; + int err; + u8 i; + + pldm_for_each_record(i, record, data->record_start, data->record_count) { + err = pldm_parse_one_record(data, record); + if (err) + return err; + } + + /* Extract a pointer to the component area, which just follows the + * PLDM device record data. + */ + component_area = (const struct __pldmfw_component_area *)(data->fw->data + data->offset); + + err = pldm_move_fw_offset(data, sizeof(*component_area)); + if (err) + return err; + + data->component_count = + get_unaligned_le16(&component_area->component_image_count); + data->component_start = component_area->components; + + return 0; +} + +/** + * pldm_parse_components - Locate the CRC header checksum + * @data: pointer to private data + * + * Extract the component count, and find the pointer to the component area. + * Scan through each component searching for the end, which should point to + * the package header checksum. + * + * Extract the package header CRC and save it for verification. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int pldm_parse_components(struct pldmfw_priv *data) +{ + const struct __pldmfw_component_info *__component; + struct device *dev = data->context->dev; + const u8 *header_crc_ptr; + int err; + u8 i; + + pldm_for_each_component(i, __component, data->component_start, data->component_count) { + struct pldmfw_component *component; + u32 offset, size; + + err = pldm_move_fw_offset(data, sizeof(*__component)); + if (err) + return err; + + err = pldm_move_fw_offset(data, __component->version_len); + if (err) + return err; + + offset = get_unaligned_le32(&__component->location_offset); + size = get_unaligned_le32(&__component->size); + + err = pldm_check_fw_space(data, offset, size); + if (err) + return err; + + component = (struct pldmfw_component *)kzalloc(sizeof(*component), GFP_KERNEL); + if (!component) + return -ENOMEM; + + component->index = i; + component->classification = get_unaligned_le16(&__component->classification); + component->identifier = get_unaligned_le16(&__component->identifier); + component->comparison_stamp = get_unaligned_le32(&__component->comparison_stamp); + component->options = get_unaligned_le16(&__component->options); + component->activation_method = get_unaligned_le16(&__component->activation_method); + component->version_type = __component->version_type; + component->version_len = __component->version_len; + component->version_string = __component->version_string; + component->component_data = data->fw->data + offset; + component->component_size = size; + + list_add_tail(&component->entry, &data->components); + } + + header_crc_ptr = data->fw->data + data->offset; + + err = pldm_move_fw_offset(data, sizeof(data->header_crc)); + if (err) + return err; + + /* Make sure that we reached the expected offset */ + if (data->offset != data->total_header_size) { + dev_dbg(dev, "Invalid firmware header size. Expected %u but got %zu\n", + data->total_header_size, data->offset); + return -EFAULT; + } + + data->header_crc = get_unaligned_le32(header_crc_ptr); + + return 0; +} + +/** + * pldm_verify_header_crc - Verify that the CRC in the header matches + * @data: pointer to private data + * + * Calculates the 32-bit CRC using the standard IEEE 802.3 CRC polynomial and + * compares it to the value stored in the header. + * + * Returns: zero on success if the CRC matches, or -EBADMSG on an invalid CRC. + */ +static int pldm_verify_header_crc(struct pldmfw_priv *data) +{ + struct device *dev = data->context->dev; + u32 calculated_crc; + size_t length; + + /* Calculate the 32-bit CRC of the header header contents up to but + * not including the checksum. Note that the Linux crc32_le function + * does not perform an expected final XOR. + */ + length = data->offset - sizeof(data->header_crc); + calculated_crc = crc32_le(~0, data->fw->data, length) ^ ~0; + + if (calculated_crc != data->header_crc) { + dev_dbg(dev, "Invalid CRC in firmware header. Got 0x%08x but expected 0x%08x\n", + calculated_crc, data->header_crc); + return -EBADMSG; + } + + return 0; +} + +/** + * pldmfw_free_priv - Free memory allocated while parsing the PLDM image + * @data: pointer to the PLDM data structure + * + * Loops through and clears all allocated memory associated with each + * allocated descriptor, record, and component. + */ +static void pldmfw_free_priv(struct pldmfw_priv *data) +{ + struct pldmfw_component *component, *c_safe; + struct pldmfw_record *record, *r_safe; + struct pldmfw_desc_tlv *desc, *d_safe; + + list_for_each_entry_safe(component, c_safe, &data->components, entry) { + list_del(&component->entry); + kfree(component); + } + + list_for_each_entry_safe(record, r_safe, &data->records, entry) { + list_for_each_entry_safe(desc, d_safe, &record->descs, entry) { + list_del(&desc->entry); + kfree(desc); + } + + if (record->component_bitmap) { + bitmap_free(record->component_bitmap); + record->component_bitmap = NULL; + } + + list_del(&record->entry); + kfree(record); + } +} + +/** + * pldm_parse_image - parse and extract details from PLDM image + * @data: pointer to private data + * + * Verify that the firmware file contains valid data for a PLDM firmware + * file. Extract useful pointers and data from the firmware file and store + * them in the data structure. + * + * The PLDM firmware file format is defined in DMTF DSP0267 1.0.0. Care + * should be taken to use get_unaligned_le* when accessing data from the + * pointers in data. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int pldm_parse_image(struct pldmfw_priv *data) +{ + int err; + + if (WARN_ON(!(data->context->dev && data->fw->data && data->fw->size))) + return -EINVAL; + + err = pldm_parse_header(data); + if (err) + return err; + + err = pldm_parse_records(data); + if (err) + return err; + + err = pldm_parse_components(data); + if (err) + return err; + + return pldm_verify_header_crc(data); +} + +/* these are u32 so that we can store PCI_ANY_ID */ +struct pldm_pci_record_id { + int vendor; + int device; + int subsystem_vendor; + int subsystem_device; +}; + +/** + * pldmfw_op_pci_match_record - Check if a PCI device matches the record + * @context: PLDM fw update structure + * @record: list of records extracted from the PLDM image + * + * Determine of the PCI device associated with this device matches the record + * data provided. + * + * Searches the descriptor TLVs and extracts the relevant descriptor data into + * a pldm_pci_record_id. This is then compared against the PCI device ID + * information. + * + * Returns: true if the device matches the record, false otherwise. + */ +bool pldmfw_op_pci_match_record(struct pldmfw *context, struct pldmfw_record *record) +{ + struct pci_dev *pdev = to_pci_dev(context->dev); + struct pldm_pci_record_id id = { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subsystem_vendor = PCI_ANY_ID, + .subsystem_device = PCI_ANY_ID, + }; + struct pldmfw_desc_tlv *desc; + + list_for_each_entry(desc, &record->descs, entry) { + u16 value; + int *ptr; + + switch (desc->type) { + case PLDM_DESC_ID_PCI_VENDOR_ID: + ptr = &id.vendor; + break; + case PLDM_DESC_ID_PCI_DEVICE_ID: + ptr = &id.device; + break; + case PLDM_DESC_ID_PCI_SUBVENDOR_ID: + ptr = &id.subsystem_vendor; + break; + case PLDM_DESC_ID_PCI_SUBDEV_ID: + ptr = &id.subsystem_device; + break; + default: + /* Skip unrelated TLVs */ + continue; + } + + value = get_unaligned_le16(desc->data); + /* A value of zero for one of the descriptors is sometimes + * used when the record should ignore this field when matching + * device. For example if the record applies to any subsystem + * device or vendor. + */ + if (value) + *ptr = (int)value; + else + *ptr = PCI_ANY_ID; + } + + if ((id.vendor == PCI_ANY_ID || id.vendor == pdev->vendor) && + (id.device == PCI_ANY_ID || id.device == pdev->device) && + (id.subsystem_vendor == PCI_ANY_ID || id.subsystem_vendor == pdev->subsystem_vendor) && + (id.subsystem_device == PCI_ANY_ID || id.subsystem_device == pdev->subsystem_device)) + return true; + else + return false; +} + +/** + * pldm_find_matching_record - Find the first matching PLDM record + * @data: pointer to private data + * + * Search through PLDM records and find the first matching entry. It is + * expected that only one entry matches. + * + * Store a pointer to the matching record, if found. + * + * Returns: zero on success, or -ENOENT if no matching record is found. + */ +static int pldm_find_matching_record(struct pldmfw_priv *data) +{ + struct pldmfw_record *record; + + list_for_each_entry(record, &data->records, entry) { + if (data->context->ops->match_record(data->context, record)) { + data->matching_record = record; + return 0; + } + } + + return -ENOENT; +} + +/** + * pldm_send_package_data - Send firmware the package data for the record + * @data: pointer to private data + * + * Send the package data associated with the matching record to the firmware, + * using the send_pkg_data operation. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int +pldm_send_package_data(struct pldmfw_priv *data) +{ + struct pldmfw_record *record = data->matching_record; + const struct pldmfw_ops *ops = data->context->ops; + + return ops->send_package_data(data->context, record->package_data, + record->package_data_len); +} + +/** + * pldm_send_component_tables - Send component table information to firmware + * @data: pointer to private data + * + * Loop over each component, sending the applicable components to the firmware + * via the send_component_table operation. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int +pldm_send_component_tables(struct pldmfw_priv *data) +{ + unsigned long *bitmap = data->matching_record->component_bitmap; + struct pldmfw_component *component; + int err; + + list_for_each_entry(component, &data->components, entry) { + u8 index = component->index, transfer_flag = 0; + + /* Skip components which are not intended for this device */ + if (!test_bit(index, bitmap)) + continue; + + /* determine whether this is the start, middle, end, or both + * the start and end of the component tables + */ + if (index == find_first_bit(bitmap, data->component_bitmap_len)) + transfer_flag |= PLDM_TRANSFER_FLAG_START; + if (index == find_last_bit(bitmap, data->component_bitmap_len)) + transfer_flag |= PLDM_TRANSFER_FLAG_END; + if (!transfer_flag) + transfer_flag = PLDM_TRANSFER_FLAG_MIDDLE; + + err = data->context->ops->send_component_table(data->context, + component, + transfer_flag); + if (err) + return err; + } + + return 0; +} + +/** + * pldm_flash_components - Program each component to device flash + * @data: pointer to private data + * + * Loop through each component that is active for the matching device record, + * and send it to the device driver for flashing. + * + * Returns: zero on success, or a negative error code on failure. + */ +static int pldm_flash_components(struct pldmfw_priv *data) +{ + unsigned long *bitmap = data->matching_record->component_bitmap; + struct pldmfw_component *component; + int err; + + list_for_each_entry(component, &data->components, entry) { + u8 index = component->index; + + /* Skip components which are not intended for this device */ + if (!test_bit(index, bitmap)) + continue; + + err = data->context->ops->flash_component(data->context, component); + if (err) + return err; + } + + return 0; +} + +/** + * pldm_finalize_update - Finalize the device flash update + * @data: pointer to private data + * + * Tell the device driver to perform any remaining logic to complete the + * device update. + * + * Returns: zero on success, or a PLFM_FWU error indicating the reason for + * failure. + */ +static int pldm_finalize_update(struct pldmfw_priv *data) +{ + if (data->context->ops->finalize_update) + return data->context->ops->finalize_update(data->context); + + return 0; +} + +/** + * pldmfw_flash_image - Write a PLDM-formatted firmware image to the device + * @context: ops and data for firmware update + * @fw: firmware object pointing to the relevant firmware file to program + * + * Parse the data for a given firmware file, verifying that it is a valid PLDM + * formatted image that matches this device. + * + * Extract the device record Package Data and Component Tables and send them + * to the device firmware. Extract and write the flash data for each of the + * components indicated in the firmware file. + * + * Returns: zero on success, or a negative error code on failure. + */ +int pldmfw_flash_image(struct pldmfw *context, const struct firmware *fw) +{ + struct pldmfw_priv *data; + int err; + + data = (struct pldmfw_priv *)kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + INIT_LIST_HEAD(&data->records); + INIT_LIST_HEAD(&data->components); + + data->fw = fw; + data->context = context; + + err = pldm_parse_image(data); + if (err) + goto out_release_data; + + err = pldm_find_matching_record(data); + if (err) + goto out_release_data; + + err = pldm_send_package_data(data); + if (err) + goto out_release_data; + + err = pldm_send_component_tables(data); + if (err) + goto out_release_data; + + err = pldm_flash_components(data); + if (err) + goto out_release_data; + + err = pldm_finalize_update(data); + +out_release_data: + pldmfw_free_priv(data); + kfree(data); + + return err; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.h new file mode 100644 index 0000000000..a13c346450 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_pldmfw.h @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2021 - 2023 Intel Corporation. */ + +/* This is taken from upstream */ + +#ifndef _KCOMPAT_PLDMFW_H_ +#define _KCOMPAT_PLDMFW_H_ + +#ifdef _PLDMFW_H_ +#error "Do not include both kcompat_pldmfw.h and " +#endif + +#if IS_ENABLED(CONFIG_PLDMFW) +#error "CONFIG_PLDMFW is enabled, use " +#endif + +#include +#include + +#define PLDM_DEVICE_UPDATE_CONTINUE_AFTER_FAIL BIT(0) + +#define PLDM_STRING_TYPE_UNKNOWN 0 +#define PLDM_STRING_TYPE_ASCII 1 +#define PLDM_STRING_TYPE_UTF8 2 +#define PLDM_STRING_TYPE_UTF16 3 +#define PLDM_STRING_TYPE_UTF16LE 4 +#define PLDM_STRING_TYPE_UTF16BE 5 + +struct pldmfw_record { + struct list_head entry; + + /* List of descriptor TLVs */ + struct list_head descs; + + /* Component Set version string*/ + const u8 *version_string; + u8 version_type; + u8 version_len; + + /* Package Data length */ + u16 package_data_len; + + /* Bitfield of Device Update Flags */ + u32 device_update_flags; + + /* Package Data block */ + const u8 *package_data; + + /* Bitmap of components applicable to this record */ + unsigned long *component_bitmap; + u16 component_bitmap_len; +}; + +/* Standard descriptor TLV identifiers */ +#define PLDM_DESC_ID_PCI_VENDOR_ID 0x0000 +#define PLDM_DESC_ID_IANA_ENTERPRISE_ID 0x0001 +#define PLDM_DESC_ID_UUID 0x0002 +#define PLDM_DESC_ID_PNP_VENDOR_ID 0x0003 +#define PLDM_DESC_ID_ACPI_VENDOR_ID 0x0004 +#define PLDM_DESC_ID_PCI_DEVICE_ID 0x0100 +#define PLDM_DESC_ID_PCI_SUBVENDOR_ID 0x0101 +#define PLDM_DESC_ID_PCI_SUBDEV_ID 0x0102 +#define PLDM_DESC_ID_PCI_REVISION_ID 0x0103 +#define PLDM_DESC_ID_PNP_PRODUCT_ID 0x0104 +#define PLDM_DESC_ID_ACPI_PRODUCT_ID 0x0105 +#define PLDM_DESC_ID_VENDOR_DEFINED 0xFFFF + +struct pldmfw_desc_tlv { + struct list_head entry; + + const u8 *data; + u16 type; + u16 size; +}; + +#define PLDM_CLASSIFICATION_UNKNOWN 0x0000 +#define PLDM_CLASSIFICATION_OTHER 0x0001 +#define PLDM_CLASSIFICATION_DRIVER 0x0002 +#define PLDM_CLASSIFICATION_CONFIG_SW 0x0003 +#define PLDM_CLASSIFICATION_APP_SW 0x0004 +#define PLDM_CLASSIFICATION_INSTRUMENTATION 0x0005 +#define PLDM_CLASSIFICATION_BIOS 0x0006 +#define PLDM_CLASSIFICATION_DIAGNOSTIC_SW 0x0007 +#define PLDM_CLASSIFICATION_OS 0x0008 +#define PLDM_CLASSIFICATION_MIDDLEWARE 0x0009 +#define PLDM_CLASSIFICATION_FIRMWARE 0x000A +#define PLDM_CLASSIFICATION_CODE 0x000B +#define PLDM_CLASSIFICATION_SERVICE_PACK 0x000C +#define PLDM_CLASSIFICATION_SOFTWARE_BUNDLE 0x000D + +#define PLDM_ACTIVATION_METHOD_AUTO BIT(0) +#define PLDM_ACTIVATION_METHOD_SELF_CONTAINED BIT(1) +#define PLDM_ACTIVATION_METHOD_MEDIUM_SPECIFIC BIT(2) +#define PLDM_ACTIVATION_METHOD_REBOOT BIT(3) +#define PLDM_ACTIVATION_METHOD_DC_CYCLE BIT(4) +#define PLDM_ACTIVATION_METHOD_AC_CYCLE BIT(5) + +#define PLDMFW_COMPONENT_OPTION_FORCE_UPDATE BIT(0) +#define PLDMFW_COMPONENT_OPTION_USE_COMPARISON_STAMP BIT(1) + +struct pldmfw_component { + struct list_head entry; + + /* component identifier */ + u16 classification; + u16 identifier; + + u16 options; + u16 activation_method; + + u32 comparison_stamp; + + u32 component_size; + const u8 *component_data; + + /* Component version string */ + const u8 *version_string; + u8 version_type; + u8 version_len; + + /* component index */ + u8 index; + +}; + +/* Transfer flag used for sending components to the firmware */ +#define PLDM_TRANSFER_FLAG_START BIT(0) +#define PLDM_TRANSFER_FLAG_MIDDLE BIT(1) +#define PLDM_TRANSFER_FLAG_END BIT(2) + +struct pldmfw_ops; + +/* Main entry point to the PLDM firmware update engine. Device drivers + * should embed this in a private structure and use container_of to obtain + * a pointer to their own data, used to implement the device specific + * operations. + */ +struct pldmfw { + const struct pldmfw_ops *ops; + struct device *dev; +}; + +bool pldmfw_op_pci_match_record(struct pldmfw *context, struct pldmfw_record *record); + +/* Operations invoked by the generic PLDM firmware update engine. Used to + * implement device specific logic. + * + * @match_record: check if the device matches the given record. For + * convenience, a standard implementation is provided for PCI devices. + * + * @send_package_data: send the package data associated with the matching + * record to firmware. + * + * @send_component_table: send the component data associated with a given + * component to firmware. Called once for each applicable component. + * + * @flash_component: Flash the data for a given component to the device. + * Called once for each applicable component, after all component tables have + * been sent. + * + * @finalize_update: (optional) Finish the update. Called after all components + * have been flashed. + */ +struct pldmfw_ops { + bool (*match_record)(struct pldmfw *context, struct pldmfw_record *record); + int (*send_package_data)(struct pldmfw *context, const u8 *data, u16 length); + int (*send_component_table)(struct pldmfw *context, struct pldmfw_component *component, + u8 transfer_flag); + int (*flash_component)(struct pldmfw *context, struct pldmfw_component *component); + int (*finalize_update)(struct pldmfw *context); +}; + +int pldmfw_flash_image(struct pldmfw *context, const struct firmware *fw); + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_rhel_defs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_rhel_defs.h new file mode 100644 index 0000000000..fdf3b3cc72 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_rhel_defs.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_RHEL_DEFS_H_ +#define _KCOMPAT_RHEL_DEFS_H_ + +/* This is the RedHat Enterprise Linux distribution specific definitions file. + * It defines what features need backports for a given version of the RHEL + * kernel. + * + * It checks the RHEL_RELEASE_CODE and RHEL_RELEASE_VERSION macros to decide + * what support the target kernel has. + * + * It assumes that kcompat_std_defs.h has already been processed, and will + * #define or #undef any flags that have changed based on backports done by + * RHEL. + */ + +#if !RHEL_RELEASE_CODE +#error "RHEL_RELEASE_CODE is 0 or undefined" +#endif + +#ifndef RHEL_RELEASE_VERSION +#error "RHEL_RELEASE_VERSION is undefined" +#endif + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3)) +#define NEED_NETDEV_TXQ_BQL_PREFETCH +#else /* >= 7.3 */ +#endif /* 7.3 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,4)) +#define NEED_BUILD_BUG_ON +#else /* >= 7.4 */ +#define HAVE_RHEL7_EXTENDED_OFFLOAD_STATS +#endif /* 7.4 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,5)) +#else /* >= 7.5 */ +#define HAVE_FLOW_DISSECTOR_KEY_IP +#endif /* 7.5 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,6)) +#undef HAVE_XDP_BUFF_RXQ +#undef HAVE_XDP_RXQ_INFO_REG_3_PARAMS +#else /* >= 7.6 */ +#undef NEED_JIFFIES_64_TIME_IS_MACROS +#undef NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 +#undef NEED_TC_SETUP_QDISC_MQPRIO +#endif /* 7.6 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,7)) +#else /* >= 7.7 */ +#define HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR +#define HAVE_ETHTOOL_NEW_100G_BITS +#undef NEED_IN_TASK +#define HAVE_FLOW_DISSECTOR_KEY_ENC_IP +#endif /* 7.7 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)) +#else /* >= 8.0 */ +#undef HAVE_ETHTOOL_NEW_100G_BITS +#define HAVE_NDO_OFFLOAD_STATS +#undef HAVE_RHEL7_EXTENDED_OFFLOAD_STATS +#endif /* 8.0 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,1)) +#define NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE +#else /* >= 8.1 */ +#define HAVE_ETHTOOL_NEW_100G_BITS +#undef NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE +#undef NEED_INDIRECT_CALL_WRAPPER_MACROS +#define HAVE_INDIRECT_CALL_WRAPPER_HEADER +#endif /* 8.1 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,2)) +#else /* >= 8.2 */ +#undef NEED_FLOW_INDR_BLOCK_CB_REGISTER +#define HAVE_FLOW_INDR_BLOCK_LOCK +#define HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID +#define HAVE_NETDEV_SB_DEV +#endif /* 8.2 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,3)) +#else /* >= 8.3 */ +#undef NEED_CPU_LATENCY_QOS_RENAME +#define HAVE_RT_IRQ_SCHED_FIX +#endif /* 8.3 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,4)) +#else /* >= 8.4 */ +#undef NEED_DEVLINK_PORT_ATTRS_SET_STRUCT +#undef HAVE_XDP_QUERY_PROG +#define HAVE_AF_XDP_ZC_SUPPORT +#define HAVE_MEM_TYPE_XSK_BUFF_POOL +#define HAVE_NDO_XSK_WAKEUP +#define XSK_UMEM_RETURNS_XDP_DESC +#undef NEED_XSK_UMEM_GET_RX_FRAME_SIZE +#define HAVE_ETHTOOL_COALESCE_PARAMS_SUPPORT +#endif /* 8.4 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,5)) +#else /* >= 8.5 */ +#undef HAVE_NAPI_BUSY_LOOP +#undef HAVE_XDP_RXQ_INFO_REG_3_PARAMS +#define NO_XDP_QUERY_XSK_UMEM +#undef NEED_XSK_BUFF_POOL_RENAME +#define HAVE_NETDEV_BPF_XSK_POOL +#define HAVE_AF_XDP_NETDEV_UMEM +#define HAVE_DEVLINK_OPS_CREATE_DEL +#endif /* 8.5 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,7)) +#else /* >= 8.7 */ +#undef NEED_DEVLINK_ALLOC_SETS_DEV +#define HAVE_DEVLINK_SET_STATE_3_PARAM +#endif /* 8.7 */ + +/*****************************************************************************/ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,0)) +#else /* >= 9.0 */ +#define HAVE_XDP_BUFF_RXQ +#endif /* 9.0 */ + +/*****************************************************************************/ +#endif /* _KCOMPAT_RHEL_DEFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_sles_defs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_sles_defs.h new file mode 100644 index 0000000000..63727ce73a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_sles_defs.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_SLES_DEFS_H_ +#define _KCOMPAT_SLES_DEFS_H_ + +/* This is the SUSE Linux Enterprise distribution specific definitions file. + * It defines what features need backports for a given version of the SUSE + * Linux Enterprise kernel. + * + * It checks a combination of the LINUX_VERSION code and the + * SLE_LOCALVERSION_CODE to determine what support the kernel has. + * + * It assumes that kcompat_std_defs.h has already been processed, and will + * #define or #undef any flags that have changed based on backports done by + * SUSE. + */ + +#ifndef LINUX_VERSION_CODE +#error "LINUX_VERSION_CODE is undefined" +#endif + +#ifndef KERNEL_VERSION +#error "KERNEL_VERSION is undefined" +#endif + +#if !SLE_KERNEL_REVISION +#error "SLE_KERNEL_REVISION is 0 or undefined" +#endif + +#if SLE_KERNEL_REVISION > 65535 +#error "SLE_KERNEL_REVISION is unexpectedly large" +#endif + +/* SLE kernel versions are a combination of the LINUX_VERSION_CODE along with + * an extra digit that indicates the SUSE specific revision of that kernel. + * This value is found in the CONFIG_LOCALVERSION of the SUSE kernel, which is + * extracted by common.mk and placed into SLE_KERNEL_REVISION_CODE. + * + * We combine the value of SLE_KERNEL_REVISION along with the LINUX_VERSION code + * to generate the useful value that determines what specific kernel we're + * dealing with. + * + * Just in case the SLE_KERNEL_REVISION ever goes above 255, we reserve 16 bits + * instead of 8 for this value. + */ +#define SLE_KERNEL_CODE ((LINUX_VERSION_CODE << 16) + SLE_KERNEL_REVISION) +#define SLE_KERNEL_VERSION(a,b,c,d) ((KERNEL_VERSION(a,b,c) << 16) + (d)) + +/* Unlike RHEL, SUSE kernels are not always tied to a single service pack. For + * example, 4.12.14 was used as the base for SLE 15 SP1, SLE 12 SP4, and SLE 12 + * SP5. + * + * You can find the patches that SUSE applied to the kernel tree at + * https://github.com/SUSE/kernel-source. + * + * You can find the correct kernel version for a check by using steps similar + * to the following + * + * 1) download the kernel-source repo + * 2) checkout the relevant branch, i.e SLE15-SP3 + * 3) find the relevant backport you're interested in the patches.suse + * directory + * 4) git log to locate the commit that introduced the backport + * 5) git describe --contains to find the relevant tag that includes that + * commit, i.e. rpm-5.3.18-37 + * 6) those digits represent the SLE kernel that introduced that backport. + * + * Try to keep the checks in SLE_KERNEL_CODE order and condense where + * possible. + */ + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE > SLE_KERNEL_VERSION(4,12,14,23) && \ + SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,94)) +/* + * 4.12.14 is used as the base for SLE 12 SP4, SLE 12 SP5, SLE 15, and SLE 15 + * SP1. Unfortunately the revision codes do not line up cleanly. SLE 15 + * launched with 4.12.14-23. It appears that SLE 12 SP4 and SLE 15 SP1 both + * diverged from this point, with SLE 12 SP4 kernels starting around + * 4.12.14-94. A few backports for SLE 15 SP1 landed in some alpha and beta + * kernels tagged between 4.12.14-25 up to 4.12.14-32. These changes did not + * make it into SLE 12 SP4. This was cleaned up with SLE 12 SP5 by an apparent + * merge in 4.12.14-111. The official launch of SLE 15 SP1 ended up with + * version 4.12.14-195. + * + * Because of this inconsistency and because all of these kernels appear to be + * alpha or beta kernel releases for SLE 15 SP1, we do not rely on version + * checks between this range. Issue a warning to indicate that we do not + * support these. + */ +#warning "SLE kernel versions between 4.12.14-23 and 4.12.14-94 are not supported" +#endif + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,10)) +#else /* >= 4.12.14-10 */ +#undef NEED_INDIRECT_CALL_WRAPPER_MACROS +#define HAVE_INDIRECT_CALL_WRAPPER_HEADER +#endif /* 4.12.14-10 */ + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,111)) +#define NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE +#else /* >= 4.12.14-111 */ +#define HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR +#undef NEED_MACVLAN_ACCEL_PRIV +#undef NEED_MACVLAN_RELEASE_L2FW_OFFLOAD +#undef NEED_MACVLAN_SUPPORTS_DEST_FILTER +#undef NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE +#endif /* 4.12.14-111 */ + +/*****************************************************************************/ +/* SLES 12-SP5 base kernel version */ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(4,12,14,115)) +#else /* >= 4.12.14-115 */ +#define HAVE_NDO_SELECT_QUEUE_SB_DEV +#undef NEED_TC_SETUP_QDISC_MQPRIO +#undef NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 +#endif /* 4.12.14-115 */ + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,8,2)) +#else /* >= 5.3.8-2 */ +#undef NEED_FLOW_INDR_BLOCK_CB_REGISTER +#define HAVE_FLOW_INDR_BLOCK_LOCK +#endif /* 5.3.8-2 */ + +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,18,26)) +#else /* >= 5.3.18-26 */ +#undef NEED_CPU_LATENCY_QOS_RENAME +#endif + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,18,34)) +#else /* >= 5.3.18-34 */ +#undef NEED_DEVLINK_PORT_ATTRS_SET_STRUCT +#endif /* 5.3.18-34 */ + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,3,18,41)) +#define NEED_XSK_BUFF_POOL_RENAME +#else /* >= 5.3.18-41 */ +#define HAVE_XDP_BUFF_FRAME_SZ +#define HAVE_NETDEV_BPF_XSK_POOL +#undef NEED_XSK_UMEM_GET_RX_FRAME_SIZE +#undef NEED_XSK_BUFF_POOL_RENAME +#define HAVE_MEM_TYPE_XSK_BUFF_POOL +#endif /* 5.3.18-41 */ + +/*****************************************************************************/ +#if (SLE_KERNEL_CODE < SLE_KERNEL_VERSION(5,14,21,9)) +#else /* >= 5.14.21-150400.9 */ +#undef NEED_DEVLINK_ALLOC_SETS_DEV +#define HAVE_DEVLINK_OPS_CREATE_DEL +#define HAVE_DEVLINK_SET_STATE_3_PARAM +#endif /* 5.14.21-150400.9 */ + +#endif /* _KCOMPAT_SLES_DEFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_std_defs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_std_defs.h new file mode 100644 index 0000000000..832eabbfaa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_std_defs.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_STD_DEFS_H_ +#define _KCOMPAT_STD_DEFS_H_ + +/* This file contains the definitions for what kernel features need backports + * for a given kernel. It targets only the standard stable kernel releases. + * It must check only LINUX_VERSION_CODE and assume the kernel is a standard + * release, and not a custom distribution. + * + * It must define HAVE_ and NEED_ for features. It must not + * implement any backports, instead leaving the implementation to the + * kcompat_impl.h header. + * + * If a feature can be easily implemented as a replacement macro or fully + * backported, use a NEED_ to indicate that the feature needs + * a backport. (If NEED_ is undefined, then no backport for that feature + * is needed). + * + * If a feature cannot be easily implemented in kcompat directly, but + * requires drivers to make specific changes such as stripping out an entire + * feature or modifying a function pointer prototype, use a HAVE_. + */ + +#ifndef LINUX_VERSION_CODE +#error "LINUX_VERSION_CODE is undefined" +#endif + +#ifndef KERNEL_VERSION +#error "KERNEL_VERSION is undefined" +#endif + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)) +#else /* >= 4,8,0 */ +#define HAVE_PCI_ALLOC_IRQ +#endif /* 4,8,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) +#define NEED_JIFFIES_64_TIME_IS_MACROS +#else /* >= 4,9,0 */ +#define HAVE_KTHREAD_DELAYED_API +#define HAVE_NDO_OFFLOAD_STATS +#endif /* 4,9,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,62)) +#define NEED_IN_TASK +#else /* >= 4,9,62 */ +#endif /* 4,9,62 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)) +#else /* >= 4,12,0 */ +#define HAVE_NAPI_BUSY_LOOP +#endif /* 4,12,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)) +#else /* >= 4,13,0 */ +#define HAVE_FLOW_DISSECTOR_KEY_IP +#endif /* 4,13,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +#define NEED_TC_SETUP_QDISC_MQPRIO +#define NEED_NETDEV_XDP_STRUCT +#else /* >= 4,15,0 */ +#define HAVE_NDO_BPF +#endif /* 4,15,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0)) +#define NEED_TC_CLS_CAN_OFFLOAD_AND_CHAIN0 +#else /* >= 4,16,0 */ +#define HAVE_XDP_BUFF_RXQ +#define HAVE_XDP_RXQ_INFO_REG_3_PARAMS +#endif /* 4,16,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,17,0)) +#define NEED_CONVERT_ART_NS_TO_TSC +#else /* >= 4,17,0 */ +#endif /* 4,17,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0)) +#define NEED_MACVLAN_ACCEL_PRIV +#define NEED_MACVLAN_RELEASE_L2FW_OFFLOAD +#define NEED_MACVLAN_SUPPORTS_DEST_FILTER +#else /* >= 4,18,0 */ +#define HAVE_DEVLINK_PORT_ATTRS_SET_PORT_FLAVOUR +#endif /* 4,18,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0)) +#define NEED_IDA_ALLOC_MIN_MAX_RANGE_FREE +#else /* >= 4,19,0 */ +#define HAVE_TC_ETF_QOPT_OFFLOAD +#define HAVE_FLOW_DISSECTOR_KEY_ENC_IP +#endif /* 4,19,0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) +#define NEED_INDIRECT_CALL_WRAPPER_MACROS +#else /* >= 5.0.0 */ +#define HAVE_INDIRECT_CALL_WRAPPER_HEADER +#endif /* 5.0.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0)) +#else /* >= 5.1.0 */ +#define HAVE_ETHTOOL_200G_BITS +#define HAVE_ETHTOOL_NEW_100G_BITS +#endif /* 5.1.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)) +#else /* >= 5.2.0 */ +#define HAVE_DEVLINK_PORT_ATTRS_SET_SWITCH_ID +#endif /* 5.2.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)) +#define NEED_FLOW_INDR_BLOCK_CB_REGISTER +#else /* >= 5.4.0 */ +#define HAVE_FLOW_INDR_BLOCK_LOCK +#define HAVE_XSK_UNALIGNED_CHUNK_PLACEMENT +#endif /* 5.4.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0)) +#define NEED_CPU_LATENCY_QOS_RENAME +#else /* >= 5.7.0 */ +#endif /* 5.7.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)) +#define NEED_XSK_UMEM_GET_RX_FRAME_SIZE +#else /* >= 5.8.0 */ +#undef HAVE_XSK_UNALIGNED_CHUNK_PLACEMENT +#define HAVE_RT_IRQ_SCHED_FIX +#endif /* 5.8.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0)) +#define NEED_DEVLINK_PORT_ATTRS_SET_STRUCT +#define HAVE_XDP_QUERY_PROG +#define NEED_INDIRECT_CALL_3_AND_4 +#else /* >= 5.9.0 */ +#define HAVE_TASKLET_SETUP +#endif /* 5.9.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)) +#define NEED_XSK_BUFF_POOL_RENAME +#else /* >= 5.10.0 */ +#define HAVE_UDP_TUNNEL_NIC_SHARED +#define HAVE_NETDEV_BPF_XSK_POOL +#endif /* 5.10.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0)) +#else /* >= 5.11.0 */ +#define HAVE_XSK_BATCHED_DESCRIPTOR_INTERFACES +#undef HAVE_XDP_RXQ_INFO_REG_3_PARAMS +#define HAVE_XSK_TX_PEEK_RELEASE_DESC_BATCH_3_PARAMS +#endif /* 5.11.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0)) +#define NEED_EXPORT_INDIRECT_CALLABLE +#else /* >= 5.12.0 */ +#define HAVE_DEVLINK_OPS_CREATE_DEL +#endif /* 5.12.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0)) +#else /* >= 5.13.0 */ +#define HAVE_XPS_MAP_TYPE +#endif /* 5.13.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,14,0)) +#else /* >= 5.14.0 */ +#define HAVE_TTY_WRITE_ROOM_UINT +#endif /* 5.14.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0)) +#define NEED_DEVLINK_ALLOC_SETS_DEV +#else /* >= 5.15.0 */ +#define HAVE_DEVICE_IN_MDEV_PARENT_OPS +#define NEED_PCI_IOV_VF_ID +#define HAVE_DEVLINK_SET_STATE_3_PARAM +#endif /* 5.15.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)) +#else /* >= 5.16.0 */ +#define HAVE_XSK_BATCHED_RX_ALLOC +#endif /* 5.16.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)) +#else /* >=5.18.0*/ +#undef NEED_PCI_IOV_VF_ID +#undef HAVE_XSK_TX_PEEK_RELEASE_DESC_BATCH_3_PARAMS +#endif /* 5.18.0 */ + +/*****************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,1,0)) +#else /* >=6.1.0 */ +#define HAVE_FLOW_DISSECTOR_KEY_L2TPV3 +#define HAVE_TTY_TERMIOS_CONST_STRUCT +#endif /* 6.1.0 */ + +#endif /* _KCOMPAT_STD_DEFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_ubuntu_defs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_ubuntu_defs.h new file mode 100644 index 0000000000..ea9cf2c2be --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_ubuntu_defs.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +#ifndef _KCOMPAT_UBUNTU_DEFS_H_ +#define _KCOMPAT_UBUNTU_DEFS_H_ + +/* This file contains the definitions for the Ubuntu specific distribution of + * the Linux kernel. + * + * It checks the UBUNTU_VERSION_CODE to decide which features are available in + * the target kernel. It assumes that kcompat_std_defs.h has already been + * processed, and will #define or #undef the relevant flags based on what + * features were backported by Ubuntu. + */ + +#if !UTS_UBUNTU_RELEASE_ABI +#error "UTS_UBUNTU_RELEASE_ABI is 0 or undefined" +#endif + +#if !UBUNTU_VERSION_CODE +#error "UBUNTU_VERSION_CODE is 0 or undefined" +#endif + +#ifndef UBUNTU_VERSION +#error "UBUNTU_VERSION is undefined" +#endif + +/*****************************************************************************/ +#if (UBUNTU_VERSION_CODE >= UBUNTU_VERSION(4,15,0,159) && \ + UBUNTU_VERSION_CODE < UBUNTU_VERSION(4,15,0,999)) +#endif + +/*****************************************************************************/ +#endif /* _KCOMPAT_UBUNTU_DEFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.c new file mode 100644 index 0000000000..f4bbab0958 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.c @@ -0,0 +1,2406 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +// SPDX-License-Identifier: GPL-2.0+ +/* + * XArray implementation + * Copyright (c) 2017-2018 Microsoft Corporation + * Copyright (c) 2018-2020 Oracle + * Author: Matthew Wilcox + */ + +/* This is taken from upstream /lib/xarray.c commit ae9b3c0e79bc */ + +#include "kcompat.h" + +/* includes from radix-tree.c and linux/radix-tree.h, + * not directly included by xarray.[ch] + */ +#include +#include +#include +#include +#include +#include +#include /* in_interrupt() */ +#include + +#define radix_tree_node xa_node + +struct kmem_cache; +struct rcu_head; + +struct kmem_cache *radix_tree_node_cachep; +static atomic_t kc_init_done = ATOMIC_INIT(0); +static DEFINE_SPINLOCK(kc_radix_tree_init_lock); + +static void radix_tree_node_ctor(void *arg) +{ + struct radix_tree_node *node = arg; + + memset(node, 0, sizeof(*node)); + INIT_LIST_HEAD(&node->private_list); +} + +static void kc_xarray_global_init(void) +{ + if (likely(atomic_read(&kc_init_done))) + return; + spin_lock(&kc_radix_tree_init_lock); + if (atomic_read(&kc_init_done)) + goto out; + radix_tree_node_cachep = kmem_cache_create("kc_radix_tree_node", + sizeof(struct radix_tree_node), 0, + SLAB_PANIC | SLAB_RECLAIM_ACCOUNT, + radix_tree_node_ctor); + atomic_set_release(&kc_init_done, 1); +out: + spin_unlock(&kc_radix_tree_init_lock); +} + +static void radix_tree_node_rcu_free(struct rcu_head *head) +{ + struct radix_tree_node *node = + container_of(head, struct radix_tree_node, rcu_head); + + /* + * Must only free zeroed nodes into the slab. We can be left with + * non-NULL entries by radix_tree_free_nodes, so clear the entries + * and tags here. + */ + memset(node->slots, 0, sizeof(node->slots)); + memset(node->tags, 0, sizeof(node->tags)); + INIT_LIST_HEAD(&node->private_list); + + kmem_cache_free(radix_tree_node_cachep, node); +} + + +/* + * Coding conventions in this file: + * + * @xa is used to refer to the entire xarray. + * @xas is the 'xarray operation state'. It may be either a pointer to + * an xa_state, or an xa_state stored on the stack. This is an unfortunate + * ambiguity. + * @index is the index of the entry being operated on + * @mark is an xa_mark_t; a small number indicating one of the mark bits. + * @node refers to an xa_node; usually the primary one being operated on by + * this function. + * @offset is the index into the slots array inside an xa_node. + * @parent refers to the @xa_node closer to the head than @node. + * @entry refers to something stored in a slot in the xarray + */ + +static inline unsigned int xa_lock_type(const struct xarray *xa) +{ + return (__force unsigned int)xa->xa_flags & 3; +} + +static inline void xas_lock_type(struct xa_state *xas, unsigned int lock_type) +{ + if (lock_type == XA_LOCK_IRQ) + xas_lock_irq(xas); + else if (lock_type == XA_LOCK_BH) + xas_lock_bh(xas); + else + xas_lock(xas); +} + +static inline void xas_unlock_type(struct xa_state *xas, unsigned int lock_type) +{ + if (lock_type == XA_LOCK_IRQ) + xas_unlock_irq(xas); + else if (lock_type == XA_LOCK_BH) + xas_unlock_bh(xas); + else + xas_unlock(xas); +} + +static inline bool xa_track_free(const struct xarray *xa) +{ + return xa->xa_flags & XA_FLAGS_TRACK_FREE; +} + +static inline bool xa_zero_busy(const struct xarray *xa) +{ + return xa->xa_flags & XA_FLAGS_ZERO_BUSY; +} + +static inline void xa_mark_set(struct xarray *xa, xa_mark_t mark) +{ + if (!(xa->xa_flags & XA_FLAGS_MARK(mark))) + xa->xa_flags |= XA_FLAGS_MARK(mark); +} + +static inline void xa_mark_clear(struct xarray *xa, xa_mark_t mark) +{ + if (xa->xa_flags & XA_FLAGS_MARK(mark)) + xa->xa_flags &= ~(XA_FLAGS_MARK(mark)); +} + +static inline unsigned long *node_marks(struct xa_node *node, xa_mark_t mark) +{ + return node->marks[(__force unsigned)mark]; +} + +static inline bool node_get_mark(struct xa_node *node, + unsigned int offset, xa_mark_t mark) +{ + return test_bit(offset, node_marks(node, mark)); +} + +/* returns true if the bit was set */ +static inline bool node_set_mark(struct xa_node *node, unsigned int offset, + xa_mark_t mark) +{ + return __test_and_set_bit(offset, node_marks(node, mark)); +} + +/* returns true if the bit was set */ +static inline bool node_clear_mark(struct xa_node *node, unsigned int offset, + xa_mark_t mark) +{ + return __test_and_clear_bit(offset, node_marks(node, mark)); +} + +static inline bool node_any_mark(struct xa_node *node, xa_mark_t mark) +{ + return !bitmap_empty(node_marks(node, mark), XA_CHUNK_SIZE); +} + +static inline void node_mark_all(struct xa_node *node, xa_mark_t mark) +{ + bitmap_fill(node_marks(node, mark), XA_CHUNK_SIZE); +} + +#define mark_inc(mark) do { \ + mark = (__force xa_mark_t)((__force unsigned)(mark) + 1); \ +} while (0) + +/* + * xas_squash_marks() - Merge all marks to the first entry + * @xas: Array operation state. + * + * Set a mark on the first entry if any entry has it set. Clear marks on + * all sibling entries. + */ +static void xas_squash_marks(const struct xa_state *xas) +{ + xa_mark_t mark = 0; + unsigned int limit = xas->xa_offset + xas->xa_sibs + 1; + + for (;;) { + unsigned long *marks = node_marks(xas->xa_node, mark); + + if (find_next_bit(marks, limit, xas->xa_offset + 1) != limit) { + __set_bit(xas->xa_offset, marks); + bitmap_clear(marks, xas->xa_offset + 1, xas->xa_sibs); + } + if (mark == XA_MARK_MAX) + break; + mark_inc(mark); + } +} + +/* extracts the offset within this node from the index */ +static unsigned int get_offset(unsigned long index, struct xa_node *node) +{ + return (index >> node->shift) & XA_CHUNK_MASK; +} + +static void xas_set_offset(struct xa_state *xas) +{ + xas->xa_offset = get_offset(xas->xa_index, xas->xa_node); +} + +/* move the index either forwards (find) or backwards (sibling slot) */ +static void xas_move_index(struct xa_state *xas, unsigned long offset) +{ + unsigned int shift = xas->xa_node->shift; + xas->xa_index &= ~XA_CHUNK_MASK << shift; + xas->xa_index += offset << shift; +} + +static void xas_next_offset(struct xa_state *xas) +{ + xas->xa_offset++; + xas_move_index(xas, xas->xa_offset); +} + +static void *set_bounds(struct xa_state *xas) +{ + xas->xa_node = XAS_BOUNDS; + return NULL; +} + +/* + * Starts a walk. If the @xas is already valid, we assume that it's on + * the right path and just return where we've got to. If we're in an + * error state, return NULL. If the index is outside the current scope + * of the xarray, return NULL without changing @xas->xa_node. Otherwise + * set @xas->xa_node to NULL and return the current head of the array. + */ +static void *xas_start(struct xa_state *xas) +{ + void *entry; + + if (xas_valid(xas)) + return xas_reload(xas); + if (xas_error(xas)) + return NULL; + + entry = xa_head(xas->xa); + if (!xa_is_node(entry)) { + if (xas->xa_index) + return set_bounds(xas); + } else { + if ((xas->xa_index >> xa_to_node(entry)->shift) > XA_CHUNK_MASK) + return set_bounds(xas); + } + + xas->xa_node = NULL; + return entry; +} + +static __always_inline void *xas_descend(struct xa_state *xas, + struct xa_node *node) +{ + unsigned int offset = get_offset(xas->xa_index, node); + void *entry = xa_entry(xas->xa, node, offset); + + xas->xa_node = node; + while (xa_is_sibling(entry)) { + offset = xa_to_sibling(entry); + entry = xa_entry(xas->xa, node, offset); + if (node->shift && xa_is_node(entry)) + entry = XA_RETRY_ENTRY; + } + + xas->xa_offset = offset; + return entry; +} + +/** + * xas_load() - Load an entry from the XArray (advanced). + * @xas: XArray operation state. + * + * Usually walks the @xas to the appropriate state to load the entry + * stored at xa_index. However, it will do nothing and return %NULL if + * @xas is in an error state. xas_load() will never expand the tree. + * + * If the xa_state is set up to operate on a multi-index entry, xas_load() + * may return %NULL or an internal entry, even if there are entries + * present within the range specified by @xas. + * + * Context: Any context. The caller should hold the xa_lock or the RCU lock. + * Return: Usually an entry in the XArray, but see description for exceptions. + */ +void *xas_load(struct xa_state *xas) +{ + void *entry = xas_start(xas); + + while (xa_is_node(entry)) { + struct xa_node *node = xa_to_node(entry); + + if (xas->xa_shift > node->shift) + break; + entry = xas_descend(xas, node); + if (node->shift == 0) + break; + } + return entry; +} +EXPORT_SYMBOL_GPL(xas_load); + +#define XA_RCU_FREE ((struct xarray *)1) + +static void xa_node_free(struct xa_node *node) +{ + XA_NODE_BUG_ON(node, !list_empty(&node->private_list)); + node->array = XA_RCU_FREE; + call_rcu(&node->rcu_head, radix_tree_node_rcu_free); +} + +/* + * xas_destroy() - Free any resources allocated during the XArray operation. + * @xas: XArray operation state. + * + * Most users will not need to call this function; it is called for you + * by xas_nomem(). + */ +void xas_destroy(struct xa_state *xas) +{ + struct xa_node *next, *node = xas->xa_alloc; + + while (node) { + XA_NODE_BUG_ON(node, !list_empty(&node->private_list)); + next = rcu_dereference_raw(node->parent); + radix_tree_node_rcu_free(&node->rcu_head); + xas->xa_alloc = node = next; + } +} + +/** + * xas_nomem() - Allocate memory if needed. + * @xas: XArray operation state. + * @gfp: Memory allocation flags. + * + * If we need to add new nodes to the XArray, we try to allocate memory + * with GFP_NOWAIT while holding the lock, which will usually succeed. + * If it fails, @xas is flagged as needing memory to continue. The caller + * should drop the lock and call xas_nomem(). If xas_nomem() succeeds, + * the caller should retry the operation. + * + * Forward progress is guaranteed as one node is allocated here and + * stored in the xa_state where it will be found by xas_alloc(). More + * nodes will likely be found in the slab allocator, but we do not tie + * them up here. + * + * Return: true if memory was needed, and was successfully allocated. + */ +bool xas_nomem(struct xa_state *xas, gfp_t gfp) +{ + if (xas->xa_node != XA_ERROR(-ENOMEM)) { + xas_destroy(xas); + return false; + } + if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT) + gfp |= __GFP_ACCOUNT; + xas->xa_alloc = kmem_cache_alloc_lru(radix_tree_node_cachep, xas->xa_lru, gfp); + if (!xas->xa_alloc) + return false; + xas->xa_alloc->parent = NULL; + XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list)); + xas->xa_node = XAS_RESTART; + return true; +} +EXPORT_SYMBOL_GPL(xas_nomem); + +/* + * __xas_nomem() - Drop locks and allocate memory if needed. + * @xas: XArray operation state. + * @gfp: Memory allocation flags. + * + * Internal variant of xas_nomem(). + * + * Return: true if memory was needed, and was successfully allocated. + */ +static bool __xas_nomem(struct xa_state *xas, gfp_t gfp) + __must_hold(xas->xa->xa_lock) +{ + unsigned int lock_type = xa_lock_type(xas->xa); + + if (xas->xa_node != XA_ERROR(-ENOMEM)) { + xas_destroy(xas); + return false; + } + if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT) + gfp |= __GFP_ACCOUNT; + if (gfpflags_allow_blocking(gfp)) { + xas_unlock_type(xas, lock_type); + xas->xa_alloc = kmem_cache_alloc_lru(radix_tree_node_cachep, xas->xa_lru, gfp); + xas_lock_type(xas, lock_type); + } else { + xas->xa_alloc = kmem_cache_alloc_lru(radix_tree_node_cachep, xas->xa_lru, gfp); + } + if (!xas->xa_alloc) + return false; + xas->xa_alloc->parent = NULL; + XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list)); + xas->xa_node = XAS_RESTART; + return true; +} + +static void xas_update(struct xa_state *xas, struct xa_node *node) +{ + if (xas->xa_update) + xas->xa_update(node); + else + XA_NODE_BUG_ON(node, !list_empty(&node->private_list)); +} + +static void *xas_alloc(struct xa_state *xas, unsigned int shift) +{ + struct xa_node *parent = xas->xa_node; + struct xa_node *node = xas->xa_alloc; + + if (xas_invalid(xas)) + return NULL; + + if (node) { + xas->xa_alloc = NULL; + } else { + gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN; + + if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT) + gfp |= __GFP_ACCOUNT; + + node = kmem_cache_alloc_lru(radix_tree_node_cachep, xas->xa_lru, gfp); + if (!node) { + xas_set_err(xas, -ENOMEM); + return NULL; + } + } + + if (parent) { + node->offset = xas->xa_offset; + parent->count++; + XA_NODE_BUG_ON(node, parent->count > XA_CHUNK_SIZE); + xas_update(xas, parent); + } + XA_NODE_BUG_ON(node, shift > BITS_PER_LONG); + XA_NODE_BUG_ON(node, !list_empty(&node->private_list)); + node->shift = shift; + node->count = 0; + node->nr_values = 0; + RCU_INIT_POINTER(node->parent, xas->xa_node); + node->array = xas->xa; + + return node; +} + +#ifdef CONFIG_XARRAY_MULTI +/* Returns the number of indices covered by a given xa_state */ +static unsigned long xas_size(const struct xa_state *xas) +{ + return (xas->xa_sibs + 1UL) << xas->xa_shift; +} +#endif + +/* + * Use this to calculate the maximum index that will need to be created + * in order to add the entry described by @xas. Because we cannot store a + * multi-index entry at index 0, the calculation is a little more complex + * than you might expect. + */ +static unsigned long xas_max(struct xa_state *xas) +{ + unsigned long max = xas->xa_index; + +#ifdef CONFIG_XARRAY_MULTI + if (xas->xa_shift || xas->xa_sibs) { + unsigned long mask = xas_size(xas) - 1; + max |= mask; + if (mask == max) + max++; + } +#endif + + return max; +} + +/* The maximum index that can be contained in the array without expanding it */ +static unsigned long max_index(void *entry) +{ + if (!xa_is_node(entry)) + return 0; + return (XA_CHUNK_SIZE << xa_to_node(entry)->shift) - 1; +} + +static inline void *xa_zero_to_null(void *entry) +{ + return xa_is_zero(entry) ? NULL : entry; +} + +static void xas_shrink(struct xa_state *xas) +{ + struct xarray *xa = xas->xa; + struct xa_node *node = xas->xa_node; + + for (;;) { + void *entry; + + XA_NODE_BUG_ON(node, node->count > XA_CHUNK_SIZE); + if (node->count != 1) + break; + entry = xa_entry_locked(xa, node, 0); + if (!entry) + break; + if (!xa_is_node(entry) && node->shift) + break; + if (xa_zero_busy(xa)) + entry = xa_zero_to_null(entry); + xas->xa_node = XAS_BOUNDS; + + RCU_INIT_POINTER(xa->xa_head, entry); + if (xa_track_free(xa) && !node_get_mark(node, 0, XA_FREE_MARK)) + xa_mark_clear(xa, XA_FREE_MARK); + + node->count = 0; + node->nr_values = 0; + if (!xa_is_node(entry)) + RCU_INIT_POINTER(node->slots[0], XA_RETRY_ENTRY); + xas_update(xas, node); + xa_node_free(node); + if (!xa_is_node(entry)) + break; + node = xa_to_node(entry); + node->parent = NULL; + } +} + +/* + * xas_delete_node() - Attempt to delete an xa_node + * @xas: Array operation state. + * + * Attempts to delete the @xas->xa_node. This will fail if xa->node has + * a non-zero reference count. + */ +static void xas_delete_node(struct xa_state *xas) +{ + struct xa_node *node = xas->xa_node; + + for (;;) { + struct xa_node *parent; + + XA_NODE_BUG_ON(node, node->count > XA_CHUNK_SIZE); + if (node->count) + break; + + parent = xa_parent_locked(xas->xa, node); + xas->xa_node = parent; + xas->xa_offset = node->offset; + xa_node_free(node); + + if (!parent) { + xas->xa->xa_head = NULL; + xas->xa_node = XAS_BOUNDS; + return; + } + + parent->slots[xas->xa_offset] = NULL; + parent->count--; + XA_NODE_BUG_ON(parent, parent->count > XA_CHUNK_SIZE); + node = parent; + xas_update(xas, node); + } + + if (!node->parent) + xas_shrink(xas); +} + +/** + * xas_free_nodes() - Free this node and all nodes that it references + * @xas: Array operation state. + * @top: Node to free + * + * This node has been removed from the tree. We must now free it and all + * of its subnodes. There may be RCU walkers with references into the tree, + * so we must replace all entries with retry markers. + */ +static void xas_free_nodes(struct xa_state *xas, struct xa_node *top) +{ + unsigned int offset = 0; + struct xa_node *node = top; + + for (;;) { + void *entry = xa_entry_locked(xas->xa, node, offset); + + if (node->shift && xa_is_node(entry)) { + node = xa_to_node(entry); + offset = 0; + continue; + } + if (entry) + RCU_INIT_POINTER(node->slots[offset], XA_RETRY_ENTRY); + offset++; + while (offset == XA_CHUNK_SIZE) { + struct xa_node *parent; + + parent = xa_parent_locked(xas->xa, node); + offset = node->offset + 1; + node->count = 0; + node->nr_values = 0; + xas_update(xas, node); + xa_node_free(node); + if (node == top) + return; + node = parent; + } + } +} + +/* + * xas_expand adds nodes to the head of the tree until it has reached + * sufficient height to be able to contain @xas->xa_index + */ +static int xas_expand(struct xa_state *xas, void *head) +{ + struct xarray *xa = xas->xa; + struct xa_node *node = NULL; + unsigned int shift = 0; + unsigned long max = xas_max(xas); + + if (!head) { + if (max == 0) + return 0; + while ((max >> shift) >= XA_CHUNK_SIZE) + shift += XA_CHUNK_SHIFT; + return shift + XA_CHUNK_SHIFT; + } else if (xa_is_node(head)) { + node = xa_to_node(head); + shift = node->shift + XA_CHUNK_SHIFT; + } + xas->xa_node = NULL; + + while (max > max_index(head)) { + xa_mark_t mark = 0; + + XA_NODE_BUG_ON(node, shift > BITS_PER_LONG); + node = xas_alloc(xas, shift); + if (!node) + return -ENOMEM; + + node->count = 1; + if (xa_is_value(head)) + node->nr_values = 1; + RCU_INIT_POINTER(node->slots[0], head); + + /* Propagate the aggregated mark info to the new child */ + for (;;) { + if (xa_track_free(xa) && mark == XA_FREE_MARK) { + node_mark_all(node, XA_FREE_MARK); + if (!xa_marked(xa, XA_FREE_MARK)) { + node_clear_mark(node, 0, XA_FREE_MARK); + xa_mark_set(xa, XA_FREE_MARK); + } + } else if (xa_marked(xa, mark)) { + node_set_mark(node, 0, mark); + } + if (mark == XA_MARK_MAX) + break; + mark_inc(mark); + } + + /* + * Now that the new node is fully initialised, we can add + * it to the tree + */ + if (xa_is_node(head)) { + xa_to_node(head)->offset = 0; + rcu_assign_pointer(xa_to_node(head)->parent, node); + } + head = xa_mk_node(node); + rcu_assign_pointer(xa->xa_head, head); + xas_update(xas, node); + + shift += XA_CHUNK_SHIFT; + } + + xas->xa_node = node; + return shift; +} + +/* + * xas_create() - Create a slot to store an entry in. + * @xas: XArray operation state. + * @allow_root: %true if we can store the entry in the root directly + * + * Most users will not need to call this function directly, as it is called + * by xas_store(). It is useful for doing conditional store operations + * (see the xa_cmpxchg() implementation for an example). + * + * Return: If the slot already existed, returns the contents of this slot. + * If the slot was newly created, returns %NULL. If it failed to create the + * slot, returns %NULL and indicates the error in @xas. + */ +static void *xas_create(struct xa_state *xas, bool allow_root) +{ + struct xarray *xa = xas->xa; + void *entry; + void __rcu **slot; + struct xa_node *node = xas->xa_node; + int shift; + unsigned int order = xas->xa_shift; + + kc_xarray_global_init(); + + if (xas_top(node)) { + entry = xa_head_locked(xa); + xas->xa_node = NULL; + if (!entry && xa_zero_busy(xa)) + entry = XA_ZERO_ENTRY; + shift = xas_expand(xas, entry); + if (shift < 0) + return NULL; + if (!shift && !allow_root) + shift = XA_CHUNK_SHIFT; + entry = xa_head_locked(xa); + slot = &xa->xa_head; + } else if (xas_error(xas)) { + return NULL; + } else if (node) { + unsigned int offset = xas->xa_offset; + + shift = node->shift; + entry = xa_entry_locked(xa, node, offset); + slot = &node->slots[offset]; + } else { + shift = 0; + entry = xa_head_locked(xa); + slot = &xa->xa_head; + } + + while (shift > order) { + shift -= XA_CHUNK_SHIFT; + if (!entry) { + node = xas_alloc(xas, shift); + if (!node) + break; + if (xa_track_free(xa)) + node_mark_all(node, XA_FREE_MARK); + rcu_assign_pointer(*slot, xa_mk_node(node)); + } else if (xa_is_node(entry)) { + node = xa_to_node(entry); + } else { + break; + } + entry = xas_descend(xas, node); + slot = &node->slots[xas->xa_offset]; + } + + return entry; +} + +/** + * xas_create_range() - Ensure that stores to this range will succeed + * @xas: XArray operation state. + * + * Creates all of the slots in the range covered by @xas. Sets @xas to + * create single-index entries and positions it at the beginning of the + * range. This is for the benefit of users which have not yet been + * converted to use multi-index entries. + */ +void xas_create_range(struct xa_state *xas) +{ + unsigned long index = xas->xa_index; + unsigned char shift = xas->xa_shift; + unsigned char sibs = xas->xa_sibs; + + xas->xa_index |= ((sibs + 1UL) << shift) - 1; + if (xas_is_node(xas) && xas->xa_node->shift == xas->xa_shift) + xas->xa_offset |= sibs; + xas->xa_shift = 0; + xas->xa_sibs = 0; + + for (;;) { + xas_create(xas, true); + if (xas_error(xas)) + goto restore; + if (xas->xa_index <= (index | XA_CHUNK_MASK)) + goto success; + xas->xa_index -= XA_CHUNK_SIZE; + + for (;;) { + struct xa_node *node = xas->xa_node; + if (node->shift >= shift) + break; + xas->xa_node = xa_parent_locked(xas->xa, node); + xas->xa_offset = node->offset - 1; + if (node->offset != 0) + break; + } + } + +restore: + xas->xa_shift = shift; + xas->xa_sibs = sibs; + xas->xa_index = index; + return; +success: + xas->xa_index = index; + if (xas->xa_node) + xas_set_offset(xas); +} +EXPORT_SYMBOL_GPL(xas_create_range); + +static void update_node(struct xa_state *xas, struct xa_node *node, + int count, int values) +{ + if (!node || (!count && !values)) + return; + + node->count += count; + node->nr_values += values; + XA_NODE_BUG_ON(node, node->count > XA_CHUNK_SIZE); + XA_NODE_BUG_ON(node, node->nr_values > XA_CHUNK_SIZE); + xas_update(xas, node); + if (count < 0) + xas_delete_node(xas); +} + +/** + * xas_store() - Store this entry in the XArray. + * @xas: XArray operation state. + * @entry: New entry. + * + * If @xas is operating on a multi-index entry, the entry returned by this + * function is essentially meaningless (it may be an internal entry or it + * may be %NULL, even if there are non-NULL entries at some of the indices + * covered by the range). This is not a problem for any current users, + * and can be changed if needed. + * + * Return: The old entry at this index. + */ +void *xas_store(struct xa_state *xas, void *entry) +{ + struct xa_node *node; + void __rcu **slot = &xas->xa->xa_head; + unsigned int offset, max; + int count = 0; + int values = 0; + void *first, *next; + bool value = xa_is_value(entry); + + if (entry) { + bool allow_root = !xa_is_node(entry) && !xa_is_zero(entry); + first = xas_create(xas, allow_root); + } else { + first = xas_load(xas); + } + + if (xas_invalid(xas)) + return first; + node = xas->xa_node; + if (node && (xas->xa_shift < node->shift)) + xas->xa_sibs = 0; + if ((first == entry) && !xas->xa_sibs) + return first; + + next = first; + offset = xas->xa_offset; + max = xas->xa_offset + xas->xa_sibs; + if (node) { + slot = &node->slots[offset]; + if (xas->xa_sibs) + xas_squash_marks(xas); + } + if (!entry) + xas_init_marks(xas); + + for (;;) { + /* + * Must clear the marks before setting the entry to NULL, + * otherwise xas_for_each_marked may find a NULL entry and + * stop early. rcu_assign_pointer contains a release barrier + * so the mark clearing will appear to happen before the + * entry is set to NULL. + */ + rcu_assign_pointer(*slot, entry); + if (xa_is_node(next) && (!node || node->shift)) + xas_free_nodes(xas, xa_to_node(next)); + if (!node) + break; + count += !next - !entry; + values += !xa_is_value(first) - !value; + if (entry) { + if (offset == max) + break; + if (!xa_is_sibling(entry)) + entry = xa_mk_sibling(xas->xa_offset); + } else { + if (offset == XA_CHUNK_MASK) + break; + } + next = xa_entry_locked(xas->xa, node, ++offset); + if (!xa_is_sibling(next)) { + if (!entry && (offset > max)) + break; + first = next; + } + slot++; + } + + update_node(xas, node, count, values); + return first; +} +EXPORT_SYMBOL_GPL(xas_store); + +/** + * xas_get_mark() - Returns the state of this mark. + * @xas: XArray operation state. + * @mark: Mark number. + * + * Return: true if the mark is set, false if the mark is clear or @xas + * is in an error state. + */ +bool xas_get_mark(const struct xa_state *xas, xa_mark_t mark) +{ + if (xas_invalid(xas)) + return false; + if (!xas->xa_node) + return xa_marked(xas->xa, mark); + return node_get_mark(xas->xa_node, xas->xa_offset, mark); +} +EXPORT_SYMBOL_GPL(xas_get_mark); + +/** + * xas_set_mark() - Sets the mark on this entry and its parents. + * @xas: XArray operation state. + * @mark: Mark number. + * + * Sets the specified mark on this entry, and walks up the tree setting it + * on all the ancestor entries. Does nothing if @xas has not been walked to + * an entry, or is in an error state. + */ +void xas_set_mark(const struct xa_state *xas, xa_mark_t mark) +{ + struct xa_node *node = xas->xa_node; + unsigned int offset = xas->xa_offset; + + if (xas_invalid(xas)) + return; + + while (node) { + if (node_set_mark(node, offset, mark)) + return; + offset = node->offset; + node = xa_parent_locked(xas->xa, node); + } + + if (!xa_marked(xas->xa, mark)) + xa_mark_set(xas->xa, mark); +} +EXPORT_SYMBOL_GPL(xas_set_mark); + +/** + * xas_clear_mark() - Clears the mark on this entry and its parents. + * @xas: XArray operation state. + * @mark: Mark number. + * + * Clears the specified mark on this entry, and walks back to the head + * attempting to clear it on all the ancestor entries. Does nothing if + * @xas has not been walked to an entry, or is in an error state. + */ +void xas_clear_mark(const struct xa_state *xas, xa_mark_t mark) +{ + struct xa_node *node = xas->xa_node; + unsigned int offset = xas->xa_offset; + + if (xas_invalid(xas)) + return; + + while (node) { + if (!node_clear_mark(node, offset, mark)) + return; + if (node_any_mark(node, mark)) + return; + + offset = node->offset; + node = xa_parent_locked(xas->xa, node); + } + + if (xa_marked(xas->xa, mark)) + xa_mark_clear(xas->xa, mark); +} +EXPORT_SYMBOL_GPL(xas_clear_mark); + +/** + * xas_init_marks() - Initialise all marks for the entry + * @xas: Array operations state. + * + * Initialise all marks for the entry specified by @xas. If we're tracking + * free entries with a mark, we need to set it on all entries. All other + * marks are cleared. + * + * This implementation is not as efficient as it could be; we may walk + * up the tree multiple times. + */ +void xas_init_marks(const struct xa_state *xas) +{ + xa_mark_t mark = 0; + + for (;;) { + if (xa_track_free(xas->xa) && mark == XA_FREE_MARK) + xas_set_mark(xas, mark); + else + xas_clear_mark(xas, mark); + if (mark == XA_MARK_MAX) + break; + mark_inc(mark); + } +} +EXPORT_SYMBOL_GPL(xas_init_marks); + +#ifdef CONFIG_XARRAY_MULTI +static unsigned int node_get_marks(struct xa_node *node, unsigned int offset) +{ + unsigned int marks = 0; + xa_mark_t mark = XA_MARK_0; + + for (;;) { + if (node_get_mark(node, offset, mark)) + marks |= 1 << (__force unsigned int)mark; + if (mark == XA_MARK_MAX) + break; + mark_inc(mark); + } + + return marks; +} + +static inline void node_mark_slots(struct xa_node *node, unsigned int sibs, + xa_mark_t mark) +{ + int i; + + if (sibs == 0) + node_mark_all(node, mark); + else { + for (i = 0; i < XA_CHUNK_SIZE; i += sibs + 1) + node_set_mark(node, i, mark); + } +} + +static void node_set_marks(struct xa_node *node, unsigned int offset, + struct xa_node *child, unsigned int sibs, + unsigned int marks) +{ + xa_mark_t mark = XA_MARK_0; + + for (;;) { + if (marks & (1 << (__force unsigned int)mark)) { + node_set_mark(node, offset, mark); + if (child) + node_mark_slots(child, sibs, mark); + } + if (mark == XA_MARK_MAX) + break; + mark_inc(mark); + } +} + +/** + * xas_split_alloc() - Allocate memory for splitting an entry. + * @xas: XArray operation state. + * @entry: New entry which will be stored in the array. + * @order: Current entry order. + * @gfp: Memory allocation flags. + * + * This function should be called before calling xas_split(). + * If necessary, it will allocate new nodes (and fill them with @entry) + * to prepare for the upcoming split of an entry of @order size into + * entries of the order stored in the @xas. + * + * Context: May sleep if @gfp flags permit. + */ +void xas_split_alloc(struct xa_state *xas, void *entry, unsigned int order, + gfp_t gfp) +{ + unsigned int sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; + unsigned int mask = xas->xa_sibs; + + /* XXX: no support for splitting really large entries yet */ + if (WARN_ON(xas->xa_shift + 2 * XA_CHUNK_SHIFT <= order)) + goto nomem; + if (xas->xa_shift + XA_CHUNK_SHIFT > order) + return; + + do { + unsigned int i; + void *sibling = NULL; + struct xa_node *node; + + node = kmem_cache_alloc_lru(radix_tree_node_cachep, xas->xa_lru, gfp); + if (!node) + goto nomem; + node->array = xas->xa; + for (i = 0; i < XA_CHUNK_SIZE; i++) { + if ((i & mask) == 0) { + RCU_INIT_POINTER(node->slots[i], entry); + sibling = xa_mk_sibling(i); + } else { + RCU_INIT_POINTER(node->slots[i], sibling); + } + } + RCU_INIT_POINTER(node->parent, xas->xa_alloc); + xas->xa_alloc = node; + } while (sibs-- > 0); + + return; +nomem: + xas_destroy(xas); + xas_set_err(xas, -ENOMEM); +} +EXPORT_SYMBOL_GPL(xas_split_alloc); + +/** + * xas_split() - Split a multi-index entry into smaller entries. + * @xas: XArray operation state. + * @entry: New entry to store in the array. + * @order: Current entry order. + * + * The size of the new entries is set in @xas. The value in @entry is + * copied to all the replacement entries. + * + * Context: Any context. The caller should hold the xa_lock. + */ +void xas_split(struct xa_state *xas, void *entry, unsigned int order) +{ + unsigned int sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; + unsigned int offset, marks; + struct xa_node *node; + void *curr = xas_load(xas); + int values = 0; + + node = xas->xa_node; + if (xas_top(node)) + return; + + marks = node_get_marks(node, xas->xa_offset); + + offset = xas->xa_offset + sibs; + do { + if (xas->xa_shift < node->shift) { + struct xa_node *child = xas->xa_alloc; + + xas->xa_alloc = rcu_dereference_raw(child->parent); + child->shift = node->shift - XA_CHUNK_SHIFT; + child->offset = offset; + child->count = XA_CHUNK_SIZE; + child->nr_values = xa_is_value(entry) ? + XA_CHUNK_SIZE : 0; + RCU_INIT_POINTER(child->parent, node); + node_set_marks(node, offset, child, xas->xa_sibs, + marks); + rcu_assign_pointer(node->slots[offset], + xa_mk_node(child)); + if (xa_is_value(curr)) + values--; + xas_update(xas, child); + } else { + unsigned int canon = offset - xas->xa_sibs; + + node_set_marks(node, canon, NULL, 0, marks); + rcu_assign_pointer(node->slots[canon], entry); + while (offset > canon) + rcu_assign_pointer(node->slots[offset--], + xa_mk_sibling(canon)); + values += (xa_is_value(entry) - xa_is_value(curr)) * + (xas->xa_sibs + 1); + } + } while (offset-- > xas->xa_offset); + + node->nr_values += values; + xas_update(xas, node); +} +EXPORT_SYMBOL_GPL(xas_split); +#endif + +/** + * xas_pause() - Pause a walk to drop a lock. + * @xas: XArray operation state. + * + * Some users need to pause a walk and drop the lock they're holding in + * order to yield to a higher priority thread or carry out an operation + * on an entry. Those users should call this function before they drop + * the lock. It resets the @xas to be suitable for the next iteration + * of the loop after the user has reacquired the lock. If most entries + * found during a walk require you to call xas_pause(), the xa_for_each() + * iterator may be more appropriate. + * + * Note that xas_pause() only works for forward iteration. If a user needs + * to pause a reverse iteration, we will need a xas_pause_rev(). + */ +void xas_pause(struct xa_state *xas) +{ + struct xa_node *node = xas->xa_node; + + if (xas_invalid(xas)) + return; + + xas->xa_node = XAS_RESTART; + if (node) { + unsigned long offset = xas->xa_offset; + while (++offset < XA_CHUNK_SIZE) { + if (!xa_is_sibling(xa_entry(xas->xa, node, offset))) + break; + } + xas->xa_index &= ~0UL << node->shift; + xas->xa_index += (offset - xas->xa_offset) << node->shift; + if (xas->xa_index == 0) + xas->xa_node = XAS_BOUNDS; + } else { + xas->xa_index++; + } +} +EXPORT_SYMBOL_GPL(xas_pause); + +/* + * __xas_prev() - Find the previous entry in the XArray. + * @xas: XArray operation state. + * + * Helper function for xas_prev() which handles all the complex cases + * out of line. + */ +void *__xas_prev(struct xa_state *xas) +{ + void *entry; + + if (!xas_frozen(xas->xa_node)) + xas->xa_index--; + if (!xas->xa_node) + return set_bounds(xas); + if (xas_not_node(xas->xa_node)) + return xas_load(xas); + + if (xas->xa_offset != get_offset(xas->xa_index, xas->xa_node)) + xas->xa_offset--; + + while (xas->xa_offset == 255) { + xas->xa_offset = xas->xa_node->offset - 1; + xas->xa_node = xa_parent(xas->xa, xas->xa_node); + if (!xas->xa_node) + return set_bounds(xas); + } + + for (;;) { + entry = xa_entry(xas->xa, xas->xa_node, xas->xa_offset); + if (!xa_is_node(entry)) + return entry; + + xas->xa_node = xa_to_node(entry); + xas_set_offset(xas); + } +} +EXPORT_SYMBOL_GPL(__xas_prev); + +/* + * __xas_next() - Find the next entry in the XArray. + * @xas: XArray operation state. + * + * Helper function for xas_next() which handles all the complex cases + * out of line. + */ +void *__xas_next(struct xa_state *xas) +{ + void *entry; + + if (!xas_frozen(xas->xa_node)) + xas->xa_index++; + if (!xas->xa_node) + return set_bounds(xas); + if (xas_not_node(xas->xa_node)) + return xas_load(xas); + + if (xas->xa_offset != get_offset(xas->xa_index, xas->xa_node)) + xas->xa_offset++; + + while (xas->xa_offset == XA_CHUNK_SIZE) { + xas->xa_offset = xas->xa_node->offset + 1; + xas->xa_node = xa_parent(xas->xa, xas->xa_node); + if (!xas->xa_node) + return set_bounds(xas); + } + + for (;;) { + entry = xa_entry(xas->xa, xas->xa_node, xas->xa_offset); + if (!xa_is_node(entry)) + return entry; + + xas->xa_node = xa_to_node(entry); + xas_set_offset(xas); + } +} +EXPORT_SYMBOL_GPL(__xas_next); + +/** + * xas_find() - Find the next present entry in the XArray. + * @xas: XArray operation state. + * @max: Highest index to return. + * + * If the @xas has not yet been walked to an entry, return the entry + * which has an index >= xas.xa_index. If it has been walked, the entry + * currently being pointed at has been processed, and so we move to the + * next entry. + * + * If no entry is found and the array is smaller than @max, the iterator + * is set to the smallest index not yet in the array. This allows @xas + * to be immediately passed to xas_store(). + * + * Return: The entry, if found, otherwise %NULL. + */ +void *xas_find(struct xa_state *xas, unsigned long max) +{ + void *entry; + + if (xas_error(xas) || xas->xa_node == XAS_BOUNDS) + return NULL; + if (xas->xa_index > max) + return set_bounds(xas); + + if (!xas->xa_node) { + xas->xa_index = 1; + return set_bounds(xas); + } else if (xas->xa_node == XAS_RESTART) { + entry = xas_load(xas); + if (entry || xas_not_node(xas->xa_node)) + return entry; + } else if (!xas->xa_node->shift && + xas->xa_offset != (xas->xa_index & XA_CHUNK_MASK)) { + xas->xa_offset = ((xas->xa_index - 1) & XA_CHUNK_MASK) + 1; + } + + xas_next_offset(xas); + + while (xas->xa_node && (xas->xa_index <= max)) { + if (unlikely(xas->xa_offset == XA_CHUNK_SIZE)) { + xas->xa_offset = xas->xa_node->offset + 1; + xas->xa_node = xa_parent(xas->xa, xas->xa_node); + continue; + } + + entry = xa_entry(xas->xa, xas->xa_node, xas->xa_offset); + if (xa_is_node(entry)) { + xas->xa_node = xa_to_node(entry); + xas->xa_offset = 0; + continue; + } + if (entry && !xa_is_sibling(entry)) + return entry; + + xas_next_offset(xas); + } + + if (!xas->xa_node) + xas->xa_node = XAS_BOUNDS; + return NULL; +} +EXPORT_SYMBOL_GPL(xas_find); + +/** + * xas_find_marked() - Find the next marked entry in the XArray. + * @xas: XArray operation state. + * @max: Highest index to return. + * @mark: Mark number to search for. + * + * If the @xas has not yet been walked to an entry, return the marked entry + * which has an index >= xas.xa_index. If it has been walked, the entry + * currently being pointed at has been processed, and so we return the + * first marked entry with an index > xas.xa_index. + * + * If no marked entry is found and the array is smaller than @max, @xas is + * set to the bounds state and xas->xa_index is set to the smallest index + * not yet in the array. This allows @xas to be immediately passed to + * xas_store(). + * + * If no entry is found before @max is reached, @xas is set to the restart + * state. + * + * Return: The entry, if found, otherwise %NULL. + */ +void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark) +{ + bool advance = true; + unsigned int offset; + void *entry; + + if (xas_error(xas)) + return NULL; + if (xas->xa_index > max) + goto max; + + if (!xas->xa_node) { + xas->xa_index = 1; + goto out; + } else if (xas_top(xas->xa_node)) { + advance = false; + entry = xa_head(xas->xa); + xas->xa_node = NULL; + if (xas->xa_index > max_index(entry)) + goto out; + if (!xa_is_node(entry)) { + if (xa_marked(xas->xa, mark)) + return entry; + xas->xa_index = 1; + goto out; + } + xas->xa_node = xa_to_node(entry); + xas->xa_offset = xas->xa_index >> xas->xa_node->shift; + } + + while (xas->xa_index <= max) { + if (unlikely(xas->xa_offset == XA_CHUNK_SIZE)) { + xas->xa_offset = xas->xa_node->offset + 1; + xas->xa_node = xa_parent(xas->xa, xas->xa_node); + if (!xas->xa_node) + break; + advance = false; + continue; + } + + if (!advance) { + entry = xa_entry(xas->xa, xas->xa_node, xas->xa_offset); + if (xa_is_sibling(entry)) { + xas->xa_offset = xa_to_sibling(entry); + xas_move_index(xas, xas->xa_offset); + } + } + + offset = xas_find_chunk(xas, advance, mark); + if (offset > xas->xa_offset) { + advance = false; + xas_move_index(xas, offset); + /* Mind the wrap */ + if ((xas->xa_index - 1) >= max) + goto max; + xas->xa_offset = offset; + if (offset == XA_CHUNK_SIZE) + continue; + } + + entry = xa_entry(xas->xa, xas->xa_node, xas->xa_offset); + if (!entry && !(xa_track_free(xas->xa) && mark == XA_FREE_MARK)) + continue; + if (xa_is_sibling(entry)) + continue; + if (!xa_is_node(entry)) + return entry; + xas->xa_node = xa_to_node(entry); + xas_set_offset(xas); + } + +out: + if (xas->xa_index > max) + goto max; + return set_bounds(xas); +max: + xas->xa_node = XAS_RESTART; + return NULL; +} +EXPORT_SYMBOL_GPL(xas_find_marked); + +/** + * xas_find_conflict() - Find the next present entry in a range. + * @xas: XArray operation state. + * + * The @xas describes both a range and a position within that range. + * + * Context: Any context. Expects xa_lock to be held. + * Return: The next entry in the range covered by @xas or %NULL. + */ +void *xas_find_conflict(struct xa_state *xas) +{ + void *curr; + + if (xas_error(xas)) + return NULL; + + if (!xas->xa_node) + return NULL; + + if (xas_top(xas->xa_node)) { + curr = xas_start(xas); + if (!curr) + return NULL; + while (xa_is_node(curr)) { + struct xa_node *node = xa_to_node(curr); + curr = xas_descend(xas, node); + } + if (curr) + return curr; + } + + if (xas->xa_node->shift > xas->xa_shift) + return NULL; + + for (;;) { + if (xas->xa_node->shift == xas->xa_shift) { + if ((xas->xa_offset & xas->xa_sibs) == xas->xa_sibs) + break; + } else if (xas->xa_offset == XA_CHUNK_MASK) { + xas->xa_offset = xas->xa_node->offset; + xas->xa_node = xa_parent_locked(xas->xa, xas->xa_node); + if (!xas->xa_node) + break; + continue; + } + curr = xa_entry_locked(xas->xa, xas->xa_node, ++xas->xa_offset); + if (xa_is_sibling(curr)) + continue; + while (xa_is_node(curr)) { + xas->xa_node = xa_to_node(curr); + xas->xa_offset = 0; + curr = xa_entry_locked(xas->xa, xas->xa_node, 0); + } + if (curr) + return curr; + } + xas->xa_offset -= xas->xa_sibs; + return NULL; +} +EXPORT_SYMBOL_GPL(xas_find_conflict); + +/** + * xa_load() - Load an entry from an XArray. + * @xa: XArray. + * @index: index into array. + * + * Context: Any context. Takes and releases the RCU lock. + * Return: The entry at @index in @xa. + */ +void *xa_load(struct xarray *xa, unsigned long index) +{ + XA_STATE(xas, xa, index); + void *entry; + + rcu_read_lock(); + do { + entry = xa_zero_to_null(xas_load(&xas)); + } while (xas_retry(&xas, entry)); + rcu_read_unlock(); + + return entry; +} +EXPORT_SYMBOL(xa_load); + +static void *xas_result(struct xa_state *xas, void *curr) +{ + if (xas_error(xas)) + curr = xas->xa_node; + return curr; +} + +/** + * __xa_erase() - Erase this entry from the XArray while locked. + * @xa: XArray. + * @index: Index into array. + * + * After this function returns, loading from @index will return %NULL. + * If the index is part of a multi-index entry, all indices will be erased + * and none of the entries will be part of a multi-index entry. + * + * Context: Any context. Expects xa_lock to be held on entry. + * Return: The entry which used to be at this index. + */ +void *__xa_erase(struct xarray *xa, unsigned long index) +{ + XA_STATE(xas, xa, index); + return xas_result(&xas, xa_zero_to_null(xas_store(&xas, NULL))); +} +EXPORT_SYMBOL(__xa_erase); + +/** + * xa_erase() - Erase this entry from the XArray. + * @xa: XArray. + * @index: Index of entry. + * + * After this function returns, loading from @index will return %NULL. + * If the index is part of a multi-index entry, all indices will be erased + * and none of the entries will be part of a multi-index entry. + * + * Context: Any context. Takes and releases the xa_lock. + * Return: The entry which used to be at this index. + */ +void *xa_erase(struct xarray *xa, unsigned long index) +{ + void *entry; + + xa_lock(xa); + entry = __xa_erase(xa, index); + xa_unlock(xa); + + return entry; +} +EXPORT_SYMBOL(xa_erase); + +/** + * __xa_store() - Store this entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * You must already be holding the xa_lock when calling this function. + * It will drop the lock if needed to allocate memory, and then reacquire + * it afterwards. + * + * Context: Any context. Expects xa_lock to be held on entry. May + * release and reacquire xa_lock if @gfp flags permit. + * Return: The old entry at this index or xa_err() if an error happened. + */ +void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) +{ + XA_STATE(xas, xa, index); + void *curr; + + if (WARN_ON_ONCE(xa_is_advanced(entry))) + return XA_ERROR(-EINVAL); + if (xa_track_free(xa) && !entry) + entry = XA_ZERO_ENTRY; + + do { + curr = xas_store(&xas, entry); + if (xa_track_free(xa)) + xas_clear_mark(&xas, XA_FREE_MARK); + } while (__xas_nomem(&xas, gfp)); + + return xas_result(&xas, xa_zero_to_null(curr)); +} +EXPORT_SYMBOL(__xa_store); + +/** + * xa_store() - Store this entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * After this function returns, loads from this index will return @entry. + * Storing into an existing multi-index entry updates the entry of every index. + * The marks associated with @index are unaffected unless @entry is %NULL. + * + * Context: Any context. Takes and releases the xa_lock. + * May sleep if the @gfp flags permit. + * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry + * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation + * failed. + */ +void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) +{ + void *curr; + + xa_lock(xa); + curr = __xa_store(xa, index, entry, gfp); + xa_unlock(xa); + + return curr; +} +EXPORT_SYMBOL(xa_store); + +static inline void *__xa_cmpxchg_raw(struct xarray *xa, unsigned long index, + void *old, void *entry, gfp_t gfp); + +/** + * __xa_cmpxchg() - Store this entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @old: Old value to test against. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * You must already be holding the xa_lock when calling this function. + * It will drop the lock if needed to allocate memory, and then reacquire + * it afterwards. + * + * Context: Any context. Expects xa_lock to be held on entry. May + * release and reacquire xa_lock if @gfp flags permit. + * Return: The old entry at this index or xa_err() if an error happened. + */ +void *__xa_cmpxchg(struct xarray *xa, unsigned long index, + void *old, void *entry, gfp_t gfp) +{ + return xa_zero_to_null(__xa_cmpxchg_raw(xa, index, old, entry, gfp)); +} +EXPORT_SYMBOL(__xa_cmpxchg); + +static inline void *__xa_cmpxchg_raw(struct xarray *xa, unsigned long index, + void *old, void *entry, gfp_t gfp) +{ + XA_STATE(xas, xa, index); + void *curr; + + if (WARN_ON_ONCE(xa_is_advanced(entry))) + return XA_ERROR(-EINVAL); + + do { + curr = xas_load(&xas); + if (curr == old) { + xas_store(&xas, entry); + if (xa_track_free(xa) && entry && !curr) + xas_clear_mark(&xas, XA_FREE_MARK); + } + } while (__xas_nomem(&xas, gfp)); + + return xas_result(&xas, curr); +} + +/** + * __xa_insert() - Store this entry in the XArray if no entry is present. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Inserting a NULL entry will store a reserved entry (like xa_reserve()) + * if no entry is present. Inserting will fail if a reserved entry is + * present, even though loading from this index will return NULL. + * + * Context: Any context. Expects xa_lock to be held on entry. May + * release and reacquire xa_lock if @gfp flags permit. + * Return: 0 if the store succeeded. -EBUSY if another entry was present. + * -ENOMEM if memory could not be allocated. + */ +int __xa_insert(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp) +{ + void *curr; + int errno; + + if (!entry) + entry = XA_ZERO_ENTRY; + curr = __xa_cmpxchg_raw(xa, index, NULL, entry, gfp); + errno = xa_err(curr); + if (errno) + return errno; + return (curr != NULL) ? -EBUSY : 0; +} +EXPORT_SYMBOL(__xa_insert); + +#ifdef CONFIG_XARRAY_MULTI +static void xas_set_range(struct xa_state *xas, unsigned long first, + unsigned long last) +{ + unsigned int shift = 0; + unsigned long sibs = last - first; + unsigned int offset = XA_CHUNK_MASK; + + xas_set(xas, first); + + while ((first & XA_CHUNK_MASK) == 0) { + if (sibs < XA_CHUNK_MASK) + break; + if ((sibs == XA_CHUNK_MASK) && (offset < XA_CHUNK_MASK)) + break; + shift += XA_CHUNK_SHIFT; + if (offset == XA_CHUNK_MASK) + offset = sibs & XA_CHUNK_MASK; + sibs >>= XA_CHUNK_SHIFT; + first >>= XA_CHUNK_SHIFT; + } + + offset = first & XA_CHUNK_MASK; + if (offset + sibs > XA_CHUNK_MASK) + sibs = XA_CHUNK_MASK - offset; + if ((((first + sibs + 1) << shift) - 1) > last) + sibs -= 1; + + xas->xa_shift = shift; + xas->xa_sibs = sibs; +} + +/** + * xa_store_range() - Store this entry at a range of indices in the XArray. + * @xa: XArray. + * @first: First index to affect. + * @last: Last index to affect. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * After this function returns, loads from any index between @first and @last, + * inclusive will return @entry. + * Storing into an existing multi-index entry updates the entry of every index. + * The marks associated with @index are unaffected unless @entry is %NULL. + * + * Context: Process context. Takes and releases the xa_lock. May sleep + * if the @gfp flags permit. + * Return: %NULL on success, xa_err(-EINVAL) if @entry cannot be stored in + * an XArray, or xa_err(-ENOMEM) if memory allocation failed. + */ +void *xa_store_range(struct xarray *xa, unsigned long first, + unsigned long last, void *entry, gfp_t gfp) +{ + XA_STATE(xas, xa, 0); + + if (WARN_ON_ONCE(xa_is_internal(entry))) + return XA_ERROR(-EINVAL); + if (last < first) + return XA_ERROR(-EINVAL); + + do { + xas_lock(&xas); + if (entry) { + unsigned int order = BITS_PER_LONG; + if (last + 1) + order = __ffs(last + 1); + xas_set_order(&xas, last, order); + xas_create(&xas, true); + if (xas_error(&xas)) + goto unlock; + } + do { + xas_set_range(&xas, first, last); + xas_store(&xas, entry); + if (xas_error(&xas)) + goto unlock; + first += xas_size(&xas); + } while (first <= last); +unlock: + xas_unlock(&xas); + } while (xas_nomem(&xas, gfp)); + + return xas_result(&xas, NULL); +} +EXPORT_SYMBOL(xa_store_range); + +/** + * xas_get_order() - Get the order of an entry. + * @xas: XArray operation state. + * + * Called after xas_load, the xas should not be in an error state. + * + * Return: A number between 0 and 63 indicating the order of the entry. + */ +int xas_get_order(struct xa_state *xas) +{ + int order = 0; + + if (!xas->xa_node) + return 0; + + for (;;) { + unsigned int slot = xas->xa_offset + (1 << order); + + if (slot >= XA_CHUNK_SIZE) + break; + if (!xa_is_sibling(xa_entry(xas->xa, xas->xa_node, slot))) + break; + order++; + } + + order += xas->xa_node->shift; + return order; +} +EXPORT_SYMBOL_GPL(xas_get_order); + +/** + * xa_get_order() - Get the order of an entry. + * @xa: XArray. + * @index: Index of the entry. + * + * Return: A number between 0 and 63 indicating the order of the entry. + */ +int xa_get_order(struct xarray *xa, unsigned long index) +{ + XA_STATE(xas, xa, index); + int order = 0; + void *entry; + + rcu_read_lock(); + entry = xas_load(&xas); + if (entry) + order = xas_get_order(&xas); + rcu_read_unlock(); + + return order; +} +EXPORT_SYMBOL(xa_get_order); +#endif /* CONFIG_XARRAY_MULTI */ + +/** + * __xa_alloc() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @limit: Range for allocated ID. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Any context. Expects xa_lock to be held on entry. May + * release and reacquire xa_lock if @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory could not be allocated or + * -EBUSY if there are no free entries in @limit. + */ +int __xa_alloc(struct xarray *xa, u32 *id, void *entry, + struct xa_limit limit, gfp_t gfp) +{ + XA_STATE(xas, xa, 0); + + if (WARN_ON_ONCE(xa_is_advanced(entry))) + return -EINVAL; + if (WARN_ON_ONCE(!xa_track_free(xa))) + return -EINVAL; + + if (!entry) + entry = XA_ZERO_ENTRY; + + do { + xas.xa_index = limit.min; + xas_find_marked(&xas, limit.max, XA_FREE_MARK); + if (xas.xa_node == XAS_RESTART) + xas_set_err(&xas, -EBUSY); + else + *id = xas.xa_index; + xas_store(&xas, entry); + xas_clear_mark(&xas, XA_FREE_MARK); + } while (__xas_nomem(&xas, gfp)); + + return xas_error(&xas); +} +EXPORT_SYMBOL(__xa_alloc); + +/** + * __xa_alloc_cyclic() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of allocated ID. + * @next: Pointer to next ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * The search for an empty entry will start at @next and will wrap + * around if necessary. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Any context. Expects xa_lock to be held on entry. May + * release and reacquire xa_lock if @gfp flags permit. + * Return: 0 if the allocation succeeded without wrapping. 1 if the + * allocation succeeded after wrapping, -ENOMEM if memory could not be + * allocated or -EBUSY if there are no free entries in @limit. + */ +int __xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry, + struct xa_limit limit, u32 *next, gfp_t gfp) +{ + u32 min = limit.min; + int ret; + + limit.min = max(min, *next); + ret = __xa_alloc(xa, id, entry, limit, gfp); + if ((xa->xa_flags & XA_FLAGS_ALLOC_WRAPPED) && ret == 0) { + xa->xa_flags &= ~XA_FLAGS_ALLOC_WRAPPED; + ret = 1; + } + + if (ret < 0 && limit.min > min) { + limit.min = min; + ret = __xa_alloc(xa, id, entry, limit, gfp); + if (ret == 0) + ret = 1; + } + + if (ret >= 0) { + *next = *id + 1; + if (*next == 0) + xa->xa_flags |= XA_FLAGS_ALLOC_WRAPPED; + } + return ret; +} +EXPORT_SYMBOL(__xa_alloc_cyclic); + +/** + * __xa_set_mark() - Set this mark on this entry while locked. + * @xa: XArray. + * @index: Index of entry. + * @mark: Mark number. + * + * Attempting to set a mark on a %NULL entry does not succeed. + * + * Context: Any context. Expects xa_lock to be held on entry. + */ +void __xa_set_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) +{ + XA_STATE(xas, xa, index); + void *entry = xas_load(&xas); + + if (entry) + xas_set_mark(&xas, mark); +} +EXPORT_SYMBOL(__xa_set_mark); + +/** + * __xa_clear_mark() - Clear this mark on this entry while locked. + * @xa: XArray. + * @index: Index of entry. + * @mark: Mark number. + * + * Context: Any context. Expects xa_lock to be held on entry. + */ +void __xa_clear_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) +{ + XA_STATE(xas, xa, index); + void *entry = xas_load(&xas); + + if (entry) + xas_clear_mark(&xas, mark); +} +EXPORT_SYMBOL(__xa_clear_mark); + +/** + * xa_get_mark() - Inquire whether this mark is set on this entry. + * @xa: XArray. + * @index: Index of entry. + * @mark: Mark number. + * + * This function uses the RCU read lock, so the result may be out of date + * by the time it returns. If you need the result to be stable, use a lock. + * + * Context: Any context. Takes and releases the RCU lock. + * Return: True if the entry at @index has this mark set, false if it doesn't. + */ +bool xa_get_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) +{ + XA_STATE(xas, xa, index); + void *entry; + + rcu_read_lock(); + entry = xas_start(&xas); + while (xas_get_mark(&xas, mark)) { + if (!xa_is_node(entry)) + goto found; + entry = xas_descend(&xas, xa_to_node(entry)); + } + rcu_read_unlock(); + return false; + found: + rcu_read_unlock(); + return true; +} +EXPORT_SYMBOL(xa_get_mark); + +/** + * xa_set_mark() - Set this mark on this entry. + * @xa: XArray. + * @index: Index of entry. + * @mark: Mark number. + * + * Attempting to set a mark on a %NULL entry does not succeed. + * + * Context: Process context. Takes and releases the xa_lock. + */ +void xa_set_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) +{ + xa_lock(xa); + __xa_set_mark(xa, index, mark); + xa_unlock(xa); +} +EXPORT_SYMBOL(xa_set_mark); + +/** + * xa_clear_mark() - Clear this mark on this entry. + * @xa: XArray. + * @index: Index of entry. + * @mark: Mark number. + * + * Clearing a mark always succeeds. + * + * Context: Process context. Takes and releases the xa_lock. + */ +void xa_clear_mark(struct xarray *xa, unsigned long index, xa_mark_t mark) +{ + xa_lock(xa); + __xa_clear_mark(xa, index, mark); + xa_unlock(xa); +} +EXPORT_SYMBOL(xa_clear_mark); + +/** + * xa_find() - Search the XArray for an entry. + * @xa: XArray. + * @indexp: Pointer to an index. + * @max: Maximum index to search to. + * @filter: Selection criterion. + * + * Finds the entry in @xa which matches the @filter, and has the lowest + * index that is at least @indexp and no more than @max. + * If an entry is found, @indexp is updated to be the index of the entry. + * This function is protected by the RCU read lock, so it may not find + * entries which are being simultaneously added. It will not return an + * %XA_RETRY_ENTRY; if you need to see retry entries, use xas_find(). + * + * Context: Any context. Takes and releases the RCU lock. + * Return: The entry, if found, otherwise %NULL. + */ +void *xa_find(struct xarray *xa, unsigned long *indexp, + unsigned long max, xa_mark_t filter) +{ + XA_STATE(xas, xa, *indexp); + void *entry; + + rcu_read_lock(); + do { + if ((__force unsigned int)filter < XA_MAX_MARKS) + entry = xas_find_marked(&xas, max, filter); + else + entry = xas_find(&xas, max); + } while (xas_retry(&xas, entry)); + rcu_read_unlock(); + + if (entry) + *indexp = xas.xa_index; + return entry; +} +EXPORT_SYMBOL(xa_find); + +static bool xas_sibling(struct xa_state *xas) +{ + struct xa_node *node = xas->xa_node; + unsigned long mask; + + if (!IS_ENABLED(CONFIG_XARRAY_MULTI) || !node) + return false; + mask = (XA_CHUNK_SIZE << node->shift) - 1; + return (xas->xa_index & mask) > + ((unsigned long)xas->xa_offset << node->shift); +} + +/** + * xa_find_after() - Search the XArray for a present entry. + * @xa: XArray. + * @indexp: Pointer to an index. + * @max: Maximum index to search to. + * @filter: Selection criterion. + * + * Finds the entry in @xa which matches the @filter and has the lowest + * index that is above @indexp and no more than @max. + * If an entry is found, @indexp is updated to be the index of the entry. + * This function is protected by the RCU read lock, so it may miss entries + * which are being simultaneously added. It will not return an + * %XA_RETRY_ENTRY; if you need to see retry entries, use xas_find(). + * + * Context: Any context. Takes and releases the RCU lock. + * Return: The pointer, if found, otherwise %NULL. + */ +void *xa_find_after(struct xarray *xa, unsigned long *indexp, + unsigned long max, xa_mark_t filter) +{ + XA_STATE(xas, xa, *indexp + 1); + void *entry; + + if (xas.xa_index == 0) + return NULL; + + rcu_read_lock(); + for (;;) { + if ((__force unsigned int)filter < XA_MAX_MARKS) + entry = xas_find_marked(&xas, max, filter); + else + entry = xas_find(&xas, max); + + if (xas_invalid(&xas)) + break; + if (xas_sibling(&xas)) + continue; + if (!xas_retry(&xas, entry)) + break; + } + rcu_read_unlock(); + + if (entry) + *indexp = xas.xa_index; + return entry; +} +EXPORT_SYMBOL(xa_find_after); + +static unsigned int xas_extract_present(struct xa_state *xas, void **dst, + unsigned long max, unsigned int n) +{ + void *entry; + unsigned int i = 0; + + rcu_read_lock(); + xas_for_each(xas, entry, max) { + if (xas_retry(xas, entry)) + continue; + dst[i++] = entry; + if (i == n) + break; + } + rcu_read_unlock(); + + return i; +} + +static unsigned int xas_extract_marked(struct xa_state *xas, void **dst, + unsigned long max, unsigned int n, xa_mark_t mark) +{ + void *entry; + unsigned int i = 0; + + rcu_read_lock(); + xas_for_each_marked(xas, entry, max, mark) { + if (xas_retry(xas, entry)) + continue; + dst[i++] = entry; + if (i == n) + break; + } + rcu_read_unlock(); + + return i; +} + +/** + * xa_extract() - Copy selected entries from the XArray into a normal array. + * @xa: The source XArray to copy from. + * @dst: The buffer to copy entries into. + * @start: The first index in the XArray eligible to be selected. + * @max: The last index in the XArray eligible to be selected. + * @n: The maximum number of entries to copy. + * @filter: Selection criterion. + * + * Copies up to @n entries that match @filter from the XArray. The + * copied entries will have indices between @start and @max, inclusive. + * + * The @filter may be an XArray mark value, in which case entries which are + * marked with that mark will be copied. It may also be %XA_PRESENT, in + * which case all entries which are not %NULL will be copied. + * + * The entries returned may not represent a snapshot of the XArray at a + * moment in time. For example, if another thread stores to index 5, then + * index 10, calling xa_extract() may return the old contents of index 5 + * and the new contents of index 10. Indices not modified while this + * function is running will not be skipped. + * + * If you need stronger guarantees, holding the xa_lock across calls to this + * function will prevent concurrent modification. + * + * Context: Any context. Takes and releases the RCU lock. + * Return: The number of entries copied. + */ +unsigned int xa_extract(struct xarray *xa, void **dst, unsigned long start, + unsigned long max, unsigned int n, xa_mark_t filter) +{ + XA_STATE(xas, xa, start); + + if (!n) + return 0; + + if ((__force unsigned int)filter < XA_MAX_MARKS) + return xas_extract_marked(&xas, dst, max, n, filter); + return xas_extract_present(&xas, dst, max, n); +} +EXPORT_SYMBOL(xa_extract); + +/** + * xa_delete_node() - Private interface for workingset code. + * @node: Node to be removed from the tree. + * @update: Function to call to update ancestor nodes. + * + * Context: xa_lock must be held on entry and will not be released. + */ +void xa_delete_node(struct xa_node *node, xa_update_node_t update) +{ + struct xa_state xas = { + .xa = node->array, + .xa_index = (unsigned long)node->offset << + (node->shift + XA_CHUNK_SHIFT), + .xa_shift = node->shift + XA_CHUNK_SHIFT, + .xa_offset = node->offset, + .xa_node = xa_parent_locked(node->array, node), + .xa_update = update, + }; + + xas_store(&xas, NULL); +} +EXPORT_SYMBOL_GPL(xa_delete_node); /* For the benefit of the test suite */ + +/** + * xa_destroy() - Free all internal data structures. + * @xa: XArray. + * + * After calling this function, the XArray is empty and has freed all memory + * allocated for its internal data structures. You are responsible for + * freeing the objects referenced by the XArray. + * + * Context: Any context. Takes and releases the xa_lock, interrupt-safe. + */ +void xa_destroy(struct xarray *xa) +{ + XA_STATE(xas, xa, 0); + unsigned long flags; + void *entry; + + xas.xa_node = NULL; + xas_lock_irqsave(&xas, flags); + entry = xa_head_locked(xa); + RCU_INIT_POINTER(xa->xa_head, NULL); + xas_init_marks(&xas); + if (xa_zero_busy(xa)) + xa_mark_clear(xa, XA_FREE_MARK); + /* lockdep checks we're still holding the lock in xas_free_nodes() */ + if (xa_is_node(entry)) + xas_free_nodes(&xas, xa_to_node(entry)); + xas_unlock_irqrestore(&xas, flags); +} +EXPORT_SYMBOL(xa_destroy); + +#ifdef XA_DEBUG +void xa_dump_node(const struct xa_node *node) +{ + unsigned i, j; + + if (!node) + return; + if ((unsigned long)node & 3) { + pr_cont("node %px\n", node); + return; + } + + pr_cont("node %px %s %d parent %px shift %d count %d values %d " + "array %px list %px %px marks", + node, node->parent ? "offset" : "max", node->offset, + node->parent, node->shift, node->count, node->nr_values, + node->array, node->private_list.prev, node->private_list.next); + for (i = 0; i < XA_MAX_MARKS; i++) + for (j = 0; j < XA_MARK_LONGS; j++) + pr_cont(" %lx", node->marks[i][j]); + pr_cont("\n"); +} + +void xa_dump_index(unsigned long index, unsigned int shift) +{ + if (!shift) + pr_info("%lu: ", index); + else if (shift >= BITS_PER_LONG) + pr_info("0-%lu: ", ~0UL); + else + pr_info("%lu-%lu: ", index, index | ((1UL << shift) - 1)); +} + +void xa_dump_entry(const void *entry, unsigned long index, unsigned long shift) +{ + if (!entry) + return; + + xa_dump_index(index, shift); + + if (xa_is_node(entry)) { + if (shift == 0) { + pr_cont("%px\n", entry); + } else { + unsigned long i; + struct xa_node *node = xa_to_node(entry); + xa_dump_node(node); + for (i = 0; i < XA_CHUNK_SIZE; i++) + xa_dump_entry(node->slots[i], + index + (i << node->shift), node->shift); + } + } else if (xa_is_value(entry)) + pr_cont("value %ld (0x%lx) [%px]\n", xa_to_value(entry), + xa_to_value(entry), entry); + else if (!xa_is_internal(entry)) + pr_cont("%px\n", entry); + else if (xa_is_retry(entry)) + pr_cont("retry (%ld)\n", xa_to_internal(entry)); + else if (xa_is_sibling(entry)) + pr_cont("sibling (slot %ld)\n", xa_to_sibling(entry)); + else if (xa_is_zero(entry)) + pr_cont("zero (%ld)\n", xa_to_internal(entry)); + else + pr_cont("UNKNOWN ENTRY (%px)\n", entry); +} + +void xa_dump(const struct xarray *xa) +{ + void *entry = xa->xa_head; + unsigned int shift = 0; + + pr_info("xarray: %px head %px flags %x marks %d %d %d\n", xa, entry, + xa->xa_flags, xa_marked(xa, XA_MARK_0), + xa_marked(xa, XA_MARK_1), xa_marked(xa, XA_MARK_2)); + if (xa_is_node(entry)) + shift = xa_to_node(entry)->shift + XA_CHUNK_SHIFT; + xa_dump_entry(entry, 0, shift); +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.h new file mode 100644 index 0000000000..0097f1a88c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ixgbe/kcompat_xarray.h @@ -0,0 +1,1912 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 1999 - 2026 Intel Corporation */ + +/* SPDX-License-Identifier: GPL-2.0+ */ +#ifndef _LINUX_XARRAY_H +#define _LINUX_XARRAY_H +/* + * eXtensible Arrays + * Copyright (c) 2017 Microsoft Corporation + * Author: Matthew Wilcox + * + * See Documentation/core-api/xarray.rst for how to use the XArray. + */ + +/* This is taken from upstream commit ae9b3c0e79bc */ + +#include "kcompat.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct list_lru; + +/* Add internal might_alloc implementation without lockdep. */ +static inline void __might_alloc(gfp_t gfp_mask) +{ + might_sleep_if(!!(gfp_mask & __GFP_DIRECT_RECLAIM)); +} + +/* + * The bottom two bits of the entry determine how the XArray interprets + * the contents: + * + * 00: Pointer entry + * 10: Internal entry + * x1: Value entry or tagged pointer + * + * Attempting to store internal entries in the XArray is a bug. + * + * Most internal entries are pointers to the next node in the tree. + * The following internal entries have a special meaning: + * + * 0-62: Sibling entries + * 256: Retry entry + * 257: Zero entry + * + * Errors are also represented as internal entries, but use the negative + * space (-4094 to -2). They're never stored in the slots array; only + * returned by the normal API. + */ + +#define BITS_PER_XA_VALUE (BITS_PER_LONG - 1) + +/** + * xa_mk_value() - Create an XArray entry from an integer. + * @v: Value to store in XArray. + * + * Context: Any context. + * Return: An entry suitable for storing in the XArray. + */ +static inline void *xa_mk_value(unsigned long v) +{ + WARN_ON((long)v < 0); + return (void *)((v << 1) | 1); +} + +/** + * xa_to_value() - Get value stored in an XArray entry. + * @entry: XArray entry. + * + * Context: Any context. + * Return: The value stored in the XArray entry. + */ +static inline unsigned long xa_to_value(const void *entry) +{ + return (unsigned long)entry >> 1; +} + +/** + * xa_is_value() - Determine if an entry is a value. + * @entry: XArray entry. + * + * Context: Any context. + * Return: True if the entry is a value, false if it is a pointer. + */ +static inline bool xa_is_value(const void *entry) +{ + return (unsigned long)entry & 1; +} + +/** + * xa_tag_pointer() - Create an XArray entry for a tagged pointer. + * @p: Plain pointer. + * @tag: Tag value (0, 1 or 3). + * + * If the user of the XArray prefers, they can tag their pointers instead + * of storing value entries. Three tags are available (0, 1 and 3). + * These are distinct from the xa_mark_t as they are not replicated up + * through the array and cannot be searched for. + * + * Context: Any context. + * Return: An XArray entry. + */ +static inline void *xa_tag_pointer(void *p, unsigned long tag) +{ + return (void *)((unsigned long)p | tag); +} + +/** + * xa_untag_pointer() - Turn an XArray entry into a plain pointer. + * @entry: XArray entry. + * + * If you have stored a tagged pointer in the XArray, call this function + * to get the untagged version of the pointer. + * + * Context: Any context. + * Return: A pointer. + */ +static inline void *xa_untag_pointer(void *entry) +{ + return (void *)((unsigned long)entry & ~3UL); +} + +/** + * xa_pointer_tag() - Get the tag stored in an XArray entry. + * @entry: XArray entry. + * + * If you have stored a tagged pointer in the XArray, call this function + * to get the tag of that pointer. + * + * Context: Any context. + * Return: A tag. + */ +static inline unsigned int xa_pointer_tag(void *entry) +{ + return (unsigned long)entry & 3UL; +} + +/* + * xa_mk_internal() - Create an internal entry. + * @v: Value to turn into an internal entry. + * + * Internal entries are used for a number of purposes. Entries 0-255 are + * used for sibling entries (only 0-62 are used by the current code). 256 + * is used for the retry entry. 257 is used for the reserved / zero entry. + * Negative internal entries are used to represent errnos. Node pointers + * are also tagged as internal entries in some situations. + * + * Context: Any context. + * Return: An XArray internal entry corresponding to this value. + */ +static inline void *xa_mk_internal(unsigned long v) +{ + return (void *)((v << 2) | 2); +} + +/* + * xa_to_internal() - Extract the value from an internal entry. + * @entry: XArray entry. + * + * Context: Any context. + * Return: The value which was stored in the internal entry. + */ +static inline unsigned long xa_to_internal(const void *entry) +{ + return (unsigned long)entry >> 2; +} + +/* + * xa_is_internal() - Is the entry an internal entry? + * @entry: XArray entry. + * + * Context: Any context. + * Return: %true if the entry is an internal entry. + */ +static inline bool xa_is_internal(const void *entry) +{ + return ((unsigned long)entry & 3) == 2; +} + +#define XA_ZERO_ENTRY xa_mk_internal(257) + +/** + * xa_is_zero() - Is the entry a zero entry? + * @entry: Entry retrieved from the XArray + * + * The normal API will return NULL as the contents of a slot containing + * a zero entry. You can only see zero entries by using the advanced API. + * + * Return: %true if the entry is a zero entry. + */ +static inline bool xa_is_zero(const void *entry) +{ + return unlikely(entry == XA_ZERO_ENTRY); +} + +/** + * xa_is_err() - Report whether an XArray operation returned an error + * @entry: Result from calling an XArray function + * + * If an XArray operation cannot complete an operation, it will return + * a special value indicating an error. This function tells you + * whether an error occurred; xa_err() tells you which error occurred. + * + * Context: Any context. + * Return: %true if the entry indicates an error. + */ +static inline bool xa_is_err(const void *entry) +{ + return unlikely(xa_is_internal(entry) && + entry >= xa_mk_internal(-MAX_ERRNO)); +} + +/** + * xa_err() - Turn an XArray result into an errno. + * @entry: Result from calling an XArray function. + * + * If an XArray operation cannot complete an operation, it will return + * a special pointer value which encodes an errno. This function extracts + * the errno from the pointer value, or returns 0 if the pointer does not + * represent an errno. + * + * Context: Any context. + * Return: A negative errno or 0. + */ +static inline int xa_err(void *entry) +{ + /* xa_to_internal() would not do sign extension. */ + if (xa_is_err(entry)) + return (long)entry >> 2; + return 0; +} + +/** + * struct xa_limit - Represents a range of IDs. + * @min: The lowest ID to allocate (inclusive). + * @max: The maximum ID to allocate (inclusive). + * + * This structure is used either directly or via the XA_LIMIT() macro + * to communicate the range of IDs that are valid for allocation. + * Three common ranges are predefined for you: + * * xa_limit_32b - [0 - UINT_MAX] + * * xa_limit_31b - [0 - INT_MAX] + * * xa_limit_16b - [0 - USHRT_MAX] + */ +struct xa_limit { + u32 max; + u32 min; +}; + +#define XA_LIMIT(_min, _max) (struct xa_limit) { .min = _min, .max = _max } + +#define xa_limit_32b XA_LIMIT(0, UINT_MAX) +#define xa_limit_31b XA_LIMIT(0, INT_MAX) +#define xa_limit_16b XA_LIMIT(0, USHRT_MAX) + +typedef unsigned __bitwise xa_mark_t; +#define XA_MARK_0 ((__force xa_mark_t)0U) +#define XA_MARK_1 ((__force xa_mark_t)1U) +#define XA_MARK_2 ((__force xa_mark_t)2U) +#define XA_PRESENT ((__force xa_mark_t)8U) +#define XA_MARK_MAX XA_MARK_2 +#define XA_FREE_MARK XA_MARK_0 + +enum xa_lock_type { + XA_LOCK_IRQ = 1, + XA_LOCK_BH = 2, +}; + +/* + * Values for xa_flags. The radix tree stores its GFP flags in the xa_flags, + * and we remain compatible with that. + */ +#define XA_FLAGS_LOCK_IRQ ((__force gfp_t)XA_LOCK_IRQ) +#define XA_FLAGS_LOCK_BH ((__force gfp_t)XA_LOCK_BH) +#define XA_FLAGS_TRACK_FREE ((__force gfp_t)4U) +#define XA_FLAGS_ZERO_BUSY ((__force gfp_t)8U) +#define XA_FLAGS_ALLOC_WRAPPED ((__force gfp_t)16U) +#define XA_FLAGS_ACCOUNT ((__force gfp_t)32U) +#define XA_FLAGS_MARK(mark) ((__force gfp_t)((1U << __GFP_BITS_SHIFT) << \ + (__force unsigned)(mark))) + +/* ALLOC is for a normal 0-based alloc. ALLOC1 is for an 1-based alloc */ +#define XA_FLAGS_ALLOC (XA_FLAGS_TRACK_FREE | XA_FLAGS_MARK(XA_FREE_MARK)) +#define XA_FLAGS_ALLOC1 (XA_FLAGS_TRACK_FREE | XA_FLAGS_ZERO_BUSY) + +/** + * struct xarray - The anchor of the XArray. + * @xa_lock: Lock that protects the contents of the XArray. + * + * To use the xarray, define it statically or embed it in your data structure. + * It is a very small data structure, so it does not usually make sense to + * allocate it separately and keep a pointer to it in your data structure. + * + * You may use the xa_lock to protect your own data structures as well. + */ +/* + * If all of the entries in the array are NULL, @xa_head is a NULL pointer. + * If the only non-NULL entry in the array is at index 0, @xa_head is that + * entry. If any other entry in the array is non-NULL, @xa_head points + * to an @xa_node. + */ +struct xarray { + spinlock_t xa_lock; +/* private: The rest of the data structure is not to be used directly. */ + gfp_t xa_flags; + void __rcu * xa_head; +}; + +#define XARRAY_INIT(name, flags) { \ + .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ + .xa_flags = flags, \ + .xa_head = NULL, \ +} + +/** + * DEFINE_XARRAY_FLAGS() - Define an XArray with custom flags. + * @name: A string that names your XArray. + * @flags: XA_FLAG values. + * + * This is intended for file scope definitions of XArrays. It declares + * and initialises an empty XArray with the chosen name and flags. It is + * equivalent to calling xa_init_flags() on the array, but it does the + * initialisation at compiletime instead of runtime. + */ +#define DEFINE_XARRAY_FLAGS(name, flags) \ + struct xarray name = XARRAY_INIT(name, flags) + +/** + * DEFINE_XARRAY() - Define an XArray. + * @name: A string that names your XArray. + * + * This is intended for file scope definitions of XArrays. It declares + * and initialises an empty XArray with the chosen name. It is equivalent + * to calling xa_init() on the array, but it does the initialisation at + * compiletime instead of runtime. + */ +#define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0) + +/** + * DEFINE_XARRAY_ALLOC() - Define an XArray which allocates IDs starting at 0. + * @name: A string that names your XArray. + * + * This is intended for file scope definitions of allocating XArrays. + * See also DEFINE_XARRAY(). + */ +#define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC) + +/** + * DEFINE_XARRAY_ALLOC1() - Define an XArray which allocates IDs starting at 1. + * @name: A string that names your XArray. + * + * This is intended for file scope definitions of allocating XArrays. + * See also DEFINE_XARRAY(). + */ +#define DEFINE_XARRAY_ALLOC1(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC1) + +void *xa_load(struct xarray *, unsigned long index); +void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); +void *xa_erase(struct xarray *, unsigned long index); +void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, + void *entry, gfp_t); +bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); +void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); +void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); +void *xa_find(struct xarray *xa, unsigned long *index, + unsigned long max, xa_mark_t) __attribute__((nonnull(2))); +void *xa_find_after(struct xarray *xa, unsigned long *index, + unsigned long max, xa_mark_t) __attribute__((nonnull(2))); +unsigned int xa_extract(struct xarray *, void **dst, unsigned long start, + unsigned long max, unsigned int n, xa_mark_t); +void xa_destroy(struct xarray *); + +/** + * xa_init_flags() - Initialise an empty XArray with flags. + * @xa: XArray. + * @flags: XA_FLAG values. + * + * If you need to initialise an XArray with special flags (eg you need + * to take the lock from interrupt context), use this function instead + * of xa_init(). + * + * Context: Any context. + */ +static inline void xa_init_flags(struct xarray *xa, gfp_t flags) +{ + spin_lock_init(&xa->xa_lock); + xa->xa_flags = flags; + xa->xa_head = NULL; +} + +/** + * xa_init() - Initialise an empty XArray. + * @xa: XArray. + * + * An empty XArray is full of NULL entries. + * + * Context: Any context. + */ +static inline void xa_init(struct xarray *xa) +{ + xa_init_flags(xa, 0); +} + +/** + * xa_empty() - Determine if an array has any present entries. + * @xa: XArray. + * + * Context: Any context. + * Return: %true if the array contains only NULL pointers. + */ +static inline bool xa_empty(const struct xarray *xa) +{ + return xa->xa_head == NULL; +} + +/** + * xa_marked() - Inquire whether any entry in this array has a mark set + * @xa: Array + * @mark: Mark value + * + * Context: Any context. + * Return: %true if any entry has this mark set. + */ +static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark) +{ + return xa->xa_flags & XA_FLAGS_MARK(mark); +} + +/** + * xa_for_each_range() - Iterate over a portion of an XArray. + * @xa: XArray. + * @index: Index of @entry. + * @entry: Entry retrieved from array. + * @start: First index to retrieve from array. + * @last: Last index to retrieve from array. + * + * During the iteration, @entry will have the value of the entry stored + * in @xa at @index. You may modify @index during the iteration if you + * want to skip or reprocess indices. It is safe to modify the array + * during the iteration. At the end of the iteration, @entry will be set + * to NULL and @index will have a value less than or equal to max. + * + * xa_for_each_range() is O(n.log(n)) while xas_for_each() is O(n). You have + * to handle your own locking with xas_for_each(), and if you have to unlock + * after each iteration, it will also end up being O(n.log(n)). + * xa_for_each_range() will spin if it hits a retry entry; if you intend to + * see retry entries, you should use the xas_for_each() iterator instead. + * The xas_for_each() iterator will expand into more inline code than + * xa_for_each_range(). + * + * Context: Any context. Takes and releases the RCU lock. + */ +#define xa_for_each_range(xa, index, entry, start, last) \ + for (index = start, \ + entry = xa_find(xa, &index, last, XA_PRESENT); \ + entry; \ + entry = xa_find_after(xa, &index, last, XA_PRESENT)) + +/** + * xa_for_each_start() - Iterate over a portion of an XArray. + * @xa: XArray. + * @index: Index of @entry. + * @entry: Entry retrieved from array. + * @start: First index to retrieve from array. + * + * During the iteration, @entry will have the value of the entry stored + * in @xa at @index. You may modify @index during the iteration if you + * want to skip or reprocess indices. It is safe to modify the array + * during the iteration. At the end of the iteration, @entry will be set + * to NULL and @index will have a value less than or equal to max. + * + * xa_for_each_start() is O(n.log(n)) while xas_for_each() is O(n). You have + * to handle your own locking with xas_for_each(), and if you have to unlock + * after each iteration, it will also end up being O(n.log(n)). + * xa_for_each_start() will spin if it hits a retry entry; if you intend to + * see retry entries, you should use the xas_for_each() iterator instead. + * The xas_for_each() iterator will expand into more inline code than + * xa_for_each_start(). + * + * Context: Any context. Takes and releases the RCU lock. + */ +#define xa_for_each_start(xa, index, entry, start) \ + xa_for_each_range(xa, index, entry, start, ULONG_MAX) + +/** + * xa_for_each() - Iterate over present entries in an XArray. + * @xa: XArray. + * @index: Index of @entry. + * @entry: Entry retrieved from array. + * + * During the iteration, @entry will have the value of the entry stored + * in @xa at @index. You may modify @index during the iteration if you want + * to skip or reprocess indices. It is safe to modify the array during the + * iteration. At the end of the iteration, @entry will be set to NULL and + * @index will have a value less than or equal to max. + * + * xa_for_each() is O(n.log(n)) while xas_for_each() is O(n). You have + * to handle your own locking with xas_for_each(), and if you have to unlock + * after each iteration, it will also end up being O(n.log(n)). xa_for_each() + * will spin if it hits a retry entry; if you intend to see retry entries, + * you should use the xas_for_each() iterator instead. The xas_for_each() + * iterator will expand into more inline code than xa_for_each(). + * + * Context: Any context. Takes and releases the RCU lock. + */ +#define xa_for_each(xa, index, entry) \ + xa_for_each_start(xa, index, entry, 0) + +/** + * xa_for_each_marked() - Iterate over marked entries in an XArray. + * @xa: XArray. + * @index: Index of @entry. + * @entry: Entry retrieved from array. + * @filter: Selection criterion. + * + * During the iteration, @entry will have the value of the entry stored + * in @xa at @index. The iteration will skip all entries in the array + * which do not match @filter. You may modify @index during the iteration + * if you want to skip or reprocess indices. It is safe to modify the array + * during the iteration. At the end of the iteration, @entry will be set to + * NULL and @index will have a value less than or equal to max. + * + * xa_for_each_marked() is O(n.log(n)) while xas_for_each_marked() is O(n). + * You have to handle your own locking with xas_for_each(), and if you have + * to unlock after each iteration, it will also end up being O(n.log(n)). + * xa_for_each_marked() will spin if it hits a retry entry; if you intend to + * see retry entries, you should use the xas_for_each_marked() iterator + * instead. The xas_for_each_marked() iterator will expand into more inline + * code than xa_for_each_marked(). + * + * Context: Any context. Takes and releases the RCU lock. + */ +#define xa_for_each_marked(xa, index, entry, filter) \ + for (index = 0, entry = xa_find(xa, &index, ULONG_MAX, filter); \ + entry; entry = xa_find_after(xa, &index, ULONG_MAX, filter)) + +#define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) +#define xa_lock(xa) spin_lock(&(xa)->xa_lock) +#define xa_unlock(xa) spin_unlock(&(xa)->xa_lock) +#define xa_lock_bh(xa) spin_lock_bh(&(xa)->xa_lock) +#define xa_unlock_bh(xa) spin_unlock_bh(&(xa)->xa_lock) +#define xa_lock_irq(xa) spin_lock_irq(&(xa)->xa_lock) +#define xa_unlock_irq(xa) spin_unlock_irq(&(xa)->xa_lock) +#define xa_lock_irqsave(xa, flags) \ + spin_lock_irqsave(&(xa)->xa_lock, flags) +#define xa_unlock_irqrestore(xa, flags) \ + spin_unlock_irqrestore(&(xa)->xa_lock, flags) +#define xa_lock_nested(xa, subclass) \ + spin_lock_nested(&(xa)->xa_lock, subclass) +#define xa_lock_bh_nested(xa, subclass) \ + spin_lock_bh_nested(&(xa)->xa_lock, subclass) +#define xa_lock_irq_nested(xa, subclass) \ + spin_lock_irq_nested(&(xa)->xa_lock, subclass) +#define xa_lock_irqsave_nested(xa, flags, subclass) \ + spin_lock_irqsave_nested(&(xa)->xa_lock, flags, subclass) + +/* + * Versions of the normal API which require the caller to hold the + * xa_lock. If the GFP flags allow it, they will drop the lock to + * allocate memory, then reacquire it afterwards. These functions + * may also re-enable interrupts if the XArray flags indicate the + * locking should be interrupt safe. + */ +void *__xa_erase(struct xarray *, unsigned long index); +void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); +void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, + void *entry, gfp_t); +int __must_check __xa_insert(struct xarray *, unsigned long index, + void *entry, gfp_t); +int __must_check __xa_alloc(struct xarray *, u32 *id, void *entry, + struct xa_limit, gfp_t); +int __must_check __xa_alloc_cyclic(struct xarray *, u32 *id, void *entry, + struct xa_limit, u32 *next, gfp_t); +void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); +void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); + +/** + * xa_store_bh() - Store this entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * This function is like calling xa_store() except it disables softirqs + * while holding the array lock. + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. + * Return: The old entry at this index or xa_err() if an error happened. + */ +static inline void *xa_store_bh(struct xarray *xa, unsigned long index, + void *entry, gfp_t gfp) +{ + void *curr; + + __might_alloc(gfp); + xa_lock_bh(xa); + curr = __xa_store(xa, index, entry, gfp); + xa_unlock_bh(xa); + + return curr; +} + +/** + * xa_store_irq() - Store this entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * This function is like calling xa_store() except it disables interrupts + * while holding the array lock. + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. + * Return: The old entry at this index or xa_err() if an error happened. + */ +static inline void *xa_store_irq(struct xarray *xa, unsigned long index, + void *entry, gfp_t gfp) +{ + void *curr; + + __might_alloc(gfp); + xa_lock_irq(xa); + curr = __xa_store(xa, index, entry, gfp); + xa_unlock_irq(xa); + + return curr; +} + +/** + * xa_erase_bh() - Erase this entry from the XArray. + * @xa: XArray. + * @index: Index of entry. + * + * After this function returns, loading from @index will return %NULL. + * If the index is part of a multi-index entry, all indices will be erased + * and none of the entries will be part of a multi-index entry. + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. + * Return: The entry which used to be at this index. + */ +static inline void *xa_erase_bh(struct xarray *xa, unsigned long index) +{ + void *entry; + + xa_lock_bh(xa); + entry = __xa_erase(xa, index); + xa_unlock_bh(xa); + + return entry; +} + +/** + * xa_erase_irq() - Erase this entry from the XArray. + * @xa: XArray. + * @index: Index of entry. + * + * After this function returns, loading from @index will return %NULL. + * If the index is part of a multi-index entry, all indices will be erased + * and none of the entries will be part of a multi-index entry. + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. + * Return: The entry which used to be at this index. + */ +static inline void *xa_erase_irq(struct xarray *xa, unsigned long index) +{ + void *entry; + + xa_lock_irq(xa); + entry = __xa_erase(xa, index); + xa_unlock_irq(xa); + + return entry; +} + +/** + * xa_cmpxchg() - Conditionally replace an entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @old: Old value to test against. + * @entry: New value to place in array. + * @gfp: Memory allocation flags. + * + * If the entry at @index is the same as @old, replace it with @entry. + * If the return value is equal to @old, then the exchange was successful. + * + * Context: Any context. Takes and releases the xa_lock. May sleep + * if the @gfp flags permit. + * Return: The old value at this index or xa_err() if an error happened. + */ +static inline void *xa_cmpxchg(struct xarray *xa, unsigned long index, + void *old, void *entry, gfp_t gfp) +{ + void *curr; + + __might_alloc(gfp); + xa_lock(xa); + curr = __xa_cmpxchg(xa, index, old, entry, gfp); + xa_unlock(xa); + + return curr; +} + +/** + * xa_cmpxchg_bh() - Conditionally replace an entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @old: Old value to test against. + * @entry: New value to place in array. + * @gfp: Memory allocation flags. + * + * This function is like calling xa_cmpxchg() except it disables softirqs + * while holding the array lock. + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. May sleep if the @gfp flags permit. + * Return: The old value at this index or xa_err() if an error happened. + */ +static inline void *xa_cmpxchg_bh(struct xarray *xa, unsigned long index, + void *old, void *entry, gfp_t gfp) +{ + void *curr; + + __might_alloc(gfp); + xa_lock_bh(xa); + curr = __xa_cmpxchg(xa, index, old, entry, gfp); + xa_unlock_bh(xa); + + return curr; +} + +/** + * xa_cmpxchg_irq() - Conditionally replace an entry in the XArray. + * @xa: XArray. + * @index: Index into array. + * @old: Old value to test against. + * @entry: New value to place in array. + * @gfp: Memory allocation flags. + * + * This function is like calling xa_cmpxchg() except it disables interrupts + * while holding the array lock. + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. May sleep if the @gfp flags permit. + * Return: The old value at this index or xa_err() if an error happened. + */ +static inline void *xa_cmpxchg_irq(struct xarray *xa, unsigned long index, + void *old, void *entry, gfp_t gfp) +{ + void *curr; + + __might_alloc(gfp); + xa_lock_irq(xa); + curr = __xa_cmpxchg(xa, index, old, entry, gfp); + xa_unlock_irq(xa); + + return curr; +} + +/** + * xa_insert() - Store this entry in the XArray unless another entry is + * already present. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Inserting a NULL entry will store a reserved entry (like xa_reserve()) + * if no entry is present. Inserting will fail if a reserved entry is + * present, even though loading from this index will return NULL. + * + * Context: Any context. Takes and releases the xa_lock. May sleep if + * the @gfp flags permit. + * Return: 0 if the store succeeded. -EBUSY if another entry was present. + * -ENOMEM if memory could not be allocated. + */ +static inline int __must_check xa_insert(struct xarray *xa, + unsigned long index, void *entry, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock(xa); + err = __xa_insert(xa, index, entry, gfp); + xa_unlock(xa); + + return err; +} + +/** + * xa_insert_bh() - Store this entry in the XArray unless another entry is + * already present. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Inserting a NULL entry will store a reserved entry (like xa_reserve()) + * if no entry is present. Inserting will fail if a reserved entry is + * present, even though loading from this index will return NULL. + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. May sleep if the @gfp flags permit. + * Return: 0 if the store succeeded. -EBUSY if another entry was present. + * -ENOMEM if memory could not be allocated. + */ +static inline int __must_check xa_insert_bh(struct xarray *xa, + unsigned long index, void *entry, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock_bh(xa); + err = __xa_insert(xa, index, entry, gfp); + xa_unlock_bh(xa); + + return err; +} + +/** + * xa_insert_irq() - Store this entry in the XArray unless another entry is + * already present. + * @xa: XArray. + * @index: Index into array. + * @entry: New entry. + * @gfp: Memory allocation flags. + * + * Inserting a NULL entry will store a reserved entry (like xa_reserve()) + * if no entry is present. Inserting will fail if a reserved entry is + * present, even though loading from this index will return NULL. + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. May sleep if the @gfp flags permit. + * Return: 0 if the store succeeded. -EBUSY if another entry was present. + * -ENOMEM if memory could not be allocated. + */ +static inline int __must_check xa_insert_irq(struct xarray *xa, + unsigned long index, void *entry, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock_irq(xa); + err = __xa_insert(xa, index, entry, gfp); + xa_unlock_irq(xa); + + return err; +} + +/** + * xa_alloc() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Any context. Takes and releases the xa_lock. May sleep if + * the @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory could not be allocated or + * -EBUSY if there are no free entries in @limit. + */ +static inline __must_check int xa_alloc(struct xarray *xa, u32 *id, + void *entry, struct xa_limit limit, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock(xa); + err = __xa_alloc(xa, id, entry, limit, gfp); + xa_unlock(xa); + + return err; +} + +/** + * xa_alloc_bh() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. May sleep if the @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory could not be allocated or + * -EBUSY if there are no free entries in @limit. + */ +static inline int __must_check xa_alloc_bh(struct xarray *xa, u32 *id, + void *entry, struct xa_limit limit, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock_bh(xa); + err = __xa_alloc(xa, id, entry, limit, gfp); + xa_unlock_bh(xa); + + return err; +} + +/** + * xa_alloc_irq() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. May sleep if the @gfp flags permit. + * Return: 0 on success, -ENOMEM if memory could not be allocated or + * -EBUSY if there are no free entries in @limit. + */ +static inline int __must_check xa_alloc_irq(struct xarray *xa, u32 *id, + void *entry, struct xa_limit limit, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock_irq(xa); + err = __xa_alloc(xa, id, entry, limit, gfp); + xa_unlock_irq(xa); + + return err; +} + +/** + * xa_alloc_cyclic() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of allocated ID. + * @next: Pointer to next ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * The search for an empty entry will start at @next and will wrap + * around if necessary. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Any context. Takes and releases the xa_lock. May sleep if + * the @gfp flags permit. + * Return: 0 if the allocation succeeded without wrapping. 1 if the + * allocation succeeded after wrapping, -ENOMEM if memory could not be + * allocated or -EBUSY if there are no free entries in @limit. + */ +static inline int xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry, + struct xa_limit limit, u32 *next, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock(xa); + err = __xa_alloc_cyclic(xa, id, entry, limit, next, gfp); + xa_unlock(xa); + + return err; +} + +/** + * xa_alloc_cyclic_bh() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of allocated ID. + * @next: Pointer to next ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * The search for an empty entry will start at @next and will wrap + * around if necessary. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. May sleep if the @gfp flags permit. + * Return: 0 if the allocation succeeded without wrapping. 1 if the + * allocation succeeded after wrapping, -ENOMEM if memory could not be + * allocated or -EBUSY if there are no free entries in @limit. + */ +static inline int xa_alloc_cyclic_bh(struct xarray *xa, u32 *id, void *entry, + struct xa_limit limit, u32 *next, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock_bh(xa); + err = __xa_alloc_cyclic(xa, id, entry, limit, next, gfp); + xa_unlock_bh(xa); + + return err; +} + +/** + * xa_alloc_cyclic_irq() - Find somewhere to store this entry in the XArray. + * @xa: XArray. + * @id: Pointer to ID. + * @entry: New entry. + * @limit: Range of allocated ID. + * @next: Pointer to next ID to allocate. + * @gfp: Memory allocation flags. + * + * Finds an empty entry in @xa between @limit.min and @limit.max, + * stores the index into the @id pointer, then stores the entry at + * that index. A concurrent lookup will not see an uninitialised @id. + * The search for an empty entry will start at @next and will wrap + * around if necessary. + * + * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set + * in xa_init_flags(). + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. May sleep if the @gfp flags permit. + * Return: 0 if the allocation succeeded without wrapping. 1 if the + * allocation succeeded after wrapping, -ENOMEM if memory could not be + * allocated or -EBUSY if there are no free entries in @limit. + */ +static inline int xa_alloc_cyclic_irq(struct xarray *xa, u32 *id, void *entry, + struct xa_limit limit, u32 *next, gfp_t gfp) +{ + int err; + + __might_alloc(gfp); + xa_lock_irq(xa); + err = __xa_alloc_cyclic(xa, id, entry, limit, next, gfp); + xa_unlock_irq(xa); + + return err; +} + +/** + * xa_reserve() - Reserve this index in the XArray. + * @xa: XArray. + * @index: Index into array. + * @gfp: Memory allocation flags. + * + * Ensures there is somewhere to store an entry at @index in the array. + * If there is already something stored at @index, this function does + * nothing. If there was nothing there, the entry is marked as reserved. + * Loading from a reserved entry returns a %NULL pointer. + * + * If you do not use the entry that you have reserved, call xa_release() + * or xa_erase() to free any unnecessary memory. + * + * Context: Any context. Takes and releases the xa_lock. + * May sleep if the @gfp flags permit. + * Return: 0 if the reservation succeeded or -ENOMEM if it failed. + */ +static inline __must_check +int xa_reserve(struct xarray *xa, unsigned long index, gfp_t gfp) +{ + return xa_err(xa_cmpxchg(xa, index, NULL, XA_ZERO_ENTRY, gfp)); +} + +/** + * xa_reserve_bh() - Reserve this index in the XArray. + * @xa: XArray. + * @index: Index into array. + * @gfp: Memory allocation flags. + * + * A softirq-disabling version of xa_reserve(). + * + * Context: Any context. Takes and releases the xa_lock while + * disabling softirqs. + * Return: 0 if the reservation succeeded or -ENOMEM if it failed. + */ +static inline __must_check +int xa_reserve_bh(struct xarray *xa, unsigned long index, gfp_t gfp) +{ + return xa_err(xa_cmpxchg_bh(xa, index, NULL, XA_ZERO_ENTRY, gfp)); +} + +/** + * xa_reserve_irq() - Reserve this index in the XArray. + * @xa: XArray. + * @index: Index into array. + * @gfp: Memory allocation flags. + * + * An interrupt-disabling version of xa_reserve(). + * + * Context: Process context. Takes and releases the xa_lock while + * disabling interrupts. + * Return: 0 if the reservation succeeded or -ENOMEM if it failed. + */ +static inline __must_check +int xa_reserve_irq(struct xarray *xa, unsigned long index, gfp_t gfp) +{ + return xa_err(xa_cmpxchg_irq(xa, index, NULL, XA_ZERO_ENTRY, gfp)); +} + +/** + * xa_release() - Release a reserved entry. + * @xa: XArray. + * @index: Index of entry. + * + * After calling xa_reserve(), you can call this function to release the + * reservation. If the entry at @index has been stored to, this function + * will do nothing. + */ +static inline void xa_release(struct xarray *xa, unsigned long index) +{ + xa_cmpxchg(xa, index, XA_ZERO_ENTRY, NULL, 0); +} + +/* Everything below here is the Advanced API. Proceed with caution. */ + +/* + * The xarray is constructed out of a set of 'chunks' of pointers. Choosing + * the best chunk size requires some tradeoffs. A power of two recommends + * itself so that we can walk the tree based purely on shifts and masks. + * Generally, the larger the better; as the number of slots per level of the + * tree increases, the less tall the tree needs to be. But that needs to be + * balanced against the memory consumption of each node. On a 64-bit system, + * xa_node is currently 576 bytes, and we get 7 of them per 4kB page. If we + * doubled the number of slots per node, we'd get only 3 nodes per 4kB page. + */ +#ifndef XA_CHUNK_SHIFT +#define XA_CHUNK_SHIFT (IS_ENABLED(CONFIG_BASE_SMALL) ? 4 : 6) +#endif +#define XA_CHUNK_SIZE (1UL << XA_CHUNK_SHIFT) +#define XA_CHUNK_MASK (XA_CHUNK_SIZE - 1) +#define XA_MAX_MARKS 3 +#define XA_MARK_LONGS BITS_TO_LONGS(XA_CHUNK_SIZE) + +/* + * @count is the count of every non-NULL element in the ->slots array + * whether that is a value entry, a retry entry, a user pointer, + * a sibling entry or a pointer to the next level of the tree. + * @nr_values is the count of every element in ->slots which is + * either a value entry or a sibling of a value entry. + */ +struct xa_node { + unsigned char shift; /* Bits remaining in each slot */ + unsigned char offset; /* Slot offset in parent */ + unsigned char count; /* Total entry count */ + unsigned char nr_values; /* Value entry count */ + struct xa_node __rcu *parent; /* NULL at top of tree */ + struct xarray *array; /* The array we belong to */ + union { + struct list_head private_list; /* For tree user */ + struct rcu_head rcu_head; /* Used when freeing node */ + }; + void __rcu *slots[XA_CHUNK_SIZE]; + union { + unsigned long tags[XA_MAX_MARKS][XA_MARK_LONGS]; + unsigned long marks[XA_MAX_MARKS][XA_MARK_LONGS]; + }; +}; + +void xa_dump(const struct xarray *); +void xa_dump_node(const struct xa_node *); + +#ifdef XA_DEBUG +#define XA_BUG_ON(xa, x) do { \ + if (x) { \ + xa_dump(xa); \ + BUG(); \ + } \ + } while (0) +#define XA_NODE_BUG_ON(node, x) do { \ + if (x) { \ + if (node) xa_dump_node(node); \ + BUG(); \ + } \ + } while (0) +#else +#define XA_BUG_ON(xa, x) do { } while (0) +#define XA_NODE_BUG_ON(node, x) do { } while (0) +#endif + +/* Private */ +static inline void *xa_head(const struct xarray *xa) +{ + return rcu_dereference_check(xa->xa_head, + lockdep_is_held(&xa->xa_lock)); +} + +/* Private */ +static inline void *xa_head_locked(const struct xarray *xa) +{ + return rcu_dereference_protected(xa->xa_head, + lockdep_is_held(&xa->xa_lock)); +} + +/* Private */ +static inline void *xa_entry(const struct xarray *xa, + const struct xa_node *node, unsigned int offset) +{ + XA_NODE_BUG_ON(node, offset >= XA_CHUNK_SIZE); + return rcu_dereference_check(node->slots[offset], + lockdep_is_held(&xa->xa_lock)); +} + +/* Private */ +static inline void *xa_entry_locked(const struct xarray *xa, + const struct xa_node *node, unsigned int offset) +{ + XA_NODE_BUG_ON(node, offset >= XA_CHUNK_SIZE); + return rcu_dereference_protected(node->slots[offset], + lockdep_is_held(&xa->xa_lock)); +} + +/* Private */ +static inline struct xa_node *xa_parent(const struct xarray *xa, + const struct xa_node *node) +{ + return rcu_dereference_check(node->parent, + lockdep_is_held(&xa->xa_lock)); +} + +/* Private */ +static inline struct xa_node *xa_parent_locked(const struct xarray *xa, + const struct xa_node *node) +{ + return rcu_dereference_protected(node->parent, + lockdep_is_held(&xa->xa_lock)); +} + +/* Private */ +static inline void *xa_mk_node(const struct xa_node *node) +{ + return (void *)((unsigned long)node | 2); +} + +/* Private */ +static inline struct xa_node *xa_to_node(const void *entry) +{ + return (struct xa_node *)((unsigned long)entry - 2); +} + +/* Private */ +static inline bool xa_is_node(const void *entry) +{ + return xa_is_internal(entry) && (unsigned long)entry > 4096; +} + +/* Private */ +static inline void *xa_mk_sibling(unsigned int offset) +{ + return xa_mk_internal(offset); +} + +/* Private */ +static inline unsigned long xa_to_sibling(const void *entry) +{ + return xa_to_internal(entry); +} + +/** + * xa_is_sibling() - Is the entry a sibling entry? + * @entry: Entry retrieved from the XArray + * + * Return: %true if the entry is a sibling entry. + */ +static inline bool xa_is_sibling(const void *entry) +{ + return IS_ENABLED(CONFIG_XARRAY_MULTI) && xa_is_internal(entry) && + (entry < xa_mk_sibling(XA_CHUNK_SIZE - 1)); +} + +#define XA_RETRY_ENTRY xa_mk_internal(256) + +/** + * xa_is_retry() - Is the entry a retry entry? + * @entry: Entry retrieved from the XArray + * + * Return: %true if the entry is a retry entry. + */ +static inline bool xa_is_retry(const void *entry) +{ + return unlikely(entry == XA_RETRY_ENTRY); +} + +/** + * xa_is_advanced() - Is the entry only permitted for the advanced API? + * @entry: Entry to be stored in the XArray. + * + * Return: %true if the entry cannot be stored by the normal API. + */ +static inline bool xa_is_advanced(const void *entry) +{ + return xa_is_internal(entry) && (entry <= XA_RETRY_ENTRY); +} + +/** + * typedef xa_update_node_t - A callback function from the XArray. + * @node: The node which is being processed + * + * This function is called every time the XArray updates the count of + * present and value entries in a node. It allows advanced users to + * maintain the private_list in the node. + * + * Context: The xa_lock is held and interrupts may be disabled. + * Implementations should not drop the xa_lock, nor re-enable + * interrupts. + */ +typedef void (*xa_update_node_t)(struct xa_node *node); + +void xa_delete_node(struct xa_node *, xa_update_node_t); + +/* + * The xa_state is opaque to its users. It contains various different pieces + * of state involved in the current operation on the XArray. It should be + * declared on the stack and passed between the various internal routines. + * The various elements in it should not be accessed directly, but only + * through the provided accessor functions. The below documentation is for + * the benefit of those working on the code, not for users of the XArray. + * + * @xa_node usually points to the xa_node containing the slot we're operating + * on (and @xa_offset is the offset in the slots array). If there is a + * single entry in the array at index 0, there are no allocated xa_nodes to + * point to, and so we store %NULL in @xa_node. @xa_node is set to + * the value %XAS_RESTART if the xa_state is not walked to the correct + * position in the tree of nodes for this operation. If an error occurs + * during an operation, it is set to an %XAS_ERROR value. If we run off the + * end of the allocated nodes, it is set to %XAS_BOUNDS. + */ +struct xa_state { + struct xarray *xa; + unsigned long xa_index; + unsigned char xa_shift; + unsigned char xa_sibs; + unsigned char xa_offset; + unsigned char xa_pad; /* Helps gcc generate better code */ + struct xa_node *xa_node; + struct xa_node *xa_alloc; + xa_update_node_t xa_update; + struct list_lru *xa_lru; +}; + +/* + * We encode errnos in the xas->xa_node. If an error has happened, we need to + * drop the lock to fix it, and once we've done so the xa_state is invalid. + */ +#define XA_ERROR(errno) ((struct xa_node *)(((unsigned long)errno << 2) | 2UL)) +#define XAS_BOUNDS ((struct xa_node *)1UL) +#define XAS_RESTART ((struct xa_node *)3UL) + +#define __XA_STATE(array, index, shift, sibs) { \ + .xa = array, \ + .xa_index = index, \ + .xa_shift = shift, \ + .xa_sibs = sibs, \ + .xa_offset = 0, \ + .xa_pad = 0, \ + .xa_node = XAS_RESTART, \ + .xa_alloc = NULL, \ + .xa_update = NULL, \ + .xa_lru = NULL, \ +} + +/** + * XA_STATE() - Declare an XArray operation state. + * @name: Name of this operation state (usually xas). + * @array: Array to operate on. + * @index: Initial index of interest. + * + * Declare and initialise an xa_state on the stack. + */ +#define XA_STATE(name, array, index) \ + struct xa_state name = __XA_STATE(array, index, 0, 0) + +/** + * XA_STATE_ORDER() - Declare an XArray operation state. + * @name: Name of this operation state (usually xas). + * @array: Array to operate on. + * @index: Initial index of interest. + * @order: Order of entry. + * + * Declare and initialise an xa_state on the stack. This variant of + * XA_STATE() allows you to specify the 'order' of the element you + * want to operate on.` + */ +#define XA_STATE_ORDER(name, array, index, order) \ + struct xa_state name = __XA_STATE(array, \ + (index >> order) << order, \ + order - (order % XA_CHUNK_SHIFT), \ + (1U << (order % XA_CHUNK_SHIFT)) - 1) + +#define xas_marked(xas, mark) xa_marked((xas)->xa, (mark)) +#define xas_trylock(xas) xa_trylock((xas)->xa) +#define xas_lock(xas) xa_lock((xas)->xa) +#define xas_unlock(xas) xa_unlock((xas)->xa) +#define xas_lock_bh(xas) xa_lock_bh((xas)->xa) +#define xas_unlock_bh(xas) xa_unlock_bh((xas)->xa) +#define xas_lock_irq(xas) xa_lock_irq((xas)->xa) +#define xas_unlock_irq(xas) xa_unlock_irq((xas)->xa) +#define xas_lock_irqsave(xas, flags) \ + xa_lock_irqsave((xas)->xa, flags) +#define xas_unlock_irqrestore(xas, flags) \ + xa_unlock_irqrestore((xas)->xa, flags) + +/** + * xas_error() - Return an errno stored in the xa_state. + * @xas: XArray operation state. + * + * Return: 0 if no error has been noted. A negative errno if one has. + */ +static inline int xas_error(const struct xa_state *xas) +{ + return xa_err(xas->xa_node); +} + +/** + * xas_set_err() - Note an error in the xa_state. + * @xas: XArray operation state. + * @err: Negative error number. + * + * Only call this function with a negative @err; zero or positive errors + * will probably not behave the way you think they should. If you want + * to clear the error from an xa_state, use xas_reset(). + */ +static inline void xas_set_err(struct xa_state *xas, long err) +{ + xas->xa_node = XA_ERROR(err); +} + +/** + * xas_invalid() - Is the xas in a retry or error state? + * @xas: XArray operation state. + * + * Return: %true if the xas cannot be used for operations. + */ +static inline bool xas_invalid(const struct xa_state *xas) +{ + return (unsigned long)xas->xa_node & 3; +} + +/** + * xas_valid() - Is the xas a valid cursor into the array? + * @xas: XArray operation state. + * + * Return: %true if the xas can be used for operations. + */ +static inline bool xas_valid(const struct xa_state *xas) +{ + return !xas_invalid(xas); +} + +/** + * xas_is_node() - Does the xas point to a node? + * @xas: XArray operation state. + * + * Return: %true if the xas currently references a node. + */ +static inline bool xas_is_node(const struct xa_state *xas) +{ + return xas_valid(xas) && xas->xa_node; +} + +/* True if the pointer is something other than a node */ +static inline bool xas_not_node(struct xa_node *node) +{ + return ((unsigned long)node & 3) || !node; +} + +/* True if the node represents RESTART or an error */ +static inline bool xas_frozen(struct xa_node *node) +{ + return (unsigned long)node & 2; +} + +/* True if the node represents head-of-tree, RESTART or BOUNDS */ +static inline bool xas_top(struct xa_node *node) +{ + return node <= XAS_RESTART; +} + +/** + * xas_reset() - Reset an XArray operation state. + * @xas: XArray operation state. + * + * Resets the error or walk state of the @xas so future walks of the + * array will start from the root. Use this if you have dropped the + * xarray lock and want to reuse the xa_state. + * + * Context: Any context. + */ +static inline void xas_reset(struct xa_state *xas) +{ + xas->xa_node = XAS_RESTART; +} + +/** + * xas_retry() - Retry the operation if appropriate. + * @xas: XArray operation state. + * @entry: Entry from xarray. + * + * The advanced functions may sometimes return an internal entry, such as + * a retry entry or a zero entry. This function sets up the @xas to restart + * the walk from the head of the array if needed. + * + * Context: Any context. + * Return: true if the operation needs to be retried. + */ +static inline bool xas_retry(struct xa_state *xas, const void *entry) +{ + if (xa_is_zero(entry)) + return true; + if (!xa_is_retry(entry)) + return false; + xas_reset(xas); + return true; +} + +void *xas_load(struct xa_state *); +void *xas_store(struct xa_state *, void *entry); +void *xas_find(struct xa_state *, unsigned long max); +void *xas_find_conflict(struct xa_state *); + +bool xas_get_mark(const struct xa_state *, xa_mark_t); +void xas_set_mark(const struct xa_state *, xa_mark_t); +void xas_clear_mark(const struct xa_state *, xa_mark_t); +void *xas_find_marked(struct xa_state *, unsigned long max, xa_mark_t); +void xas_init_marks(const struct xa_state *); + +bool xas_nomem(struct xa_state *, gfp_t); +void xas_destroy(struct xa_state *); +void xas_pause(struct xa_state *); + +void xas_create_range(struct xa_state *); + +#ifdef CONFIG_XARRAY_MULTI +int xa_get_order(struct xarray *, unsigned long index); +int xas_get_order(struct xa_state *xas); +void xas_split(struct xa_state *, void *entry, unsigned int order); +void xas_split_alloc(struct xa_state *, void *entry, unsigned int order, gfp_t); +#else +static inline int xa_get_order(struct xarray *xa, unsigned long index) +{ + return 0; +} + +static inline int xas_get_order(struct xa_state *xas) +{ + return 0; +} + +static inline void xas_split(struct xa_state *xas, void *entry, + unsigned int order) +{ + xas_store(xas, entry); +} + +static inline void xas_split_alloc(struct xa_state *xas, void *entry, + unsigned int order, gfp_t gfp) +{ +} +#endif + +/** + * xas_reload() - Refetch an entry from the xarray. + * @xas: XArray operation state. + * + * Use this function to check that a previously loaded entry still has + * the same value. This is useful for the lockless pagecache lookup where + * we walk the array with only the RCU lock to protect us, lock the page, + * then check that the page hasn't moved since we looked it up. + * + * The caller guarantees that @xas is still valid. If it may be in an + * error or restart state, call xas_load() instead. + * + * Return: The entry at this location in the xarray. + */ +static inline void *xas_reload(struct xa_state *xas) +{ + struct xa_node *node = xas->xa_node; + void *entry; + char offset; + + if (!node) + return xa_head(xas->xa); + if (IS_ENABLED(CONFIG_XARRAY_MULTI)) { + offset = (xas->xa_index >> node->shift) & XA_CHUNK_MASK; + entry = xa_entry(xas->xa, node, offset); + if (!xa_is_sibling(entry)) + return entry; + offset = xa_to_sibling(entry); + } else { + offset = xas->xa_offset; + } + return xa_entry(xas->xa, node, offset); +} + +/** + * xas_set() - Set up XArray operation state for a different index. + * @xas: XArray operation state. + * @index: New index into the XArray. + * + * Move the operation state to refer to a different index. This will + * have the effect of starting a walk from the top; see xas_next() + * to move to an adjacent index. + */ +static inline void xas_set(struct xa_state *xas, unsigned long index) +{ + xas->xa_index = index; + xas->xa_node = XAS_RESTART; +} + +/** + * xas_advance() - Skip over sibling entries. + * @xas: XArray operation state. + * @index: Index of last sibling entry. + * + * Move the operation state to refer to the last sibling entry. + * This is useful for loops that normally want to see sibling + * entries but sometimes want to skip them. Use xas_set() if you + * want to move to an index which is not part of this entry. + */ +static inline void xas_advance(struct xa_state *xas, unsigned long index) +{ + unsigned char shift = xas_is_node(xas) ? xas->xa_node->shift : 0; + + xas->xa_index = index; + xas->xa_offset = (index >> shift) & XA_CHUNK_MASK; +} + +/** + * xas_set_order() - Set up XArray operation state for a multislot entry. + * @xas: XArray operation state. + * @index: Target of the operation. + * @order: Entry occupies 2^@order indices. + */ +static inline void xas_set_order(struct xa_state *xas, unsigned long index, + unsigned int order) +{ +#ifdef CONFIG_XARRAY_MULTI + xas->xa_index = order < BITS_PER_LONG ? (index >> order) << order : 0; + xas->xa_shift = order - (order % XA_CHUNK_SHIFT); + xas->xa_sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; + xas->xa_node = XAS_RESTART; +#else + BUG_ON(order > 0); + xas_set(xas, index); +#endif +} + +/** + * xas_set_update() - Set up XArray operation state for a callback. + * @xas: XArray operation state. + * @update: Function to call when updating a node. + * + * The XArray can notify a caller after it has updated an xa_node. + * This is advanced functionality and is only needed by the page + * cache and swap cache. + */ +static inline void xas_set_update(struct xa_state *xas, xa_update_node_t update) +{ + xas->xa_update = update; +} + +static inline void xas_set_lru(struct xa_state *xas, struct list_lru *lru) +{ + xas->xa_lru = lru; +} + +/** + * xas_next_entry() - Advance iterator to next present entry. + * @xas: XArray operation state. + * @max: Highest index to return. + * + * xas_next_entry() is an inline function to optimise xarray traversal for + * speed. It is equivalent to calling xas_find(), and will call xas_find() + * for all the hard cases. + * + * Return: The next present entry after the one currently referred to by @xas. + */ +static inline void *xas_next_entry(struct xa_state *xas, unsigned long max) +{ + struct xa_node *node = xas->xa_node; + void *entry; + + if (unlikely(xas_not_node(node) || node->shift || + xas->xa_offset != (xas->xa_index & XA_CHUNK_MASK))) + return xas_find(xas, max); + + do { + if (unlikely(xas->xa_index >= max)) + return xas_find(xas, max); + if (unlikely(xas->xa_offset == XA_CHUNK_MASK)) + return xas_find(xas, max); + entry = xa_entry(xas->xa, node, xas->xa_offset + 1); + if (unlikely(xa_is_internal(entry))) + return xas_find(xas, max); + xas->xa_offset++; + xas->xa_index++; + } while (!entry); + + return entry; +} + +/* Private */ +static inline unsigned int xas_find_chunk(struct xa_state *xas, bool advance, + xa_mark_t mark) +{ + unsigned long *addr = xas->xa_node->marks[(__force unsigned)mark]; + unsigned int offset = xas->xa_offset; + + if (advance) + offset++; + if (XA_CHUNK_SIZE == BITS_PER_LONG) { + if (offset < XA_CHUNK_SIZE) { + unsigned long data = *addr & (~0UL << offset); + if (data) + return __ffs(data); + } + return XA_CHUNK_SIZE; + } + + return find_next_bit(addr, XA_CHUNK_SIZE, offset); +} + +/** + * xas_next_marked() - Advance iterator to next marked entry. + * @xas: XArray operation state. + * @max: Highest index to return. + * @mark: Mark to search for. + * + * xas_next_marked() is an inline function to optimise xarray traversal for + * speed. It is equivalent to calling xas_find_marked(), and will call + * xas_find_marked() for all the hard cases. + * + * Return: The next marked entry after the one currently referred to by @xas. + */ +static inline void *xas_next_marked(struct xa_state *xas, unsigned long max, + xa_mark_t mark) +{ + struct xa_node *node = xas->xa_node; + void *entry; + unsigned int offset; + + if (unlikely(xas_not_node(node) || node->shift)) + return xas_find_marked(xas, max, mark); + offset = xas_find_chunk(xas, true, mark); + xas->xa_offset = offset; + xas->xa_index = (xas->xa_index & ~XA_CHUNK_MASK) + offset; + if (xas->xa_index > max) + return NULL; + if (offset == XA_CHUNK_SIZE) + return xas_find_marked(xas, max, mark); + entry = xa_entry(xas->xa, node, offset); + if (!entry) + return xas_find_marked(xas, max, mark); + return entry; +} + +/* + * If iterating while holding a lock, drop the lock and reschedule + * every %XA_CHECK_SCHED loops. + */ +enum { + XA_CHECK_SCHED = 4096, +}; + +/** + * xas_for_each() - Iterate over a range of an XArray. + * @xas: XArray operation state. + * @entry: Entry retrieved from the array. + * @max: Maximum index to retrieve from array. + * + * The loop body will be executed for each entry present in the xarray + * between the current xas position and @max. @entry will be set to + * the entry retrieved from the xarray. It is safe to delete entries + * from the array in the loop body. You should hold either the RCU lock + * or the xa_lock while iterating. If you need to drop the lock, call + * xas_pause() first. + */ +#define xas_for_each(xas, entry, max) \ + for (entry = xas_find(xas, max); entry; \ + entry = xas_next_entry(xas, max)) + +/** + * xas_for_each_marked() - Iterate over a range of an XArray. + * @xas: XArray operation state. + * @entry: Entry retrieved from the array. + * @max: Maximum index to retrieve from array. + * @mark: Mark to search for. + * + * The loop body will be executed for each marked entry in the xarray + * between the current xas position and @max. @entry will be set to + * the entry retrieved from the xarray. It is safe to delete entries + * from the array in the loop body. You should hold either the RCU lock + * or the xa_lock while iterating. If you need to drop the lock, call + * xas_pause() first. + */ +#define xas_for_each_marked(xas, entry, max, mark) \ + for (entry = xas_find_marked(xas, max, mark); entry; \ + entry = xas_next_marked(xas, max, mark)) + +/** + * xas_for_each_conflict() - Iterate over a range of an XArray. + * @xas: XArray operation state. + * @entry: Entry retrieved from the array. + * + * The loop body will be executed for each entry in the XArray that + * lies within the range specified by @xas. If the loop terminates + * normally, @entry will be %NULL. The user may break out of the loop, + * which will leave @entry set to the conflicting entry. The caller + * may also call xa_set_err() to exit the loop while setting an error + * to record the reason. + */ +#define xas_for_each_conflict(xas, entry) \ + while ((entry = xas_find_conflict(xas))) + +void *__xas_next(struct xa_state *); +void *__xas_prev(struct xa_state *); + +/** + * xas_prev() - Move iterator to previous index. + * @xas: XArray operation state. + * + * If the @xas was in an error state, it will remain in an error state + * and this function will return %NULL. If the @xas has never been walked, + * it will have the effect of calling xas_load(). Otherwise one will be + * subtracted from the index and the state will be walked to the correct + * location in the array for the next operation. + * + * If the iterator was referencing index 0, this function wraps + * around to %ULONG_MAX. + * + * Return: The entry at the new index. This may be %NULL or an internal + * entry. + */ +static inline void *xas_prev(struct xa_state *xas) +{ + struct xa_node *node = xas->xa_node; + + if (unlikely(xas_not_node(node) || node->shift || + xas->xa_offset == 0)) + return __xas_prev(xas); + + xas->xa_index--; + xas->xa_offset--; + return xa_entry(xas->xa, node, xas->xa_offset); +} + +/** + * xas_next() - Move state to next index. + * @xas: XArray operation state. + * + * If the @xas was in an error state, it will remain in an error state + * and this function will return %NULL. If the @xas has never been walked, + * it will have the effect of calling xas_load(). Otherwise one will be + * added to the index and the state will be walked to the correct + * location in the array for the next operation. + * + * If the iterator was referencing index %ULONG_MAX, this function wraps + * around to 0. + * + * Return: The entry at the new index. This may be %NULL or an internal + * entry. + */ +static inline void *xas_next(struct xa_state *xas) +{ + struct xa_node *node = xas->xa_node; + + if (unlikely(xas_not_node(node) || node->shift || + xas->xa_offset == XA_CHUNK_MASK)) + return __xas_next(xas); + + xas->xa_index++; + xas->xa_offset++; + return xa_entry(xas->xa, node, xas->xa_offset); +} + +#endif /* _LINUX_XARRAY_H */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c index 26a7fab2c9..9279d96536 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c @@ -571,6 +571,22 @@ static int dfd_info_reg2data_mac_th5(int data, int *temp_value) return DFD_RV_OK; } +static int dfd_info_reg2data_mac_th6(int data, int *temp_value) +{ + int tmp_val; + int val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th6, data=%d\n", data); + + tmp_val = (data >> 4) | (data & 0xf); + val = 378850 - (((tmp_val - 2) * 259680) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th6, val=%d\n", val); + *temp_value = val; + + return DFD_RV_OK; +} + static int dfd_info_reg2data_mac_th4(int data, int *temp_value) { int tmp_val; @@ -697,6 +713,9 @@ static int dfd_info_get_cpld_temperature(int key, int *value) case MAC_TH4: rv = dfd_info_reg2data_mac_th4(temp_reg, &temp_value); break; + case MAC_TH6: + rv = dfd_info_reg2data_mac_th6(temp_reg, &temp_value); + break; default: temp_value = temp_reg; rv = DFD_RV_OK; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h index def93cd513..ce0144e74c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h @@ -118,7 +118,8 @@ typedef enum sensor_format_mem_s { TMP464, MAC_TH5, MAC_TD3, - MAC_TH4 + MAC_TH4, + MAC_TH6 } sensor_format_mem_t; typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h index 853dba4333..927bf91869 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h @@ -495,6 +495,30 @@ extern const struct regulator_ops pmbus_regulator_ops; #define PMBUS_REGULATOR(_name, _id) PMBUS_REGULATOR_STEP(_name, _id, 0, 0) +#define PMBUS_DEV_NAME_SIZE (256) + +typedef struct { + char device_name[I2C_NAME_SIZE]; + char chip_name[I2C_NAME_SIZE]; + uint8_t device_id[PMBUS_DEV_NAME_SIZE]; + uint32_t dev_id_len; +} pmbus_dev_info_t; + +pmbus_dev_info_t pmbus_dev_infos[] = { + {.device_name = "xdpe12284", .chip_name = "XDPE12284C", .device_id = {0x79, 0x00}, .dev_id_len = 2}, + {.device_name = "xdpe12284", .chip_name = "XDPE12284C", .device_id = {0x79, 0x01}, .dev_id_len = 2}, + {.device_name = "xdpe12284", .chip_name = "XDPE12284C", .device_id = {0x79, 0x02}, .dev_id_len = 2}, + {.device_name = "wb_xdpe132g5c_pmbus", .chip_name = "XDPE132G5C", .device_id = {0x76}, .dev_id_len = 1}, + {.device_name = "wb_xdpe132g5c_pmbus", .chip_name = "XDPE132G5D", .device_id = {0x7c}, .dev_id_len = 1}, + {.device_name = "wb_xdpe1a2g5b_pmbus", .chip_name = "XDPE1A2G5B", .device_id = {0x01, 0x9e}, .dev_id_len = 2}, + /* The driver does not support RAA228248, using RAA228228 instead. */ + {.device_name = "raa228228", .chip_name = "RAA228248", .device_id = {0x00, 0xbc, 0xd2, 0x49}, .dev_id_len = 4}, + {.device_name = "raa228228", .chip_name = "RAA22962048", .device_id = {0x00, 0x9B, 0xD2, 0x49}, .dev_id_len = 4}, + /* The old manual ID is 0x49d26e00, and the new manual ID is 0x49d28100. */ + {.device_name = "isl69260", .chip_name = "ISL69260", .device_id = {0x00, 0x81, 0xd2, 0x49}, .dev_id_len = 4}, + {.device_name = "isl69260", .chip_name = "ISL69260", .device_id = {0x00, 0x6e, 0xd2, 0x49}, .dev_id_len = 4}, +}; + /* Function declarations */ void pmbus_clear_cache(struct i2c_client *client); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c index 05da8b6800..188e6e4f85 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c @@ -187,6 +187,29 @@ static int wb_set_id_led_status(int status) return ret; } +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_lan_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_lan_led_status); + + ret = g_drv->get_lan_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_lan_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_lan_led_status); + + ret = g_drv->set_lan_led_status(status); + return ret; +} /**************************************end of sysled******************************************/ static struct s3ip_sysfs_sysled_drivers_s drivers = { @@ -204,6 +227,8 @@ static struct s3ip_sysfs_sysled_drivers_s drivers = { .set_sys_psu_led_status = wb_set_sys_psu_led_status, .get_id_led_status = wb_get_id_led_status, .set_id_led_status = wb_set_id_led_status, + .get_lan_led_status = wb_get_lan_led_status, + .set_lan_led_status = wb_set_lan_led_status, }; static int __init sysled_init(void) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c index 7579af9069..52c3d08c10 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c @@ -784,6 +784,9 @@ static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl strscpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); #endif break; + case INFO_CTRL_VAL_TYPE: + info_ctrl->val_type = dfd_ko_cfg_get_enum_value_by_str(g_info_val_type_str, INFO_VAL_TYPE_END, buf_val); + break; case INFO_CTRL_MEM_INT_EXTRA1: dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); break; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c index 615285d1c3..4d9a510adf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c @@ -61,6 +61,7 @@ char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END] = { ".len", ".bit_offset", ".str_cons", + ".val_type", ".int_extra1", ".int_extra2", ".int_extra3", @@ -82,6 +83,7 @@ char *g_info_src_str[INFO_SRC_END] = { "fpga", "other_i2c", "file", + "logic_file", }; /* info_frmt_t enumeration string */ @@ -102,6 +104,57 @@ char *g_info_pola_str[INFO_POLA_END] = { "negative", }; +/* info_val_type_t enumeration string */ +char *g_info_val_type_str[INFO_VAL_TYPE_END] = { + "normal", + "fixed_key", + "nega_key", +}; + +static void dfd_val_type_handle(info_ctrl_t *info_ctrl, uint8_t *val, uint8_t is_write) +{ + uint8_t ori_val; + + if (info_ctrl == NULL || val == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error.\n"); + return; + } + + if (!is_write) { + switch (info_ctrl->val_type) { + case INFO_VAL_TYPE_NORMAL: + break; + case INFO_VAL_TYPE_FIXED_KEY: + case INFO_VAL_TYPE_NEGA_KEY: + ori_val = *val; + if (info_ctrl->pola == INFO_POLA_NEGA) { + ori_val = ~ori_val; + } + *val = ori_val & 0x01; + break; + default: + DBG_DEBUG(DBG_ERROR, "info ctrl val_type[%d] invalid.\n", info_ctrl->val_type); + break; + } + } else { + switch (info_ctrl->val_type) { + case INFO_VAL_TYPE_NORMAL: + case INFO_VAL_TYPE_FIXED_KEY: + break; + case INFO_VAL_TYPE_NEGA_KEY: + ori_val = *val; + if (info_ctrl->pola == INFO_POLA_NEGA) { + ori_val = ~ori_val; + } + *val = (~info_ctrl->addr & 0xfe) | (ori_val & 0x01); + break; + default: + DBG_DEBUG(DBG_ERROR, "info ctrl val_type[%d] invalid.\n", info_ctrl->val_type); + break; + } + } +} + /* Read information from the cpld */ static int dfd_read_info_from_cpld(int32_t addr, int read_bytes, uint8_t *val) { @@ -168,6 +221,7 @@ static int dfd_read_info(info_src_t src, char *fpath, int32_t addr, int read_byt case INFO_SRC_OTHER_I2C: rv = dfd_read_info_from_other_i2c(addr, read_bytes, val); break; + case INFO_SRC_LOGIC_FILE: case INFO_SRC_FILE: rv = dfd_ko_read_file(fpath, addr, val, read_bytes); break; @@ -198,6 +252,7 @@ static int dfd_write_info(info_src_t src, char *fpath, int32_t addr, int write_b rv = -1; DBG_DEBUG(DBG_ERROR, "not support write info to other i2c\n"); break; + case INFO_SRC_LOGIC_FILE: case INFO_SRC_FILE: rv = dfd_ko_write_file(fpath, addr, val, write_bytes); break; @@ -277,6 +332,9 @@ static int dfd_get_info_value(info_ctrl_t *info_ctrl, int *ret, info_num_buf_to_ int_tmp <<= 8; } } + if (info_ctrl->frmt == INFO_FRMT_BYTE) { + dfd_val_type_handle(info_ctrl, (uint8_t *)&int_tmp, 0); + } } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { val[readed_bytes] = '\0'; int_tmp = simple_strtol((char *)(&(val[0])), NULL, 10); @@ -542,6 +600,9 @@ int dfd_info_set_int(uint64_t key, int val) /* Write data value conversion */ byte_tmp = (uint8_t)(val & 0xff); + if (info_ctrl->frmt == INFO_FRMT_BYTE) { + dfd_val_type_handle(info_ctrl, &byte_tmp, 1); + } /* Information valid mask */ bit_mask = 0xff; @@ -665,6 +726,21 @@ static long dfd_info_reg2data_mac_th5(uint64_t key, int data) return val; } +static int dfd_info_reg2data_mac_th6(uint64_t key, int data) +{ + int tmp_val; + int val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th6, data=%d\n", data); + + tmp_val = (data >> 4) | (data & 0xf); + val = 378850 - (((tmp_val - 2) * 259680) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th6, val=%d\n", val); + + return val; +} + static long dfd_info_reg2data_mac_th4(uint64_t key, int data) { int tmp_val; @@ -766,6 +842,9 @@ static int dfd_info_get_cpld_temperature(uint64_t key, int *value) case MAC_TH4: val = dfd_info_reg2data_mac_th4(key, temp_reg); break; + case MAC_TH6: + val = dfd_info_reg2data_mac_th6(key, temp_reg); + break; default: val = temp_reg; break; @@ -795,7 +874,8 @@ static int dfd_info_get_sensor_value(uint64_t key, uint8_t *buf, int buf_len, in return -DFD_RV_DEV_NOTSUPPORT; } - if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN && info_ctrl->src == INFO_SRC_CPLD) { + if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN + && (info_ctrl->src == INFO_SRC_CPLD || info_ctrl->src == INFO_SRC_LOGIC_FILE)) { rv = dfd_info_get_cpld_voltage(key, &value); if (rv < 0) { DBG_DEBUG(DBG_ERROR, "get cpld voltage failed.key=0x%08llx, rv:%d\n", key, rv); @@ -821,7 +901,8 @@ static int dfd_info_get_sensor_value(uint64_t key, uint8_t *buf, int buf_len, in memcpy(buf, buf_tmp, buf_real_len); } return buf_real_len; - } else if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_TEMP && info_ctrl->src == INFO_SRC_CPLD) { + } else if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_TEMP + && (info_ctrl->src == INFO_SRC_CPLD || info_ctrl->src == INFO_SRC_LOGIC_FILE)) { rv = dfd_info_get_cpld_temperature(key, &temp_value); if (rv < 0) { DBG_DEBUG(DBG_ERROR, "get cpld temperature failed.key=0x%08llx, rv:%d\n", key, rv); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h index 2e5dd2f3d6..a213db748c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h @@ -76,6 +76,7 @@ typedef enum info_src_e { INFO_SRC_FPGA, /* FPGA equipment */ INFO_SRC_OTHER_I2C, /* other i2c equipment */ INFO_SRC_FILE, /* file */ + INFO_SRC_LOGIC_FILE, /* logic file */ INFO_SRC_END } info_src_t; @@ -87,6 +88,14 @@ typedef enum info_pola_e { INFO_POLA_END } info_pola_t; +/* value type of info ctrl */ +typedef enum info_val_type_e { + INFO_VAL_TYPE_NORMAL = 0, /* Normal value. Keep 0 for compatibility */ + INFO_VAL_TYPE_FIXED_KEY, /* High 7 bits are fixed key */ + INFO_VAL_TYPE_NEGA_KEY, /* High 7 bits are inverse of addr high 7 bits */ + INFO_VAL_TYPE_END +} info_val_type_t; + /* Information control structure */ #define INFO_FPATH_MAX_LEN (128) /* Maximum length of the file source path */ #define INFO_STR_CONS_MAX_LEN (64) /* Maximum length of a string constant */ @@ -101,6 +110,7 @@ typedef struct info_ctrl_s { int32_t len; /* Length, bit length, or byte length */ int32_t bit_offset; /* Offset number of bits in the address */ char str_cons[INFO_STR_CONS_MAX_LEN]; /* String constant */ + info_val_type_t val_type; /* value type */ int32_t int_extra1; /* int type reserved */ int32_t int_extra2; int32_t int_extra3; /* cpld voltage mode */ @@ -118,6 +128,7 @@ typedef enum info_ctrl_mem_s { INFO_CTRL_MEM_LEN, INFO_CTRL_MEM_BIT_OFFSET, INFO_CTRL_MEM_STR_CONS, + INFO_CTRL_VAL_TYPE, INFO_CTRL_MEM_INT_EXTRA1, INFO_CTRL_MEM_INT_EXTRA2, INFO_CTRL_MEM_INT_EXTRA3, @@ -131,6 +142,7 @@ typedef enum sensor_format_mem_s { TMP464 = 3, MAC_TH5 = 4, MAC_TH4 = 5, + MAC_TH6 = 6, } sensor_format_mem_t; /* hwmon data format conversion */ @@ -143,6 +155,7 @@ extern char *g_info_src_str[INFO_SRC_END]; /* info_src_t enumeration extern char *g_info_frmt_str[INFO_FRMT_END]; /* info_frmt_t enumeration string */ extern char *g_info_pola_str[INFO_POLA_END]; /* info_pola_t enumeration string */ extern char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END];/* info_ctrl_mode_t enumeration string */ +extern char *g_info_val_type_str[INFO_VAL_TYPE_END]; /* info_val_type_t enumeration string */ /** * dfd_info_get_int - Get int type information diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h index 994bb2387d..fb2d2d50b4 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h @@ -156,6 +156,8 @@ struct switch_drivers_s { int (*set_sys_psu_led_status)(int status); ssize_t (*get_id_led_status)(char *buf, size_t count); int (*set_id_led_status)(int status); + ssize_t (*get_lan_led_status)(char *buf, size_t count); + int (*set_lan_led_status)(int status); /* FPGA */ int (*get_main_board_fpga_number)(void); ssize_t (*get_main_board_fpga_alias)(unsigned int fpga_index, char *buf, size_t count); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h index 6bce2817cb..af1e1c6f0d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h @@ -186,6 +186,7 @@ typedef enum wb_led_e { WB_FAN_LED_MODULE = 10, /* Fan module indicator */ WB_PSU_LED_MODULE = 11, /* Power module indicator */ WB_SLOT_LED_MODULE = 12, /* Sub-card status indicator */ + WB_OCP_LAN_LED = 13, /* Network status indicator */ } wb_led_t; extern int g_dfd_dbg_level; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c index 5628aadab4..57b79e79f2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c @@ -3003,6 +3003,36 @@ static int dfd_set_id_led_status(int status) return ret; } +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_lan_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_OCP_LAN_LED, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_lan_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_OCP_LAN_LED, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + + return ret; +} + /**************************************end of sysled******************************************/ /******************************************FPGA***********************************************/ static int dfd_get_main_board_fpga_number(void) @@ -4460,6 +4490,8 @@ static struct switch_drivers_s switch_drivers = { .set_sys_psu_led_status = dfd_set_sys_psu_led_status, .get_id_led_status = dfd_get_id_led_status, .set_id_led_status = dfd_set_id_led_status, + .get_lan_led_status = dfd_get_lan_led_status, + .set_lan_led_status = dfd_set_lan_led_status, /* FPGA */ .get_main_board_fpga_number = dfd_get_main_board_fpga_number, .get_main_board_fpga_alias = dfd_get_main_board_fpga_alias, diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c index d0991c6088..f38acf6823 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c @@ -256,7 +256,6 @@ int dfd_set_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, unsigned main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_TEST_REG)); return -DFD_RV_DEV_NOTSUPPORT; } - if (info_ctrl->len > FPGA_REG_WIDTH_MAX) { DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u info_ctrl len: %d, unsupport\n", main_dev_id, fpga_index, info_ctrl->len); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h index 5eaf3af705..9115658c15 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h @@ -32,6 +32,8 @@ struct s3ip_sysfs_sysled_drivers_s { int (*set_sys_psu_led_status)(int status); ssize_t (*get_id_led_status)(char *buf, size_t count); int (*set_id_led_status)(int status); + ssize_t (*get_lan_led_status)(char *buf, size_t count); + int (*set_lan_led_status)(int status); }; extern int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c index 242fb20a87..f4cf7a2080 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c @@ -201,12 +201,47 @@ static ssize_t id_led_status_store(struct switch_obj *obj, struct switch_attribu return count; } +static ssize_t lan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_lan_led_status); + + return g_sysled_drv->get_lan_led_status(buf, PAGE_SIZE); +} + +static ssize_t lan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_lan_led_status); + + value = 0; + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild lan led status ret: %d, can't set lan led status\n", ret); + SYSLED_ERR("invaild lan led status buf: %s\n", buf); + return -EINVAL; + } + + ret = g_sysled_drv->set_lan_led_status(value); + if (ret < 0) { + SYSLED_ERR("set lan led status %d faield, ret: %d\n", value, ret); + return ret; + } + + SYSLED_DBG("set lan led status %d success\n", value); + return count; +} + /************************************syseeprom dir and attrs*******************************************/ static struct switch_attribute sys_led_attr = __ATTR(sys_led_status, S_IRUGO | S_IWUSR, sys_led_status_show, sys_led_status_store); static struct switch_attribute bmc_led_attr = __ATTR(bmc_led_status, S_IRUGO | S_IWUSR, bmc_led_status_show, bmc_led_status_store); static struct switch_attribute fan_led_attr = __ATTR(fan_led_status, S_IRUGO | S_IWUSR, sys_fan_led_status_show, sys_fan_led_status_store); static struct switch_attribute psu_led_attr = __ATTR(psu_led_status, S_IRUGO | S_IWUSR, sys_psu_led_status_show, sys_psu_led_status_store); static struct switch_attribute id_led_attr = __ATTR(id_led_status, S_IRUGO | S_IWUSR, id_led_status_show, id_led_status_store); +static struct switch_attribute lan_led_attr = __ATTR(lan_led_status, S_IRUGO | S_IWUSR, lan_led_status_show, lan_led_status_store); static struct attribute *sysled_dir_attrs[] = { &sys_led_attr.attr, @@ -214,6 +249,7 @@ static struct attribute *sysled_dir_attrs[] = { &fan_led_attr.attr, &psu_led_attr.attr, &id_led_attr.attr, + &lan_led_attr.attr, NULL, }; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c index ef398fbb74..93ccc0dd7a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c @@ -31,176 +31,91 @@ #include #include #include -#include #include #include #include #include -#include -#include #include "wb_indirect_dev.h" -#define MODULE_NAME "wb-indirect-dev" - -#define SYMBOL_I2C_DEV_MODE (1) -#define FILE_MODE (2) -#define SYMBOL_PCIE_DEV_MODE (3) -#define SYMBOL_IO_DEV_MODE (4) -#define SYMBOL_SPI_DEV_MODE (5) - -#define KERNEL_SPACE (0) -#define USER_SPACE (1) - -#define MAX_INDIRECT_DEV_NUM (256) -#define INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff) -#define INDIRECT_ADDR_L(addr) ((addr) & 0xff) -#define INDIRECT_OP_WRITE (0x2) -#define INDIRECT_OP_READ (0x3) - -static int g_indirect_dev_debug = 0; -static int g_indirect_dev_error = 0; - -module_param(g_indirect_dev_debug, int, S_IRUGO | S_IWUSR); -module_param(g_indirect_dev_error, int, S_IRUGO | S_IWUSR); - -#define INDIRECT_DEV_INFO(fmt, args...) do { \ - printk(KERN_INFO "[INDIRECT_DEV][INFO][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ -} while (0) - -#define INDIRECT_DEV_DEBUG(fmt, args...) do { \ - if (g_indirect_dev_debug) { \ - printk(KERN_DEBUG "[INDIRECT_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define INDIRECT_DEV_ERROR(fmt, args...) do { \ - if (g_indirect_dev_error) { \ - printk(KERN_ERR "[INDIRECT_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -static struct indirect_dev_info* indirect_dev_arry[MAX_INDIRECT_DEV_NUM]; - -static int noop_pre(struct kprobe *p, struct pt_regs *regs) { return 0; } -static struct kprobe kp = { - .symbol_name = "kallsyms_lookup_name", -}; -unsigned long (*kallsyms_lookup_name_fun)(const char *name) = NULL; - -/* Call kprobe to find the address location of kallsyms_lookup_name */ -static int find_kallsyms_lookup_name(void) -{ - int ret = -1; - - kp.pre_handler = noop_pre; - ret = register_kprobe(&kp); - if (ret < 0) { - INDIRECT_DEV_ERROR("register_kprobe failed, error:%d\n", ret); - return ret; - } - INDIRECT_DEV_DEBUG("kallsyms_lookup_name addr: %p\n", kp.addr); - kallsyms_lookup_name_fun = (void*)kp.addr; - unregister_kprobe(&kp); - - return ret; -} - -struct indirect_dev_info { +#include +#include + +#define MODULE_NAME "wb-indirect-dev" +#define INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff) +#define INDIRECT_ADDR_L(addr) ((addr) & 0xff) +#define INDIRECT_OP_WRITE (0x2) +#define INDIRECT_OP_READ (0x3) + +/* Use the wb_bsp_kernel_debug header file must define debug variable */ +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static int status_cache_ms = 0; +module_param(status_cache_ms, int, S_IRUGO | S_IWUSR); + +static DEFINE_SPINLOCK(dev_array_lock); +static struct indirect_dev_info* indirect_dev_arry[MAX_DEV_NUM]; + +typedef struct indirect_dev_info { const char *name; /* generate dev name */ + const char *alias; /* generate dev alias */ const char *logic_dev_name; /* dependent dev name */ uint32_t indirect_len; /* dev data len */ uint32_t data_bus_width; /* dev data_bus_width */ - uint32_t addr_bus_width; /* dev addr_bus_width */ uint32_t wr_data; /* dependent dev wr date reg */ - uint32_t wr_data_width; /* dependent dev wr_data_width */ uint32_t addr_low; /* dependent dev w/r addr reg low */ uint32_t addr_high; /* dependent dev w/r addr reg high */ uint32_t rd_data; /* dependent dev rd date reg */ - uint32_t rd_data_width; /* dependent dev rd_data_width */ uint32_t opt_ctl; /* dependent dev opt code reg */ uint32_t logic_func_mode; /* 1: i2c, 2: file, 3:pcie, 4:io, 5:spi */ + uint32_t lock_mode; /* 1:spin lock, 2:mutex */ unsigned long write_intf_addr; unsigned long read_intf_addr; spinlock_t indirect_dev_lock; + struct mutex mutex_lock; struct miscdevice misc; - struct device *dev; -}; - -static int wb_dev_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) + struct kobject kobj; + struct attribute_group *sysfs_group; + uint8_t file_cache_rd; + uint8_t file_cache_wr; + char cache_file_path[MAX_NAME_SIZE]; + char mask_file_path[MAX_NAME_SIZE]; + struct mutex update_lock; + wb_bsp_key_device_log_node_t log_node; + device_status_check_t status_check; +} wb_indirect_dev_t; + +static void wb_dev_lock_init(struct indirect_dev_info *indirect_dev) { - int ret; - struct file *filp; - loff_t tmp_pos; - - struct kvec iov = { - .iov_base = val, - .iov_len = min_t(size_t, size, MAX_RW_COUNT), - }; - struct iov_iter iter; - - filp = filp_open(path, O_RDONLY, 0); - if (IS_ERR(filp)) { - INDIRECT_DEV_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); - filp = NULL; - goto exit; - } - tmp_pos = (loff_t)pos; - iov_iter_kvec(&iter, ITER_DEST, &iov, 1, iov.iov_len); - ret = vfs_iter_read(filp, &iter, &tmp_pos, 0); - if (ret < 0) { - INDIRECT_DEV_ERROR("vfs_iter_read failed, path=%s, addr=0x%x, size=%zu, ret=%d\r\n", path, pos, size, ret); - goto exit; - } - filp_close(filp, NULL); - - return ret; - -exit: - if (filp != NULL) { - filp_close(filp, NULL); + if (indirect_dev->lock_mode == WB_MUTEX_LOCK_MODE) { + mutex_init(&indirect_dev->mutex_lock); + } else { + spin_lock_init(&indirect_dev->indirect_dev_lock); } - return -1; + return; } -static int wb_dev_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +static void wb_dev_lock(struct indirect_dev_info *indirect_dev, unsigned long *flags) { - int ret; - struct file *filp; - loff_t tmp_pos; - - struct kvec iov = { - .iov_base = val, - .iov_len = min_t(size_t, size, MAX_RW_COUNT), - }; - struct iov_iter iter; - - filp = filp_open(path, O_RDWR, 777); - if (IS_ERR(filp)) { - INDIRECT_DEV_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); - filp = NULL; - goto exit; - } - - tmp_pos = (loff_t)pos; - iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, iov.iov_len); - ret = vfs_iter_write(filp, &iter, &tmp_pos, 0); - if (ret < 0) { - INDIRECT_DEV_ERROR("vfs_iter_write failed, path=%s, addr=0x%x, size=%zu, ret=%d\r\n", path, pos, size, ret); - goto exit; + if (indirect_dev->lock_mode == WB_MUTEX_LOCK_MODE) { + mutex_lock(&indirect_dev->mutex_lock); + } else { + spin_lock_irqsave(&indirect_dev->indirect_dev_lock, *flags); } - - vfs_fsync(filp, 1); - filp_close(filp, NULL); - return ret; + return; +} -exit: - if (filp != NULL) { - filp_close(filp, NULL); +static void wb_dev_unlock(struct indirect_dev_info *indirect_dev, unsigned long *flags) +{ + if (indirect_dev->lock_mode == WB_MUTEX_LOCK_MODE) { + mutex_unlock(&indirect_dev->mutex_lock); + } else { + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, *flags); } - return -1; + return; } static int wb_logic_reg_write(struct indirect_dev_info *indirect_dev, uint32_t pos, uint8_t *val, size_t size) @@ -230,37 +145,40 @@ static int indirect_addressing_read(struct indirect_dev_info *indirect_dev, uint addr_l = INDIRECT_ADDR_L(address); op_code = INDIRECT_OP_READ; - spin_lock_irqsave(&indirect_dev->indirect_dev_lock, flags); + wb_dev_lock(indirect_dev, &flags); + DEBUG_VERBOSE("write reg addr_low=0x%x, value = 0x%x\n\n", indirect_dev->addr_low, addr_l); ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_low, &addr_l, WIDTH_1Byte); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_low, addr_l); + DEBUG_ERROR("indirect_read write reg error.offset = 0x%x, value = 0x%x\n", indirect_dev->addr_low, addr_l); goto fail; } + DEBUG_VERBOSE("write reg addr_high=0x%x, value = 0x%x\n\n", indirect_dev->addr_high, addr_h); ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_high, &addr_h, WIDTH_1Byte); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_high, addr_h); + DEBUG_ERROR("indirect_read write reg error.offset = 0x%x, value = 0x%x\n", indirect_dev->addr_high, addr_h); goto fail; } + DEBUG_VERBOSE("write reg opt_ctl=0x%x, value = 0x%x\n\n", indirect_dev->opt_ctl, op_code); ret = wb_logic_reg_write(indirect_dev, indirect_dev->opt_ctl, &op_code, WIDTH_1Byte); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); + DEBUG_ERROR("indirect_read write reg error.offset = 0x%x, value = 0x%x\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); goto fail; } ret = wb_logic_reg_read(indirect_dev, indirect_dev->rd_data, buf, rd_data_width); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_read read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->rd_data, ret); + DEBUG_ERROR("indirect_read read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->rd_data, ret); goto fail; } - INDIRECT_DEV_DEBUG("indirect_read success, addr = 0x%x\n", address); - spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + DEBUG_VERBOSE("indirect_read success, addr = 0x%x\n", address); + wb_dev_unlock(indirect_dev, &flags); return ret; fail: - spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + wb_dev_unlock(indirect_dev, &flags); return ret; } @@ -270,30 +188,50 @@ static int device_read(struct indirect_dev_info *indirect_dev, uint32_t offset, u32 data_width; u32 tmp; - data_width = indirect_dev->data_bus_width; + if (offset >= indirect_dev->indirect_len) { + DEBUG_VERBOSE("offset: 0x%x, indirect len: 0x%x, count: %zu, EOF.\n", + offset, indirect_dev->indirect_len, count); + return 0; + } + data_width = indirect_dev->data_bus_width; if (offset % data_width) { - INDIRECT_DEV_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", + DEBUG_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", data_width, offset, count); return -EINVAL; } if (count > indirect_dev->indirect_len - offset) { - INDIRECT_DEV_DEBUG("read count out of range. input len:%zu, read len:%u.\n", - count, indirect_dev->indirect_len - offset); - count = indirect_dev->indirect_len - offset; + DEBUG_VERBOSE("read count out of range. input len:%zu, read len:%u.\n", + count, indirect_dev->indirect_len - offset); + count = indirect_dev->indirect_len - offset; } tmp = count; for (i = 0; i < count; i += data_width) { ret = indirect_addressing_read(indirect_dev, buf + i, offset + i, (tmp > data_width ? data_width : tmp)); if (ret < 0) { - INDIRECT_DEV_ERROR("read error.read offset = %u\n", (offset + i)); + DEBUG_ERROR("read error.read offset = %u\n", (offset + i)); return -EFAULT; } tmp -= data_width; } + if (indirect_dev->file_cache_rd) { + ret = cache_value_read(indirect_dev->mask_file_path, indirect_dev->cache_file_path, offset, buf, count); + if (ret < 0) { + DEBUG_ERROR("indirect_dev data offset: 0x%x, read_len: %zu, read cache file fail, ret: %d, return act value\n", + offset, count, ret); + } else { + DEBUG_VERBOSE("indirect_dev data offset: 0x%x, read_len: %zu success, read from cache value\n", + offset, count); + } + } + + if (debug & DEBUG_DUMP_DATA_LEVEL) { + logic_dev_dump_data(indirect_dev->name, offset, buf, count, true); + } + return count; } @@ -307,37 +245,40 @@ static int indirect_addressing_write(struct indirect_dev_info *indirect_dev, uin addr_l = INDIRECT_ADDR_L(address); op_code = INDIRECT_OP_WRITE; - spin_lock_irqsave(&indirect_dev->indirect_dev_lock, flags); + wb_dev_lock(indirect_dev, &flags); ret = wb_logic_reg_write(indirect_dev, indirect_dev->wr_data, buf, wr_data_width); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_write read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->wr_data, ret); + DEBUG_ERROR("indirect_write read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->wr_data, ret); goto fail; } + DEBUG_VERBOSE("write reg addr_low=0x%x, value = 0x%x\n\n", indirect_dev->addr_low, addr_l); ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_low, &addr_l, WIDTH_1Byte); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_low, addr_l); + DEBUG_ERROR("indirect_write write reg error.offset = 0x%x, value = 0x%x\n", indirect_dev->addr_low, addr_l); goto fail; } + DEBUG_VERBOSE("write reg addr_high=0x%x, value = 0x%x\n\n", indirect_dev->addr_high, addr_h); ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_high, &addr_h, WIDTH_1Byte); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_high, addr_h); + DEBUG_ERROR("indirect_write write reg error.offset = 0x%x, value = 0x%x\n", indirect_dev->addr_high, addr_h); goto fail; } + DEBUG_VERBOSE("write reg opt_ctl=0x%x, value = 0x%x\n\n", indirect_dev->opt_ctl, op_code); ret = wb_logic_reg_write(indirect_dev, indirect_dev->opt_ctl, &op_code, WIDTH_1Byte); if (ret < 0) { - INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); + DEBUG_ERROR("indirect_write write reg error.offset = 0x%x, value = 0x%x\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); goto fail; } - INDIRECT_DEV_DEBUG("indirect_write success, addr = 0x%x\n", address); - spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + DEBUG_VERBOSE("indirect_write success, addr = 0x%x\n", address); + wb_dev_unlock(indirect_dev, &flags); return ret; fail: - spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + wb_dev_unlock(indirect_dev, &flags); return ret; } @@ -347,154 +288,144 @@ static int device_write(struct indirect_dev_info *indirect_dev, uint32_t offset, u32 data_width; u32 tmp; - if (offset > indirect_dev->indirect_len) { - INDIRECT_DEV_DEBUG("offset: 0x%x, spi len: 0x%x, count: %zu, EOF.\n", + if (offset >= indirect_dev->indirect_len) { + DEBUG_VERBOSE("offset: 0x%x, indirect len: 0x%x, count: %zu, EOF.\n", offset, indirect_dev->indirect_len, count); return 0; } data_width = indirect_dev->data_bus_width; if (offset % data_width) { - INDIRECT_DEV_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", + DEBUG_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", data_width, offset, count); return -EINVAL; } if (count > (indirect_dev->indirect_len - offset)) { - INDIRECT_DEV_DEBUG("write count out of range. input len:%zu, read len:%u.\n", + DEBUG_VERBOSE("write count out of range. input len:%zu, read len:%u.\n", count, indirect_dev->indirect_len - offset); count = indirect_dev->indirect_len - offset; } - if (count == 0) { - INDIRECT_DEV_DEBUG("offset: 0x%x, i2c len: 0x%x, read len: %zu, EOF.\n", - offset, indirect_dev->indirect_len, count); - return 0; - } - tmp = count; for (i = 0; i < count; i += data_width) { ret = indirect_addressing_write(indirect_dev, buf + i, offset + i, (tmp > data_width ? data_width : tmp)); if (ret < 0) { - INDIRECT_DEV_ERROR("write error.offset = %u\n", (offset + i)); + DEBUG_ERROR("write error.offset = %u\n", (offset + i)); return -EFAULT; } tmp -= data_width; } + + if (debug & DEBUG_DUMP_DATA_LEVEL) { + logic_dev_dump_data(indirect_dev->name, offset, buf, count, false); + } + return count; } -static ssize_t indirect_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset, int flag) +static ssize_t indirect_dev_read(struct file *file, char *buf, size_t count, loff_t *offset) { u8 val[MAX_RW_LEN]; int ret, read_len; struct indirect_dev_info *indirect_dev; + if (offset == NULL || *offset < 0) { + DEBUG_ERROR("offset invalid, read failed.\n"); + return -EINVAL; + } + indirect_dev = file->private_data; if (indirect_dev == NULL) { - INDIRECT_DEV_ERROR("can't get read private_data.\n"); + DEBUG_ERROR("can't get read private_data.\n"); return -EINVAL; } if (count == 0) { - INDIRECT_DEV_ERROR("Invalid params, read count is 0.\n"); + DEBUG_ERROR("Invalid params, read count is 0.\n"); return -EINVAL; } if (count > sizeof(val)) { - INDIRECT_DEV_DEBUG("read count %zu exceed max %zu.\n", count, sizeof(val)); + DEBUG_VERBOSE("read count %zu exceed max %zu.\n", count, sizeof(val)); count = sizeof(val); } mem_clear(val, sizeof(val)); read_len = device_read(indirect_dev, (uint32_t)*offset, val, count); if (read_len < 0) { - INDIRECT_DEV_ERROR("indirect dev read failed, dev name:%s, offset:0x%x, len:%zu.\n", + DEBUG_ERROR("indirect dev read failed, dev name:%s, offset:0x%x, len:%zu.\n", indirect_dev->name, (uint32_t)*offset, count); return read_len; } - /* check flag is user spase or kernel spase */ - if (flag == USER_SPACE) { - INDIRECT_DEV_DEBUG("user space read, buf: %p, offset: %lld, read count %zu.\n", - buf, *offset, count); - if (copy_to_user(buf, val, read_len)) { - INDIRECT_DEV_ERROR("copy_to_user failed.\n"); - return -EFAULT; - } - } else { - INDIRECT_DEV_DEBUG("kernel space read, buf: %p, offset: %lld, read count %zu.\n", - buf, *offset, count); - memcpy(buf, val, read_len); + if (read_len == 0) { + DEBUG_VERBOSE("indirect dev read EOF, offset: 0x%llx, count: %zu\n", *offset, count); + return 0; } + DEBUG_VERBOSE("read, buf: %p, offset: %lld, read count %zu.\n", buf, *offset, count); + memcpy(buf, val, read_len); + *offset += read_len; ret = read_len; return ret; } -static ssize_t indirect_dev_read_user(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - int ret; - - INDIRECT_DEV_DEBUG("indirect_dev_read_user, file: %p, count: %lu, offset: %lld\n", - file, count, *offset); - ret = indirect_dev_read(file, buf, count, offset, USER_SPACE); - return ret; -} - - static ssize_t indirect_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) { - int ret; - - INDIRECT_DEV_DEBUG("indirect_dev_read_iter, file: %p, count: %zu, offset: %lld\n", - iocb->ki_filp, to->count, iocb->ki_pos); - ret = indirect_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); - return ret; + DEBUG_VERBOSE("indirect_dev_read_iter, file: %p, count: %zu, offset: %lld\n", + iocb->ki_filp, iov_iter_count(to), iocb->ki_pos); + return wb_iov_iter_read(iocb, to, indirect_dev_read); } -static ssize_t indirect_dev_write(struct file *file, const char __user *buf, - size_t count, loff_t *offset, int flag) +static ssize_t indirect_dev_write(struct file *file, char *buf, + size_t count, loff_t *offset) { u8 val[MAX_RW_LEN]; int write_len; struct indirect_dev_info *indirect_dev; + char bsp_log_dev_name[BSP_LOG_DEV_NAME_MAX_LEN]; + char bsp_log_file_path[BSP_LOG_DEV_NAME_MAX_LEN]; + + if (offset == NULL || *offset < 0) { + DEBUG_ERROR("offset invalid, read failed.\n"); + return -EINVAL; + } indirect_dev = file->private_data; if (indirect_dev == NULL) { - INDIRECT_DEV_ERROR("get write private_data error.\n"); + DEBUG_ERROR("get write private_data error.\n"); return -EINVAL; } if (count == 0) { - INDIRECT_DEV_ERROR("Invalid params, write count is 0.\n"); + DEBUG_ERROR("Invalid params, write count is 0.\n"); return -EINVAL; } if (count > sizeof(val)) { - INDIRECT_DEV_DEBUG("write count %zu exceed max %zu.\n", count, sizeof(val)); + DEBUG_VERBOSE("write count %zu exceed max %zu.\n", count, sizeof(val)); count = sizeof(val); } mem_clear(val, sizeof(val)); - /* check flag is user spase or kernel spase */ - if (flag == USER_SPACE) { - INDIRECT_DEV_DEBUG("user space write, buf: %p, offset: %lld, write count %zu.\n", - buf, *offset, count); - if (copy_from_user(val, buf, count)) { - INDIRECT_DEV_ERROR("copy_from_user failed.\n"); - return -EFAULT; - } - } else { - INDIRECT_DEV_DEBUG("kernel space write, buf: %p, offset: %lld, write count %zu.\n", - buf, *offset, count); - memcpy(val, buf, count); + + DEBUG_VERBOSE("write, buf: %p, offset: %lld, write count %zu.\n", buf, *offset, count); + memcpy(val, buf, count); + + if (indirect_dev->log_node.log_num > 0) { + mem_clear(bsp_log_dev_name, sizeof(bsp_log_dev_name)); + mem_clear(bsp_log_file_path, sizeof(bsp_log_file_path)); + snprintf(bsp_log_dev_name, sizeof(bsp_log_dev_name), "[Devfs]"); + snprintf(bsp_log_file_path, sizeof(bsp_log_file_path), "%s.%s_bsp_key_reg", BSP_LOG_DIR, indirect_dev->name); + (void)wb_bsp_key_device_log(bsp_log_dev_name, bsp_log_file_path, WB_BSP_LOG_MAX, + &(indirect_dev->log_node), (uint32_t)*offset, val, count); } write_len = device_write(indirect_dev, (uint32_t)*offset, val, count); if (write_len < 0) { - INDIRECT_DEV_ERROR("indirect dev write failed, dev name:%s, offset:0x%llx, len:%zu.\n", + DEBUG_ERROR("indirect dev write failed, dev name:%s, offset:0x%llx, len:%zu.\n", indirect_dev->name, *offset, count); return write_len; } @@ -503,24 +434,11 @@ static ssize_t indirect_dev_write(struct file *file, const char __user *buf, return write_len; } -static ssize_t indirect_dev_write_user(struct file *file, const char __user *buf, size_t count, loff_t *offset) -{ - int ret; - - INDIRECT_DEV_DEBUG("indirect_dev_write_user, file: %p, count: %lu, offset: %lld\n", - file, count, *offset); - ret = indirect_dev_write(file, buf, count, offset, USER_SPACE); - return ret; -} - static ssize_t indirect_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) { - int ret; - - INDIRECT_DEV_DEBUG("indirect_dev_write_iter, file: %p, count: %zu, offset: %lld\n", - iocb->ki_filp, from->count, iocb->ki_pos); - ret = indirect_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); - return ret; + DEBUG_VERBOSE("indirect_dev_write_iter, file: %p, count: %zu, offset: %lld\n", + iocb->ki_filp, iov_iter_count(from), iocb->ki_pos); + return wb_iov_iter_write(iocb, from, indirect_dev_write); } static loff_t indirect_dev_llseek(struct file *file, loff_t offset, int origin) @@ -530,19 +448,19 @@ static loff_t indirect_dev_llseek(struct file *file, loff_t offset, int origin) indirect_dev = file->private_data; if (indirect_dev == NULL) { - INDIRECT_DEV_ERROR("indirect_dev is NULL, llseek failed.\n"); + DEBUG_ERROR("indirect_dev is NULL, llseek failed.\n"); return -EINVAL; } switch (origin) { case SEEK_SET: if (offset < 0) { - INDIRECT_DEV_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); ret = -EINVAL; break; } if (offset > indirect_dev->indirect_len) { - INDIRECT_DEV_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n", + DEBUG_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n", offset, indirect_dev->indirect_len); ret = - EINVAL; break; @@ -552,14 +470,16 @@ static loff_t indirect_dev_llseek(struct file *file, loff_t offset, int origin) break; case SEEK_CUR: if (((file->f_pos + offset) > indirect_dev->indirect_len) || ((file->f_pos + offset) < 0)) { - INDIRECT_DEV_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", file->f_pos, offset); + ret = -EINVAL; + break; } file->f_pos += offset; ret = file->f_pos; break; default: - INDIRECT_DEV_ERROR("unsupport llseek type:%d.\n", origin); + DEBUG_ERROR("unsupport llseek type:%d.\n", origin); ret = -EINVAL; break; } @@ -571,24 +491,70 @@ static long indirect_dev_ioctl(struct file *file, unsigned int cmd, unsigned lon return 0; } -static int indirect_dev_open(struct inode *inode, struct file *file) +static int minor_to_dev(int minor, struct indirect_dev_info **indirect_dev) { - unsigned int minor = iminor(inode); - struct indirect_dev_info *indirect_dev; + int i; - if (minor >= MAX_INDIRECT_DEV_NUM) { - INDIRECT_DEV_ERROR("minor out of range, minor = %d.\n", minor); - return -ENODEV; + for (i = 0; i < MAX_DEV_NUM; i++) { + if (indirect_dev_arry[i] == NULL) { + continue; + } + if (indirect_dev_arry[i]->misc.minor == minor) { + *indirect_dev = indirect_dev_arry[i]; + return 0; + } } + return -ENODEV; +} - indirect_dev = indirect_dev_arry[minor]; - if (indirect_dev == NULL) { - INDIRECT_DEV_ERROR("indirect_dev is NULL, open failed, minor = %d\n", minor); - return -ENODEV; +static int add_dev_to_g_dev_list(struct indirect_dev_info *indirect_dev) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&dev_array_lock, flags); + for (i = 0; i < MAX_DEV_NUM; i++) { + if (indirect_dev_arry[i] == NULL) { + indirect_dev_arry[i] = indirect_dev; + spin_unlock_irqrestore(&dev_array_lock, flags); + return 0; + } } + spin_unlock_irqrestore(&dev_array_lock, flags); + return -EBUSY; +} - file->private_data = indirect_dev; +static int remove_dev_from_g_dev_list(int minor) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&dev_array_lock, flags); + for (i = 0; i < MAX_DEV_NUM; i++) { + if (indirect_dev_arry[i] == NULL) { + continue; + } + if (indirect_dev_arry[i]->misc.minor == minor) { + indirect_dev_arry[i] = NULL; + spin_unlock_irqrestore(&dev_array_lock, flags); + return 0; + } + } + spin_unlock_irqrestore(&dev_array_lock, flags); + return -ENODEV ; +} + +static int indirect_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct indirect_dev_info *indirect_dev; + int ret; + ret = minor_to_dev(minor, &indirect_dev); + if (ret) { + return ret; + } + file->private_data = indirect_dev; return 0; } @@ -602,8 +568,6 @@ static int indirect_dev_release(struct inode *inode, struct file *file) static const struct file_operations indirect_dev_fops = { .owner = THIS_MODULE, .llseek = indirect_dev_llseek, - .read = indirect_dev_read_user, - .write = indirect_dev_write_user, .read_iter = indirect_dev_read_iter, .write_iter = indirect_dev_write_iter, .unlocked_ioctl = indirect_dev_ioctl, @@ -614,17 +578,17 @@ static const struct file_operations indirect_dev_fops = { static struct indirect_dev_info *dev_match(const char *path) { struct indirect_dev_info *indirect_dev; - char dev_name[DEV_NAME_LEN]; + char dev_name[MAX_NAME_SIZE]; int i; - for (i = 0; i < MAX_INDIRECT_DEV_NUM; i++) { + for (i = 0; i < MAX_DEV_NUM; i++) { if (indirect_dev_arry[i] == NULL) { continue; } indirect_dev = indirect_dev_arry[i]; - snprintf(dev_name, DEV_NAME_LEN,"/dev/%s", indirect_dev->name); + snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", indirect_dev->name); if (!strcmp(path, dev_name)) { - INDIRECT_DEV_DEBUG("get dev_name = %s, minor = %d\n", dev_name, i); + DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i); return indirect_dev; } } @@ -638,24 +602,24 @@ int indirect_device_func_read(const char *path, uint32_t offset, uint8_t *buf, s int read_len; if (path == NULL) { - INDIRECT_DEV_ERROR("path NULL"); + DEBUG_ERROR("path NULL"); return -EINVAL; } if (buf == NULL) { - INDIRECT_DEV_ERROR("buf NULL"); + DEBUG_ERROR("buf NULL"); return -EINVAL; } indirect_dev = dev_match(path); if (indirect_dev == NULL) { - INDIRECT_DEV_ERROR("indirect_dev match failed. dev path = %s", path); + DEBUG_ERROR("indirect_dev match failed. dev path = %s", path); return -EINVAL; } read_len = device_read(indirect_dev, offset, buf, count); if (read_len < 0) { - INDIRECT_DEV_ERROR("indirect_dev_read_tmp failed, ret:%d.\n", read_len); + DEBUG_ERROR("indirect_dev_read_tmp failed, ret:%d.\n", read_len); } return read_len; } @@ -665,40 +629,574 @@ int indirect_device_func_write(const char *path, uint32_t offset, uint8_t *buf, { struct indirect_dev_info *indirect_dev; int write_len; + char bsp_log_dev_name[BSP_LOG_DEV_NAME_MAX_LEN]; + char bsp_log_file_path[BSP_LOG_DEV_NAME_MAX_LEN]; if (path == NULL) { - INDIRECT_DEV_ERROR("path NULL"); + DEBUG_ERROR("path NULL"); return -EINVAL; } if (buf == NULL) { - INDIRECT_DEV_ERROR("buf NULL"); + DEBUG_ERROR("buf NULL"); return -EINVAL; } indirect_dev = dev_match(path); if (indirect_dev == NULL) { - INDIRECT_DEV_ERROR("indirect_dev match failed. dev path = %s", path); + DEBUG_ERROR("indirect_dev match failed. dev path = %s", path); return -EINVAL; } + if (indirect_dev->log_node.log_num > 0) { + mem_clear(bsp_log_dev_name, sizeof(bsp_log_dev_name)); + mem_clear(bsp_log_file_path, sizeof(bsp_log_file_path)); + snprintf(bsp_log_dev_name, sizeof(bsp_log_dev_name), "[Symbol]"); + snprintf(bsp_log_file_path, sizeof(bsp_log_file_path), "%s.%s_bsp_key_reg", BSP_LOG_DIR, indirect_dev->name); + (void)wb_bsp_key_device_log(bsp_log_dev_name, bsp_log_file_path, WB_BSP_LOG_MAX, + &(indirect_dev->log_node), offset, buf, count); + } + write_len = device_write(indirect_dev, offset, buf, count); if (write_len < 0) { - INDIRECT_DEV_ERROR("indirect_dev_write_tmp failed, ret:%d.\n", write_len); + DEBUG_ERROR("indirect_dev_write_tmp failed, ret:%d.\n", write_len); } return write_len; } EXPORT_SYMBOL(indirect_device_func_write); +static ssize_t indirect_dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct kobj_attribute *attribute; + + attribute = container_of(attr, struct kobj_attribute, attr); + + if (!attribute->show) { + DEBUG_ERROR("indirect dev attr show is null.\n"); + return -ENOSYS; + } + + return attribute->show(kobj, attribute, buf); +} + +static ssize_t indirect_dev_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t len) +{ + struct kobj_attribute *attribute; + + attribute = container_of(attr, struct kobj_attribute, attr); + + if (!attribute->store) { + DEBUG_ERROR("indirect dev attr store is null.\n"); + return -ENOSYS; + } + + return attribute->store(kobj, attribute, buf, len); +} + +static const struct sysfs_ops indirect_dev_sysfs_ops = { + .show = indirect_dev_attr_show, + .store = indirect_dev_attr_store, +}; + +static void indirect_dev_obj_release(struct kobject *kobj) +{ + return; +} + +static struct kobj_type indirect_dev_ktype = { + .sysfs_ops = &indirect_dev_sysfs_ops, + .release = indirect_dev_obj_release, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0) + .default_attrs = NULL, +#endif +}; + +static ssize_t alias_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + + if (!indirect_dev) { + DEBUG_ERROR("alias show indirect dev is null.\n"); + return -ENODEV; + } + + mem_clear(buf, PAGE_SIZE); + return snprintf(buf, PAGE_SIZE, "%s\n", indirect_dev->alias); +} + +static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mem_clear(buf, PAGE_SIZE); + return snprintf(buf, PAGE_SIZE, "%s\n", MODULE_NAME); +} + +static ssize_t info_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + int offset; + ssize_t buf_len; + + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + if (!indirect_dev) { + DEBUG_ERROR("info show alias_show indirect dev is null.\n"); + return -ENODEV; + } + + mem_clear(buf, PAGE_SIZE); + offset = 0; + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "name: %s\n", indirect_dev->name); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "alias: %s\n", indirect_dev->alias); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "dependent logic_dev_name: %s\n", indirect_dev->logic_dev_name); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "indirect_len: 0x%x\n", indirect_dev->indirect_len); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "wr_data reg: 0x%x\n", indirect_dev->wr_data); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "rd_data reg: 0x%x\n", indirect_dev->rd_data); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "opt_ctl reg: 0x%x\n", indirect_dev->opt_ctl); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "addr_high reg: 0x%x\n", indirect_dev->addr_high); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "addr_low reg: 0x%x\n", indirect_dev->addr_low); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "logic_func_mode: %u\n", indirect_dev->logic_func_mode); + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "lock_mode reg: %u\n", indirect_dev->lock_mode); + buf_len = strlen(buf); + return buf_len; +} + +static ssize_t status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + wb_indirect_dev_t *indirect_dev; + uint32_t type, len; + int ret; + + indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + if (!indirect_dev) { + DEBUG_ERROR("Failed: status show param is NULL.\n"); + return -ENODEV; + } + + type = indirect_dev->status_check.status_check_type_bmp; + /* check logic dev support type */ + if (wb_logic_status_type_get_number(type) == 0) { + DEBUG_ERROR("unsupport dev status check.\n"); + return -EOPNOTSUPP; + } + + if (time_before(jiffies, indirect_dev->status_check.last_jiffies + msecs_to_jiffies(status_cache_ms))) { + /* Within the time range of status_cache_ms, directly return the last result */ + DEBUG_VERBOSE("time before last time %d ms return last status: %d\n", + status_cache_ms, indirect_dev->status_check.dev_status); + return sprintf(buf, "%u\n", indirect_dev->status_check.dev_status); + } + + indirect_dev->status_check.last_jiffies = jiffies; + + len = indirect_dev->data_bus_width; + if (len > MAX_DATA_WIDTH) { + DEBUG_ERROR("status show rw len:%u beyond max byte.\n", len); + return -EINVAL; + } + + mutex_lock(&indirect_dev->update_lock); + ret = wb_logic_dev_get_status(&indirect_dev->status_check, len, buf, PAGE_SIZE); + if (ret < 0) { + DEBUG_ERROR("wb_logic_dev_get_status fail. (ret %d)\n", ret); + } + mutex_unlock(&indirect_dev->update_lock); + + return ret; +} + +static ssize_t status_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + wb_indirect_dev_t *indirect_dev; + uint32_t val; + int ret; + uint32_t len; + + indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + if (!indirect_dev) { + DEBUG_ERROR("status_store param is null.\n"); + return -ENODEV; + } + + val = 0; + ret = kstrtou32(buf, 0, &val); + if (ret) { + DEBUG_ERROR("Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + + len = indirect_dev->data_bus_width; + if (len > MAX_DATA_WIDTH) { + DEBUG_ERROR("status store rw len:%u beyond max byte.\n", len); + return -EINVAL; + } + + DEBUG_INFO("status store len:%u val:0x%x.\n", len, val); + + mutex_lock(&indirect_dev->update_lock); + ret = wb_logic_clear_status(&indirect_dev->status_check, len, val); + if (ret < 0) { + DEBUG_ERROR("wb_logic_clear_status fail. (ret %d)\n", ret); + } else { + ret = count; + } + mutex_unlock(&indirect_dev->update_lock); + + return ret; +} + +static ssize_t status_show_with_type(struct kobject *kobj, struct kobj_attribute *attr, char *buf, uint32_t type) +{ + wb_indirect_dev_t *indirect_dev; + uint32_t len; + int ret; + + indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + if (!indirect_dev) { + DEBUG_ERROR("Failed: status show param is NULL.\n"); + return -ENODEV; + } + + /* Input parameter detection, only one type */ + if (wb_logic_status_type_get_number(type) != 1) { + DEBUG_ERROR("unsupport dev status check. type 0x%x\n", type); + return -EOPNOTSUPP; + } + + ret = wb_logic_get_cache_status_with_type(&indirect_dev->status_check, type, status_cache_ms, buf, PAGE_SIZE); + if (ret > 0) { + /* use cache status */ + DEBUG_VERBOSE("use cache status return %d, type %d\n", ret, type); + return ret; + } else if (ret == 0) { + /* do nothing */ + DEBUG_VERBOSE("not use cache status\n"); + } else { + /* get cache status fail */ + DEBUG_VERBOSE("wb_logic_get_cache_status_with_type fail, ret %d, type %d\n", ret, type); + return ret; + } + + len = indirect_dev->data_bus_width; + if (len > MAX_DATA_WIDTH) { + DEBUG_ERROR("status show rw len:%u beyond max 4 byte.\n", len); + return -EINVAL; + } + + mutex_lock(&indirect_dev->update_lock); + ret = wb_logic_dev_get_status_with_type(&indirect_dev->status_check, len, buf, PAGE_SIZE, type); + if (ret < 0) { + DEBUG_ERROR("wb_logic_dev_get_status fail. (ret %d)\n", ret); + } + mutex_unlock(&indirect_dev->update_lock); + + return ret; +} + +static ssize_t status_seu_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return status_show_with_type(kobj, attr, buf, STATUS_CHECK_SEU); +} + +static ssize_t status_selftest_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return status_show_with_type(kobj, attr, buf, STATUS_CHECK_SELFTEST); +} + +static ssize_t status_scratch_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return status_show_with_type(kobj, attr, buf, STATUS_CHECK_SCRATCH); +} + +static ssize_t status_cram_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return status_show_with_type(kobj, attr, buf, STATUS_CHECK_CRAM); +} + +static ssize_t file_cache_rd_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + + if (!indirect_dev) { + DEBUG_ERROR("file_cache_rd_show indirect dev is null.\n"); + return -ENODEV; + } + + mem_clear(buf, PAGE_SIZE); + return snprintf(buf, PAGE_SIZE, "%u\n", indirect_dev->file_cache_rd); +} + +static ssize_t file_cache_rd_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + u8 val; + int ret; + + if (!indirect_dev) { + DEBUG_ERROR("file_cache_rd_store indirect dev is null.\n"); + return -ENODEV; + } + + val = 0; + ret = kstrtou8(buf, 0, &val); + if (ret) { + DEBUG_ERROR("Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + indirect_dev->file_cache_rd = val; + + return count; +} + +static ssize_t file_cache_wr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + + if (!indirect_dev) { + DEBUG_ERROR("file_cache_wr_show indirect dev is null.\n"); + return -ENODEV; + } + + mem_clear(buf, PAGE_SIZE); + return snprintf(buf, PAGE_SIZE, "%d\n", indirect_dev->file_cache_wr); +} + +static ssize_t file_cache_wr_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + u8 val; + int ret; + + if (!indirect_dev) { + DEBUG_ERROR("file_cache_wr_store indirect dev is null.\n"); + return -ENODEV; + } + + val = 0; + ret = kstrtou8(buf, 0, &val); + if (ret) { + DEBUG_ERROR("Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + indirect_dev->file_cache_wr = val; + + return count; +} + +static ssize_t cache_file_path_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + + if (!indirect_dev) { + DEBUG_ERROR("cache_file_path_show indirect dev is null.\n"); + return -ENODEV; + } + + mem_clear(buf, PAGE_SIZE); + return snprintf(buf, PAGE_SIZE, "%s\n", indirect_dev->cache_file_path); +} + +static ssize_t mask_file_path_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + wb_indirect_dev_t *indirect_dev = container_of(kobj, wb_indirect_dev_t, kobj); + + if (!indirect_dev) { + DEBUG_ERROR("mask_file_path_show indirect dev is null.\n"); + return -ENODEV; + } + + mem_clear(buf, PAGE_SIZE); + return snprintf(buf, PAGE_SIZE, "%s\n", indirect_dev->mask_file_path); +} + +static struct kobj_attribute alias_attribute = __ATTR(alias, S_IRUGO, alias_show, NULL); +static struct kobj_attribute type_attribute = __ATTR(type, S_IRUGO, type_show, NULL); +static struct kobj_attribute info_attribute = __ATTR(info, S_IRUGO, info_show, NULL); +static struct kobj_attribute status_attribute = __ATTR(status, S_IRUGO | S_IWUSR, status_show, status_store); +static struct kobj_attribute seu_status_attribute = __ATTR(seu_status, S_IRUGO, status_seu_show, NULL); +static struct kobj_attribute selftest_status_attribute = __ATTR(selftest_status, S_IRUGO, status_selftest_show, NULL); +static struct kobj_attribute scratch_status_attribute = __ATTR(scratch_status, S_IRUGO, status_scratch_show, NULL); +static struct kobj_attribute cram_status_attribute = __ATTR(cram_status, S_IRUGO, status_cram_show, NULL); +static struct kobj_attribute file_cache_rd_attribute = __ATTR(file_cache_rd, S_IRUGO | S_IWUSR, file_cache_rd_show, file_cache_rd_store); +static struct kobj_attribute file_cache_wr_attribute = __ATTR(file_cache_wr, S_IRUGO | S_IWUSR, file_cache_wr_show, file_cache_wr_store); +static struct kobj_attribute cache_file_path_attribute = __ATTR(cache_file_path, S_IRUGO, cache_file_path_show, NULL); +static struct kobj_attribute mask_file_path_attribute = __ATTR(mask_file_path, S_IRUGO, mask_file_path_show, NULL); + +static struct attribute *indirect_dev_attrs[] = { + &alias_attribute.attr, + &type_attribute.attr, + &info_attribute.attr, + &status_attribute.attr, + &file_cache_rd_attribute.attr, + &file_cache_wr_attribute.attr, + &cache_file_path_attribute.attr, + &mask_file_path_attribute.attr, + &seu_status_attribute.attr, + &selftest_status_attribute.attr, + &scratch_status_attribute.attr, + &cram_status_attribute.attr, + NULL, +}; + +static struct attribute_group indirect_dev_attr_group = { + .attrs = indirect_dev_attrs, +}; + +static int of_indirect_dev_config_init(struct platform_device *pdev, struct indirect_dev_info *indirect_dev) +{ + int i, ret; + + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "dev_name", &indirect_dev->name); + ret += of_property_read_string(pdev->dev.of_node, "logic_dev_name", &indirect_dev->logic_dev_name); + ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &indirect_dev->addr_low); + ret += of_property_read_u32(pdev->dev.of_node, "data_bus_width", &indirect_dev->data_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &indirect_dev->addr_high); + ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &indirect_dev->wr_data); + ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &indirect_dev->rd_data); + ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &indirect_dev->opt_ctl); + ret += of_property_read_u32(pdev->dev.of_node, "indirect_len", &indirect_dev->indirect_len); + ret += of_property_read_u32(pdev->dev.of_node, "logic_func_mode", &indirect_dev->logic_func_mode); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + + if (of_property_read_string(pdev->dev.of_node, "dev_alias", &indirect_dev->alias)) { + indirect_dev->alias = indirect_dev->name; + } + + if (indirect_dev->data_bus_width == 0) { + dev_err(&pdev->dev, "Invalid data_bus_width: %u\n", indirect_dev->data_bus_width); + return -EINVAL; + } + + if (of_property_read_u32(pdev->dev.of_node, "lock_mode", &indirect_dev->lock_mode)) { + /* lock_mode can not set, default use spin lock */ + indirect_dev->lock_mode = WB_SPIN_LOCK_MODE; + } + + if ((indirect_dev->lock_mode != WB_SPIN_LOCK_MODE) + && (indirect_dev->lock_mode != WB_MUTEX_LOCK_MODE)) { + dev_err(&pdev->dev, "Invalid lock_mode: %u\n", indirect_dev->lock_mode); + return -EINVAL; + } + + ret = of_dev_status_check_config_init(&pdev->dev, &indirect_dev->status_check, indirect_dev->data_bus_width, + indirect_device_func_read, indirect_device_func_write, indirect_dev->name); + if (ret != 0) { + dev_err(&pdev->dev, "status_check_config_init fail: %d\n", ret); + return -EINVAL; + } + + ret = of_property_read_u32(pdev->dev.of_node, "log_num", &(indirect_dev->log_node.log_num)); + if (ret == 0) { + if ((indirect_dev->log_node.log_num > BSP_KEY_DEVICE_NUM_MAX) || (indirect_dev->log_node.log_num == 0)) { + dev_err(&pdev->dev, "Invalid log_num: %u\n", indirect_dev->log_node.log_num); + return -EINVAL; + } + ret = of_property_read_u32_array(pdev->dev.of_node, "log_index", indirect_dev->log_node.log_index, indirect_dev->log_node.log_num); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get log_index config, ret: %d\n", ret); + return -EINVAL; + } + for (i = 0; i < indirect_dev->log_node.log_num; i++) { + DEBUG_VERBOSE("log_index[%d] address = 0x%x\n", i, indirect_dev->log_node.log_index[i]); + } + } else { + DEBUG_VERBOSE("Don't support bsp key record.\n"); + indirect_dev->log_node.log_num = 0; + } + + DEBUG_VERBOSE("dev_name: %s, dev_alias: %s, logic_dev_name: %s, indirect_len: 0x%x, data_bus_width: %u, logic_func_mode: %d\n", + indirect_dev->name, indirect_dev->alias, indirect_dev->logic_dev_name, indirect_dev->indirect_len, + indirect_dev->data_bus_width, indirect_dev->logic_func_mode); + DEBUG_VERBOSE("wr_data: 0x%x, rd_data: 0x%x, addr_low: 0x%x, addr_high: 0x%x, opt_ctl: 0x%x, lock_mode: %u\n", + indirect_dev->wr_data, indirect_dev->rd_data, indirect_dev->addr_low, + indirect_dev->addr_high, indirect_dev->opt_ctl, indirect_dev->lock_mode); + return 0; +} + +static int indirect_dev_config_init(struct platform_device *pdev, struct indirect_dev_info *indirect_dev) +{ + int i; + indirect_dev_device_t *indirect_dev_device; + int ret; + + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + + indirect_dev_device = pdev->dev.platform_data; + indirect_dev->name = indirect_dev_device->dev_name; + indirect_dev->logic_dev_name = indirect_dev_device->logic_dev_name; + indirect_dev->data_bus_width = indirect_dev_device->data_bus_width; + indirect_dev->wr_data = indirect_dev_device->wr_data; + indirect_dev->addr_low = indirect_dev_device->addr_low; + indirect_dev->addr_high = indirect_dev_device->addr_high; + indirect_dev->rd_data = indirect_dev_device->rd_data; + indirect_dev->opt_ctl = indirect_dev_device->opt_ctl; + indirect_dev->indirect_len = indirect_dev_device->indirect_len; + indirect_dev->logic_func_mode = indirect_dev_device->logic_func_mode; + indirect_dev->lock_mode = indirect_dev_device->lock_mode; + if (strlen(indirect_dev_device->dev_alias) == 0) { + indirect_dev->alias = indirect_dev->name; + } else { + indirect_dev->alias = indirect_dev_device->dev_alias; + } + + if (indirect_dev->data_bus_width == 0) { + dev_err(&pdev->dev, "Invalid data_bus_width: %u\n", indirect_dev->data_bus_width); + return -EINVAL; + } + + if (indirect_dev->lock_mode == 0) { + /* lock_mode can not set, default use spin lock */ + indirect_dev->lock_mode = WB_SPIN_LOCK_MODE; + } + + if ((indirect_dev->lock_mode != WB_SPIN_LOCK_MODE) + && (indirect_dev->lock_mode != WB_MUTEX_LOCK_MODE)) { + dev_err(&pdev->dev, "Invalid lock_mode: %u\n", indirect_dev->lock_mode); + return -EINVAL; + } + + ret = platform_dev_status_check_config_init(&pdev->dev, &indirect_dev->status_check, indirect_dev->data_bus_width, &indirect_dev_device->status_check, + indirect_device_func_read, indirect_device_func_write, indirect_dev->name); + if (ret != 0) { + dev_err(&pdev->dev, "platform status_check_config_init fail: %d\n", ret); + return -EINVAL; + } + + indirect_dev->log_node.log_num = indirect_dev_device->log_num; + if (indirect_dev->log_node.log_num != 0) { + if (indirect_dev->log_node.log_num > BSP_KEY_DEVICE_NUM_MAX) { + dev_err(&pdev->dev, "Invalid log_num: %u\n", indirect_dev->log_node.log_num); + return -EINVAL; + } + for (i = 0; i < indirect_dev->log_node.log_num; i++) { + indirect_dev->log_node.log_index[i] = indirect_dev_device->log_index[i]; + DEBUG_VERBOSE("log_index[%d] address = 0x%x\n", i, indirect_dev->log_node.log_index[i]); + } + } else { + DEBUG_VERBOSE("Don't support bsp key record.\n"); + } + + DEBUG_VERBOSE("dev_name: %s, dev_alias: %s, logic_dev_name: %s, indirect_len: 0x%x, data_bus_width: %u, logic_func_mode: %d\n", + indirect_dev->name, indirect_dev->alias, indirect_dev->logic_dev_name, indirect_dev->indirect_len, + indirect_dev->data_bus_width, indirect_dev->logic_func_mode); + DEBUG_VERBOSE("wr_data: 0x%x, rd_data: 0x%x, addr_low: 0x%x, addr_high: 0x%x, opt_ctl: 0x%x, lock_mode: %u\n", + indirect_dev->wr_data, indirect_dev->rd_data, indirect_dev->addr_low, + indirect_dev->addr_high, indirect_dev->opt_ctl, indirect_dev->lock_mode); + return 0; +} static int wb_indirect_dev_probe(struct platform_device *pdev) { int ret; struct indirect_dev_info *indirect_dev; struct miscdevice *misc; - indirect_dev_device_t *indirect_dev_device; - INDIRECT_DEV_DEBUG("wb_indirect_dev_probe\n"); + DEBUG_VERBOSE("wb_indirect_dev_probe\n"); indirect_dev = devm_kzalloc(&pdev->dev, sizeof(struct indirect_dev_info), GFP_KERNEL); if (!indirect_dev) { @@ -706,137 +1204,120 @@ static int wb_indirect_dev_probe(struct platform_device *pdev) return -ENOMEM; } - platform_set_drvdata(pdev, indirect_dev); - indirect_dev->dev = &pdev->dev; - if (pdev->dev.of_node) { - ret = 0; - ret += of_property_read_string(pdev->dev.of_node, "dev_name", &indirect_dev->name); - ret += of_property_read_string(pdev->dev.of_node, "logic_dev_name", &indirect_dev->logic_dev_name); - ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &indirect_dev->addr_low); - ret += of_property_read_u32(pdev->dev.of_node, "data_bus_width", &indirect_dev->data_bus_width); - ret += of_property_read_u32(pdev->dev.of_node, "addr_bus_width", &indirect_dev->addr_bus_width); - ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &indirect_dev->addr_high); - ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &indirect_dev->wr_data); - ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &indirect_dev->rd_data); - ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &indirect_dev->opt_ctl); - ret += of_property_read_u32(pdev->dev.of_node, "indirect_len", &indirect_dev->indirect_len); - ret += of_property_read_u32(pdev->dev.of_node, "logic_func_mode", &indirect_dev->logic_func_mode); - - if (of_property_read_u32(pdev->dev.of_node, "wr_data_width", &indirect_dev->wr_data_width)) { - /* dts have no wr_data_width,set default 1 */ - indirect_dev->wr_data_width = WIDTH_1Byte; - } - if (of_property_read_u32(pdev->dev.of_node, "rd_data_width", &indirect_dev->rd_data_width)) { - /* dts have no rd_data_width,set default 1 */ - indirect_dev->rd_data_width = WIDTH_1Byte; - } - if (ret != 0) { - dev_err(&pdev->dev, "dts config error.ret:%d.\n", ret); - return -ENXIO; - } + ret = of_indirect_dev_config_init(pdev, indirect_dev); } else { - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "Failed to get platform data config.\n"); - return -ENXIO; - } - indirect_dev_device = pdev->dev.platform_data; - indirect_dev->name = indirect_dev_device->dev_name; - indirect_dev->logic_dev_name = indirect_dev_device->logic_dev_name; - indirect_dev->data_bus_width = indirect_dev_device->data_bus_width; - indirect_dev->addr_bus_width = indirect_dev_device->addr_bus_width; - indirect_dev->wr_data = indirect_dev_device->wr_data; - indirect_dev->wr_data_width = indirect_dev_device->wr_data_width; - indirect_dev->addr_low = indirect_dev_device->addr_low; - indirect_dev->addr_high = indirect_dev_device->addr_high; - indirect_dev->rd_data = indirect_dev_device->rd_data; - indirect_dev->rd_data_width = indirect_dev_device->rd_data_width; - indirect_dev->opt_ctl = indirect_dev_device->opt_ctl; - indirect_dev->indirect_len = indirect_dev_device->indirect_len; - indirect_dev->logic_func_mode = indirect_dev_device->logic_func_mode; - } - - switch (indirect_dev->logic_func_mode) { - case SYMBOL_I2C_DEV_MODE: - indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_write"); - indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_read"); - break; - case SYMBOL_SPI_DEV_MODE: - indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_write"); - indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_read"); - break; - case SYMBOL_IO_DEV_MODE: - indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_write"); - indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_read"); - break; - case SYMBOL_PCIE_DEV_MODE: - indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_write"); - indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_read"); - break; - case FILE_MODE: - indirect_dev->write_intf_addr = (unsigned long)wb_dev_file_write; - indirect_dev->read_intf_addr = (unsigned long)wb_dev_file_read; - break; - default: - dev_err(&pdev->dev, "func mode %d don't support.\n", indirect_dev->logic_func_mode); - return -EINVAL; + ret = indirect_dev_config_init(pdev, indirect_dev); + } + + if (ret < 0) { + return ret; + } + + ret = wb_logic_lock_mode_check(indirect_dev->lock_mode, indirect_dev->logic_func_mode); + if (ret != 0) { + dev_err(&pdev->dev, "Invalid lock mode %u for func mode %u\n", indirect_dev->lock_mode, indirect_dev->logic_func_mode); + return ret; + } + + ret = find_intf_addr(&indirect_dev->write_intf_addr, &indirect_dev->read_intf_addr, indirect_dev->logic_func_mode); + if (ret) { + dev_err(&pdev->dev, "Failed to find_intf_addr func mode %u, ret: %d\n", indirect_dev->logic_func_mode, ret); + return ret; } if (!indirect_dev->write_intf_addr || !indirect_dev->read_intf_addr) { - dev_err(&pdev->dev, "Fail: func mode %u rw symbol undefined.\n", indirect_dev->logic_func_mode); + dev_err(&pdev->dev, "Fail: func mode %u rw symbol undefined\n", indirect_dev->logic_func_mode); return -ENOSYS; } - /* TODO: data_bus_width unuse now, need judge in rd or wr */ - dev_info(&pdev->dev, "register indirect device %s success. logic_dev_name: %s, indirect_len: 0x%x, data_bus_width: 0x%x, dependent dev: 0x%x, wr_data: 0x%x, wr_data_width: %d, \ - rd_data: 0x%x, rd_data_width: %d, addr_low: 0x%x, addr_high: 0x%x, opt_ctl: 0x%x, logic_func_mode: %d\n", indirect_dev->name, indirect_dev->logic_dev_name, indirect_dev->indirect_len, indirect_dev->data_bus_width, \ - indirect_dev->addr_bus_width, indirect_dev->wr_data, indirect_dev->wr_data_width, indirect_dev->rd_data, indirect_dev->rd_data_width, indirect_dev->addr_low, indirect_dev->addr_high,\ - indirect_dev->opt_ctl, indirect_dev->logic_func_mode); + mutex_init(&indirect_dev->update_lock); + mutex_init(&indirect_dev->log_node.file_lock); + + indirect_dev->file_cache_rd = 0; + indirect_dev->file_cache_wr = 0; + snprintf(indirect_dev->cache_file_path, sizeof(indirect_dev->cache_file_path), CACHE_FILE_PATH, indirect_dev->name); + snprintf(indirect_dev->mask_file_path, sizeof(indirect_dev->mask_file_path), MASK_FILE_PATH, indirect_dev->name); + /* creat parent dir by dev name in /sys/logic_dev */ + ret = kobject_init_and_add(&indirect_dev->kobj, &indirect_dev_ktype, logic_dev_kobj, "%s", indirect_dev->name); + if (ret) { + kobject_put(&indirect_dev->kobj); + dev_err(&pdev->dev, "Failed to creat parent dir: %s, ret: %d\n", indirect_dev->name, ret); + return ret; + } + + indirect_dev->sysfs_group = &indirect_dev_attr_group; + ret = sysfs_create_group(&indirect_dev->kobj, indirect_dev->sysfs_group); + if (ret) { + dev_err(&pdev->dev, "Failed to create %s sysfs group, ret: %d\n", indirect_dev->name, ret); + goto remove_parent_kobj; + } + + platform_set_drvdata(pdev, indirect_dev); misc = &indirect_dev->misc; misc->minor = MISC_DYNAMIC_MINOR; misc->name = indirect_dev->name; misc->fops = &indirect_dev_fops; misc->mode = 0666; if (misc_register(misc) != 0) { - dev_err(&pdev->dev, "register %s faild.\n", misc->name); - return -ENXIO; + dev_err(&pdev->dev, "Failed to register %s device\n", misc->name); + ret = -ENXIO; + goto remove_sysfs_group; } - if (misc->minor >= MAX_INDIRECT_DEV_NUM) { - dev_err(&pdev->dev, "minor number beyond the limit! is %d.\n", misc->minor); - misc_deregister(misc); - return -ENXIO; + ret = add_dev_to_g_dev_list(indirect_dev); + if (ret) { + dev_err(&pdev->dev, "Failed to add_dev_to_g_dev_list, ret: %d\n", ret); + goto deregister_misc; + } + + wb_dev_lock_init(indirect_dev); + + dev_info(&pdev->dev, "Register indirect device %s success, logic_dev_name: %s, indirect_len: 0x%x, data_bus_width: %u, logic_func_mode: %u, lock_mode: %u\n", + indirect_dev->name, indirect_dev->logic_dev_name, indirect_dev->indirect_len, + indirect_dev->data_bus_width, indirect_dev->logic_func_mode, indirect_dev->lock_mode); + + ret = wb_logic_check_status_hw_init(&indirect_dev->status_check, indirect_dev->data_bus_width); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to wb_logic_check_status_hw_init, ret: %d\n", ret); } - spin_lock_init(&indirect_dev->indirect_dev_lock); - indirect_dev_arry[misc->minor] = indirect_dev; - dev_info(&pdev->dev, "register indirect device %s success.\n", indirect_dev->name); return 0; +deregister_misc: + misc_deregister(misc); +remove_sysfs_group: + sysfs_remove_group(&indirect_dev->kobj, (const struct attribute_group *)indirect_dev->sysfs_group); +remove_parent_kobj: + kobject_put(&indirect_dev->kobj); + return ret; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) -static int wb_indirect_dev_remove(struct platform_device *pdev) -#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,11,0) static void wb_indirect_dev_remove(struct platform_device *pdev) +#else +static int wb_indirect_dev_remove(struct platform_device *pdev) #endif { - int i; + int minor; + wb_indirect_dev_t *indirect_dev; - for (i = 0; i < MAX_INDIRECT_DEV_NUM; i++) { - if (indirect_dev_arry[i] != NULL) { - if (indirect_dev_arry[i]->dev == &pdev->dev) { - misc_deregister(&indirect_dev_arry[i]->misc); - indirect_dev_arry[i] = NULL; -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) - return 0; -#else - return; -#endif - } - } + indirect_dev = platform_get_drvdata(pdev); + minor = indirect_dev->misc.minor; + + dev_dbg(&pdev->dev, "misc_deregister %s, minor: %d\n", indirect_dev->misc.name, minor); + misc_deregister(&indirect_dev->misc); + remove_dev_from_g_dev_list(minor); + + if (indirect_dev->sysfs_group) { + dev_dbg(&pdev->dev, "Unregister %s indirect_dev sysfs group\n", indirect_dev->name); + sysfs_remove_group(&indirect_dev->kobj, (const struct attribute_group *)indirect_dev->sysfs_group); + kobject_put(&indirect_dev->kobj); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) + + dev_info(&pdev->dev, "Remove %s indirect device success.\n", indirect_dev->name); + platform_set_drvdata(pdev, NULL); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0) return 0; #endif } @@ -858,14 +1339,6 @@ static struct platform_driver wb_indirect_dev_driver = { static int __init wb_indirect_dev_init(void) { - int ret; - - ret = find_kallsyms_lookup_name(); - if (ret < 0) { - INDIRECT_DEV_ERROR("find kallsyms_lookup_name failed\n"); - return -ENXIO; - } - INDIRECT_DEV_DEBUG("find kallsyms_lookup_name ok\n"); return platform_driver_register(&wb_indirect_dev_driver); } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h index bc2570f527..48df82fcb0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h @@ -1,5 +1,5 @@ /* - * A header definition for wb_indirect_dev driver + * An wb_indirect_dev driver for indirect adapter device function * * Copyright (C) 2024 Micas Networks Inc. * @@ -20,35 +20,25 @@ #ifndef __WB_INDIRECT_DEV_H__ #define __WB_INDIRECT_DEV_H__ - -#include - -#define DEV_NAME_LEN (64) -#define WIDTH_1Byte (1) -#define WIDTH_2Byte (2) -#define WIDTH_4Byte (4) -#define MAX_RW_LEN (256) - -#define mem_clear(data, size) memset((data), 0, (size)) - -typedef int (*device_func_write)(const char *, uint32_t, uint8_t *, size_t); -typedef int (*device_func_read)(const char *, uint32_t, uint8_t *, size_t ); +#include typedef struct indirect_dev_device_s { - char dev_name[DEV_NAME_LEN]; - char logic_dev_name[DEV_NAME_LEN]; + char dev_name[MAX_NAME_SIZE]; + char dev_alias[MAX_NAME_SIZE]; + char logic_dev_name[MAX_NAME_SIZE]; uint32_t data_bus_width; - uint32_t addr_bus_width; uint32_t indirect_len; uint32_t wr_data; - uint32_t wr_data_width; uint32_t addr_low; uint32_t addr_high; uint32_t rd_data; - uint32_t rd_data_width; uint32_t opt_ctl; uint32_t logic_func_mode; + uint32_t lock_mode; int device_flag; + uint32_t log_num; /* The number of write record registers is 64 at most */ + uint32_t log_index[BSP_KEY_DEVICE_NUM_MAX]; /* Write record register address = (base_addr & 0xFFFF) | (len << 16) */ + device_status_check_t status_check; } indirect_dev_device_t; #endif /* __WB_INDIRECT_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_logic_dev_common.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_logic_dev_common.c new file mode 100644 index 0000000000..117ed39185 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_logic_dev_common.c @@ -0,0 +1,2570 @@ +/* + * wb_logic_dev_common.c + * ko provide universal methods to logic_dev module + */ + +#include +#include + +#define LOGIC_DEV_DUMP_LINE_BYTES (16) + +/* Use the wb_bsp_kernel_debug header file must define debug variable */ +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +#define LOGIC_DEV_INFO(fmt, args...) do { \ + printk(KERN_INFO "[LOGIC_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ +} while (0) + +static int noop_pre(struct kprobe *p, struct pt_regs *regs) { return 0; } +static struct kprobe kp = { + .symbol_name = "kallsyms_lookup_name", +}; +unsigned long (*kallsyms_lookup_name_fun)(const char *name) = NULL; + +struct kobject *logic_dev_kobj; + +/* Call kprobe to find the address location of kallsyms_lookup_name */ +static int find_kallsyms_lookup_name(void) +{ + int ret = -1; + + kp.pre_handler = noop_pre; + ret = register_kprobe(&kp); + if (ret < 0) { + DEBUG_ERROR("register_kprobe failed, error:%d\n", ret); + return ret; + } + DEBUG_INFO("kallsyms_lookup_name addr: %p\n", kp.addr); + kallsyms_lookup_name_fun = (void*)kp.addr; + unregister_kprobe(&kp); + + return ret; +} + +EXPORT_SYMBOL_GPL(kallsyms_lookup_name_fun); +EXPORT_SYMBOL_GPL(logic_dev_kobj); + +static int wb_bsp_log_file_backup(char *src_path, struct file *src_fp, int src_file_size) +{ + int ret; + struct file *dst_fp; + char dst_path[BSP_LOG_DEV_NAME_MAX_LEN]; + char *buffer; + ssize_t bytes_read, bytes_written; + loff_t src_offset, dst_offset; + + buffer = kzalloc(src_file_size, GFP_KERNEL); + if (!buffer) { + DEBUG_ERROR("Failed to allocate memory for buffer size %d\n", src_file_size); + return -ENOMEM; + } + + mem_clear(dst_path, sizeof(dst_path)); + snprintf(dst_path, sizeof(dst_path), "%s_bak", src_path); + dst_fp = filp_open(dst_path, O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); + if (IS_ERR(dst_fp)) { + DEBUG_ERROR("Open %s failed, errno = %ld\n", dst_path, -PTR_ERR(dst_fp)); + ret = PTR_ERR(dst_fp); + goto out_free_buffer; + } + + /* read origin file */ + src_offset = 0; + bytes_read = kernel_read(src_fp, buffer, src_file_size, &src_offset); + if (bytes_read < 0) { + DEBUG_ERROR("Read %s failed, src_file_size: %d, ret: %zu\n", src_path, src_file_size, bytes_read); + ret = bytes_read; + goto out_close_dst; + } + /* write to backup file */ + dst_offset = 0; + bytes_written = kernel_write(dst_fp, buffer, bytes_read, &dst_offset); + if (bytes_written < 0) { + DEBUG_ERROR("Write %s failed, src_file_size: %d, ret: %zu\n", src_path, src_file_size, bytes_written); + ret = bytes_written; + goto out_close_dst; + } + + ret = 0; + (void)vfs_fsync(dst_fp, 1); + DEBUG_VERBOSE("Backup %s to %s success, src_file_size: %d\n", src_path, dst_path, src_file_size); +out_close_dst: + filp_close(dst_fp, NULL); +out_free_buffer: + kfree(buffer); + return ret; +} + +/** + * wb_bsp_log_file_without_ts -- Log a message without generating a timestamp. + * @log: The log message to be recorded. + * + * This function is used in kernel threads. + */ +static void wb_bsp_log_file_without_ts(char *path, int file_max_size, char *log, int size) +{ + struct file *fp; + ssize_t ret; + loff_t tmp_pos; + struct inode *inode; + + fp = filp_open(path, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); + if (IS_ERR(fp)) { + DEBUG_ERROR("open %s failed, errno = %ld\n", path, -PTR_ERR(fp)); + return; + } + + /* get file size */ + inode = fp->f_inode; + tmp_pos = i_size_read(inode); + + DEBUG_VERBOSE("%s file size: %lld, write len: %d, file_max_size: %d\n", path, tmp_pos, size, file_max_size); + + if (tmp_pos + size >= file_max_size) { + DEBUG_VERBOSE("%s file write file offset: %lld, write len: %d, exceed max file size: %d, backup file\n", + path, tmp_pos, size, file_max_size); + ret = wb_bsp_log_file_backup(path, fp, tmp_pos); + if (ret == 0) { + DEBUG_VERBOSE("Backup %s success, truncate the file and start writing from the beginning\n", path); + (void)filp_close(fp, NULL); + /* Reopen file (truncate) */ + fp = filp_open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRWXG | S_IRWXO); + if (IS_ERR(fp)) { + DEBUG_ERROR("open %s failed, errno = %ld\n", path, -PTR_ERR(fp)); + return; + } + } else { + DEBUG_ERROR("Backup %s failed, ret: %zu, do not truncate the file, write it from the beginning\n", path, ret); + } + tmp_pos = 0; + } + + ret = kernel_write(fp, log, size, &tmp_pos); + if (ret < 0) { + DEBUG_ERROR("Write %s failed, offset: %lld, size: %d, ret: %zu\n", path, tmp_pos, size, ret); + goto finish; + } + + vfs_fsync(fp, 1); + DEBUG_VERBOSE("Write %s success, write len: %d, pos: %lld\n", path, size,tmp_pos); +finish: + (void)filp_close(fp, NULL); + return; +} + +/** + * wb_bsp_create_timestamp -- Generate a timestamp. + * @ts: Output parameter to store the generated timestamp string. + * @size: The size of the ts buffer. + * + * return: The length of the timestamp string stored in ts. + */ +static int wb_bsp_create_timestamp(char *buf, int size) +{ + int offset; + struct tm tm; + struct timespec64 ts; + + /* get timestamp_sec */ + mem_clear(&tm, sizeof(tm)); + mem_clear(&ts, sizeof(ts)); + ktime_get_real_ts64(&ts); + time64_to_tm(ts.tv_sec, 0, &tm); + mem_clear(buf, size); + offset = snprintf(buf, size, "%-4ld-%02d-%02d %02d:%02d:%02d\n", tm.tm_year + 1900, + tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + return offset; +} + +/** + * wb_bsp_log_file_with_ts -- Log a message with an automatically generated timestamp. + * @log: The log message to record. + * + * To be used within a kernel thread. + */ +static void wb_bsp_log_file_with_ts(char *path, int file_max_size, char *log, struct mutex *file_lock) +{ + char ts[BSP_LOG_TS_BUFF_SIZE]; + char wr_buf[BSP_KEY_DEVICE_LOG_SIZE+BSP_LOG_TS_BUFF_SIZE]; + + mem_clear(ts, sizeof(ts)); + mem_clear(wr_buf, sizeof(wr_buf)); + (void)wb_bsp_create_timestamp(ts, BSP_LOG_TS_BUFF_SIZE); + snprintf(wr_buf, sizeof(wr_buf), "%s%s", ts, log); + mutex_lock(file_lock); + wb_bsp_log_file_without_ts(path, file_max_size, wr_buf, strlen(wr_buf)); + mutex_unlock(file_lock); + return; +} + +int wb_bsp_key_device_log(char *dev_name, char *log_name, int log_size, + wb_bsp_key_device_log_node_t *log_node, uint32_t offset, uint8_t *buf, size_t size) +{ + int i, j, addr, len, flags, log_len, tmp_offset; + char log[BSP_KEY_DEVICE_LOG_SIZE]; + + if (dev_name == NULL || log_name == NULL || log_node == NULL || buf == NULL || + size <= 0 || log_size <= 0) { + DEBUG_ERROR("Invalid param! dev_name = %p, log_name = %p, log_node = %p, buf = %p, size = %zu, offset = 0x%x, log_size=%d\n", + dev_name, log_name, log_node, buf, size, offset, log_size); + return -EINVAL; + } + + DEBUG_VERBOSE("log_name: %s, write type: %s, offset = 0x%02x size = %zu,\n", log_name, dev_name, offset, size); + mem_clear(log, BSP_KEY_DEVICE_LOG_SIZE); + log_len = 0; + log_len += snprintf(log + log_len, BSP_KEY_DEVICE_LOG_SIZE - log_len, "%s: write register - value:\n", dev_name); + /* Check if the address is the key register to be logged */ + flags = 0; + for (j = 0; j < size; j++) { + for (i = 0; i < log_node->log_num; i++) { + addr = BSP_KEY_DEV_INDEX_TO_ADDR(log_node->log_index[i]); + len = BSP_KEY_DEV_INDEX_TO_SIZE(log_node->log_index[i]); + DEBUG_VERBOSE("log_reg[%d] addr = 0x%02x, len = 0x%02x\n", i, addr, len); + /** + *If the next log entry exceeds the buffer length, it will be written to the file first. + * The magic number is related to the log format '0x%04x:0x%02x'. + */ + if (log_len + 13 > BSP_KEY_DEVICE_LOG_SIZE) { + /* Interrupt and crash handling processes output directly using printk without writing to a file. */ + if (unlikely(in_interrupt() || oops_in_progress)) { + /* Data concatenation already includes line breaks; no additional line breaks are added here */ + printk("%s:%s", log_name, log); + } else { + wb_bsp_log_file_with_ts(log_name, log_size, log, &log_node->file_lock); + } + mem_clear(log, BSP_KEY_DEVICE_LOG_SIZE); + log_len = 0; + } + tmp_offset = offset + j; + if ((tmp_offset >= addr) && (tmp_offset < addr + len)) { + log_len += snprintf(log + log_len, BSP_KEY_DEVICE_LOG_SIZE - log_len, "0x%04x:0x%02x\n", + tmp_offset, buf[j]); + flags = 1; + break; + } + } + } + + if (flags == 0) { + DEBUG_VERBOSE("Key reg can not match!\n"); + return 0; + } + + /* Interrupt and crash handling processes output directly using printk without writing to a file. */ + if (unlikely(in_interrupt() || oops_in_progress)) { + /* Data concatenation already includes line breaks; no additional line breaks are added here */ + printk("%s", log); + } else { + wb_bsp_log_file_with_ts(log_name, log_size, log, &log_node->file_lock); + } + + return 0; +} +EXPORT_SYMBOL_GPL(wb_bsp_key_device_log); + +static int check_mode_data_process(uint32_t check_mode, uint8_t *data, int data_len) +{ + int ret; + int i; + + ret = 0; + switch (check_mode) { + case WB_LOGIC_NORMAL: + break; + case WB_LOGIC_NAGATIVE_MODE: + for (i = 0; i < data_len; i++) { + data[i] = ~data[i]; + } + break; + default: + return -EINVAL; + } + + return ret; +} + +int dev_rw_check(uint8_t *rd_buf, uint8_t *wr_buf, uint32_t len, uint32_t type, uint32_t check_mode) +{ + int i; + int ret; + + if (rd_buf == NULL || wr_buf == NULL) { + DEBUG_ERROR("Error: buf is NULL\n"); + return -EINVAL; + } + + if ((len == 0) ||(len > MAX_DATA_WIDTH)) { + DEBUG_ERROR("Invalid len: %u.\n", len); + return -EINVAL; + } + + if (check_mode >= WB_LOGIC_SUPPORT_CHECK_MODE_MAX) { + DEBUG_ERROR("Invalid check_mode: 0x%x.\n", check_mode); + return -EINVAL; + } + + ret = check_mode_data_process(check_mode, rd_buf, len); + if (ret < 0) { + DEBUG_ERROR("check mode check_mode_data_process fail, check_mode: %d, ret:%d.\n", check_mode, ret); + return ret; + } + + switch (type) { + case STATUS_CHECK_SELFTEST: + case STATUS_CHECK_SCRATCH: + case STATUS_CHECK_SEU: + case STATUS_CHECK_CRAM: + if (memcmp(rd_buf, wr_buf, len)) { + DEBUG_ERROR("type: %u, status check result failed.\n", type); + for (i = 0; i < len; i++) { + DEBUG_INFO("rd_buf[%d]: 0x%x, wr_buf[%d]: 0x%x\n", + i, rd_buf[i], i, wr_buf[i]); + } + return -EIO; + } + break; + default: + DEBUG_ERROR("Failed: status check type:%d not support.\n", type); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(dev_rw_check); + +void logic_dev_dump_data(const char *dev_name, uint32_t offset, u8 *val, size_t count, bool read_flag) +{ + int i; + uint8_t buf[DEBUG_BUF_MAX_LEN]; + uint8_t *point; + + if ((dev_name == NULL) || (val == NULL) || (count <= 0)) { + DEBUG_ERROR("Invalid param, dev_name: %p, val buf: %p, count: %zu\n", dev_name, val, count); + return; + } + + mem_clear(buf, sizeof(buf)); + point = buf; + printk(KERN_INFO "%s %s, offset=0x%x, count=%zu, data:\n", dev_name, read_flag ? "read":"write", offset, count); + for (i = 0; i < count; i++) { + snprintf(point, DEBUG_BUF_MAX_LEN - (point - buf), "0x%02x ", val[i]); + /* Format length. */ + point += 5; + if (((i + 1) % 16) == 0) { + printk(KERN_INFO "%s\n", buf); + point = buf; + mem_clear(buf, sizeof(buf)); + } + } + + if (point != buf) { + printk(KERN_INFO "%s\n", buf); + } + + return; +} +EXPORT_SYMBOL_GPL(logic_dev_dump_data); + +static int wb_dev_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + DEBUG_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + ret = 0; + tmp_pos = (loff_t)pos; + ret = kernel_write(filp, (void*)val, size, &tmp_pos); + if (ret < 0) { + DEBUG_ERROR("write kernel_write failed, ret=%d\r\n", ret); + goto exit; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_dev_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + DEBUG_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + ret = 0; + tmp_pos = (loff_t)pos; + ret = kernel_read(filp, val, size, &tmp_pos); + if (ret < 0) { + DEBUG_ERROR("read kernel_read failed, ret=%d\r\n", ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +int find_intf_addr(unsigned long *write_intf_addr, unsigned long *read_intf_addr, uint32_t mode) +{ + switch (mode) { + case SYMBOL_I2C_DEV_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_read"); + break; + case SYMBOL_SPI_DEV_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_read"); + break; + case SYMBOL_SPI_DEV_ATOMIC_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_atomic_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_atomic_read"); + break; + case SYMBOL_IO_DEV_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_read"); + break; + case SYMBOL_PCIE_DEV_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_read"); + break; + case SYMBOL_INDIRECT_DEV_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("indirect_device_func_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("indirect_device_func_read"); + break; + case SYMBOL_PLATFORM_I2C_DEV_MODE: + *write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("platform_i2c_device_func_write"); + *read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("platform_i2c_device_func_read"); + break; + case FILE_MODE: + *write_intf_addr = (unsigned long)wb_dev_file_write; + *read_intf_addr = (unsigned long)wb_dev_file_read; + break; + default: + DEBUG_ERROR("func mode %d don't support.\n", mode); + return -EINVAL; + } + + if (!*write_intf_addr || !*read_intf_addr) { + DEBUG_ERROR("Fail: func mode %u rw symbol undefined\n", mode); + return -ENOSYS; + } + + return 0; +} +EXPORT_SYMBOL_GPL(find_intf_addr); + +int find_cs_intf_addr(unsigned long *cs_enable_intf_addr, unsigned long *cs_disable_intf_addr) +{ + *cs_enable_intf_addr = (unsigned long)kallsyms_lookup_name_fun("chip_select_enable"); + *cs_disable_intf_addr = (unsigned long)kallsyms_lookup_name_fun("chip_select_disable"); + + if (!*cs_enable_intf_addr || !*cs_disable_intf_addr) { + DEBUG_ERROR("Fail: cs enable or disable symbol undefined\n"); + return -ENOSYS; + } + + return 0; +} +EXPORT_SYMBOL_GPL(find_cs_intf_addr); + + +static int logic_dev_read(logic_dev_dump_t *dump_logic_dev, uint32_t pos, uint8_t *val, size_t size) +{ + device_func_read pfunc; + + if (!dump_logic_dev->logic_dev_read_intf_addr) { + return -ENOSYS; + } + + pfunc = (device_func_read)dump_logic_dev->logic_dev_read_intf_addr; + return pfunc(dump_logic_dev->logic_dev_name, pos, val, size); +} + +static void logic_dev_dump_buf_seg(struct device *dev, uint32_t base, const uint8_t *buf, size_t bytes) +{ + int i, j, pos; + char print_line[MAX_RW_LEN]; + + for (i = 0; i < bytes; i += LOGIC_DEV_DUMP_LINE_BYTES) { + pos = snprintf(print_line, sizeof(print_line), "0x%04x:", base + i); + for (j = 0; j < LOGIC_DEV_DUMP_LINE_BYTES && (i + j) < bytes; j++) { + pos += snprintf(print_line + pos, sizeof(print_line) - pos, " %02x", buf[i + j]); + } + dev_info(dev, "%s\n", print_line); + } +} + +void logic_dev_dump_regs(logic_dev_dump_info_t *dump_info, struct device *dev, const char *log_tag) +{ + uint8_t dump_buf[LOGIC_DEV_DUMP_LINE_BYTES]; + uint32_t addr, bytes, i; + int ret; + logic_dev_dump_t *dump_logic_dev; + const char *tag; + + if (!dump_info || !dev) { + return; + } + + tag = log_tag ? log_tag : "logic_dev"; + for (i = 0; i < dump_info->dump_logic_dev_num; i++) { + dump_logic_dev = &dump_info->dump_logic_dev_cfg[i]; + dev_info(dev, + "[%s] :dump logic dev regs, dev:%s, range:[0x%x, 0x%x]\n", + tag, dump_logic_dev->logic_dev_name, + dump_logic_dev->logic_dev_reg_start, dump_logic_dev->logic_dev_reg_end); + + for (addr = dump_logic_dev->logic_dev_reg_start; + addr <= dump_logic_dev->logic_dev_reg_end; + addr += LOGIC_DEV_DUMP_LINE_BYTES) { + bytes = min_t(uint32_t, LOGIC_DEV_DUMP_LINE_BYTES, + dump_logic_dev->logic_dev_reg_end - addr + 1); + mem_clear(dump_buf, sizeof(dump_buf)); + + ret = logic_dev_read(dump_logic_dev, addr, dump_buf, bytes); + if (ret < 0) { + dev_err(dev, + "read logic dev reg failed, dev:%s, addr:0x%x, len:%u, ret:%d\n", + dump_logic_dev->logic_dev_name, addr, bytes, ret); + break; + } + logic_dev_dump_buf_seg(dev, addr, dump_buf, bytes); + } + dev_info(dev, "===== %s: End dump from logic dev regs =====\n", tag); + } +} +EXPORT_SYMBOL_GPL(logic_dev_dump_regs); + +static int logic_dev_dump_init(logic_dev_dump_info_t *dump_info, struct device *dev, uint32_t cfg_index, + const logic_dev_dump_cfg_t *dump_logic_dev_cfg) +{ + int ret; + logic_dev_dump_t *dump_logic_dev; + + if (!dump_info || !dev || !dump_logic_dev_cfg) { + dev_err(dev, "invalid param, dump_info:%p, dev:%p, dump_logic_dev_cfg:%p\n", + dump_info, dev, dump_logic_dev_cfg); + return -EINVAL; + } + + if (!dump_logic_dev_cfg->logic_dev_name[0]) { + dev_err(dev, "invalid logic dev dump name, index:%u\n", cfg_index); + return -EINVAL; + } + + if (cfg_index >= LOGIC_DEV_DUMP_MAX_NUM) { + dev_err(dev, "logic dev dump index %u out of range, max:%u\n", + cfg_index, LOGIC_DEV_DUMP_MAX_NUM); + return -EINVAL; + } + + if (dump_logic_dev_cfg->logic_dev_reg_end < dump_logic_dev_cfg->logic_dev_reg_start) { + dev_err(dev, + "invalid logic dev dump range, dev:%s, start:0x%x, end:0x%x\n", + dump_logic_dev_cfg->logic_dev_name, + dump_logic_dev_cfg->logic_dev_reg_start, + dump_logic_dev_cfg->logic_dev_reg_end); + return -EINVAL; + } + + dump_logic_dev = &dump_info->dump_logic_dev_cfg[cfg_index]; + dump_logic_dev->logic_dev_name = kstrdup_const(dump_logic_dev_cfg->logic_dev_name, GFP_KERNEL); + if (!dump_logic_dev->logic_dev_name) { + dev_err(dev, "alloc logic dev dump name failed, dev:%s\n", + dump_logic_dev_cfg->logic_dev_name); + return -ENOMEM; + } + dump_logic_dev->logic_dev_func_mode = dump_logic_dev_cfg->logic_dev_func_mode; + dump_logic_dev->logic_dev_reg_start = dump_logic_dev_cfg->logic_dev_reg_start; + dump_logic_dev->logic_dev_reg_end = dump_logic_dev_cfg->logic_dev_reg_end; + + ret = find_intf_addr(&dump_logic_dev->logic_dev_write_intf_addr, + &dump_logic_dev->logic_dev_read_intf_addr, dump_logic_dev->logic_dev_func_mode); + if (ret) { + dev_err(dev, + "find_intf_addr for logic dev dump failed, mode:%u, ret:%d\n", + dump_logic_dev->logic_dev_func_mode, ret); + return ret; + } + + if (!dump_logic_dev->logic_dev_write_intf_addr || !dump_logic_dev->logic_dev_read_intf_addr) { + dev_err(dev, + "logic dev dump rw symbol undefined, mode:%u\n", + dump_logic_dev->logic_dev_func_mode); + return -ENOSYS; + } + + LOGIC_DEV_INFO("logic dev dump init success, index:%u, dev:%s, mode:%u, range:[0x%x, 0x%x]\n", + cfg_index, dump_logic_dev->logic_dev_name, dump_logic_dev->logic_dev_func_mode, + dump_logic_dev->logic_dev_reg_start, dump_logic_dev->logic_dev_reg_end); + + return 0; +} + +int logic_dev_dump_of_node_init(logic_dev_dump_info_t *dump_info, struct device *dev) +{ + int ret; + int rv; + int dump_logic_dev_name_num; + uint32_t i; + uint32_t dump_logic_dev_num; + uint32_t dump_logic_dev_func_mode; + uint32_t dump_logic_dev_reg_start; + uint32_t dump_logic_dev_reg_end; + const char *dump_logic_dev_name; + logic_dev_dump_cfg_t dump_logic_dev_cfg; + + if (!dump_info || !dev || !dev->of_node) { + dev_err(dev, "invalid param, dump_info:%p, dev:%p, of_node:%p\n", + dump_info, dev, dev ? dev->of_node : NULL); + return -EINVAL; + } + + dump_logic_dev_name_num = of_property_count_strings(dev->of_node, "dump_logic_dev_name"); + if (dump_logic_dev_name_num <= 0) { + return 0; + } + + if (dump_logic_dev_name_num > LOGIC_DEV_DUMP_MAX_NUM) { + dev_err(dev, "invalid logic dev dump num:%d, max:%u\n", + dump_logic_dev_name_num, LOGIC_DEV_DUMP_MAX_NUM); + return -EINVAL; + } + + dump_logic_dev_num = dump_logic_dev_name_num; + for (i = 0; i < dump_logic_dev_num; i++) { + rv = of_property_read_string_index(dev->of_node, "dump_logic_dev_name", i, &dump_logic_dev_name); + if (rv != 0) { + dev_err(dev, "dump_logic_dev_name[%u] read failed, rv:%d\n", i, rv); + return rv; + } + + if (!dump_logic_dev_name || !dump_logic_dev_name[0]) { + dev_err(dev, "dump_logic_dev_name[%u] is empty\n", i); + return -EINVAL; + } + + rv = of_property_read_u32_index(dev->of_node, "dump_logic_dev_func_mode", i, + &dump_logic_dev_func_mode); + if (rv != 0) { + dev_err(dev, + "dump_logic_dev_name[%u] configured but dump_logic_dev_func_mode[%u] is missing.\n", + i, i); + return rv; + } + + dump_logic_dev_reg_start = 0; + dump_logic_dev_reg_end = LOGIC_DEV_DUMP_REG_END_DEFAULT; + of_property_read_u32_index(dev->of_node, "dump_logic_dev_reg_start", i, &dump_logic_dev_reg_start); + of_property_read_u32_index(dev->of_node, "dump_logic_dev_reg_end", i, &dump_logic_dev_reg_end); + + mem_clear(&dump_logic_dev_cfg, sizeof(dump_logic_dev_cfg)); + strscpy(dump_logic_dev_cfg.logic_dev_name, dump_logic_dev_name, + sizeof(dump_logic_dev_cfg.logic_dev_name)); + dump_logic_dev_cfg.logic_dev_func_mode = dump_logic_dev_func_mode; + dump_logic_dev_cfg.logic_dev_reg_start = dump_logic_dev_reg_start; + dump_logic_dev_cfg.logic_dev_reg_end = dump_logic_dev_reg_end; + + ret = logic_dev_dump_init(dump_info, dev, i, &dump_logic_dev_cfg); + if (ret) { + return ret; + } + } + + dump_info->dump_logic_dev_num = dump_logic_dev_num; + + return 0; +} +EXPORT_SYMBOL_GPL(logic_dev_dump_of_node_init); + +int logic_dev_dump_cfg_info_init(logic_dev_dump_info_t *dump_info, struct device *dev, + const logic_dev_dump_cfg_info_t *dump_logic_dev_cfg_info) +{ + int ret; + uint32_t i; + uint32_t dump_logic_dev_num; + logic_dev_dump_cfg_t dump_logic_dev_cfg; + + if (!dump_info || !dev || !dump_logic_dev_cfg_info) { + dev_err(dev, "invalid param, dump_info:%p, dev:%p, dump_logic_dev_cfg_info:%p\n", + dump_info, dev, dump_logic_dev_cfg_info); + return -EINVAL; + } + + dump_logic_dev_num = dump_logic_dev_cfg_info->dump_logic_dev_num; + if (dump_logic_dev_num > LOGIC_DEV_DUMP_MAX_NUM) { + dev_err(dev, "invalid logic dev dump num:%u, max:%u\n", + dump_logic_dev_num, LOGIC_DEV_DUMP_MAX_NUM); + return -EINVAL; + } + + for (i = 0; i < dump_logic_dev_num; i++) { + mem_clear(&dump_logic_dev_cfg, sizeof(dump_logic_dev_cfg)); + dump_logic_dev_cfg = dump_logic_dev_cfg_info->dump_logic_dev_cfg[i]; + if (!dump_logic_dev_cfg.logic_dev_name[0]) { + dev_err(dev, "dump_logic_dev_cfg[%u].logic_dev_name is empty\n", i); + return -EINVAL; + } + + if (dump_logic_dev_cfg.logic_dev_reg_end == 0) { + dump_logic_dev_cfg.logic_dev_reg_end = LOGIC_DEV_DUMP_REG_END_DEFAULT; + } + + ret = logic_dev_dump_init(dump_info, dev, i, &dump_logic_dev_cfg); + if (ret) { + return ret; + } + } + + dump_info->dump_logic_dev_num = dump_logic_dev_num; + + return 0; +} +EXPORT_SYMBOL_GPL(logic_dev_dump_cfg_info_init); + +int cache_value_read(const char *mask_file_path, const char *cache_file_path, uint32_t offset, uint8_t *value, uint32_t count) +{ + int ret, i; + u8 mask_value[MAX_RW_LEN]; + u8 cache_value[MAX_RW_LEN]; + uint32_t total_read, per_len; + + if ((mask_file_path == NULL) || (cache_file_path == NULL) || (value == NULL)) { + DEBUG_ERROR("Invalid params, mask_file_path or cache_file_path or value in NULL\n"); + return -EINVAL; + } + + if (count == 0) { + DEBUG_ERROR("Invalid params, read count is 0.\n"); + return -EINVAL; + } + + DEBUG_INFO("mask_file_path: %s, cache_file_path: %s, offset: 0x%x, count: %u\n", + mask_file_path, cache_file_path, offset, count); + + total_read = 0; + while (total_read < count) { + mem_clear(mask_value, sizeof(mask_value)); + mem_clear(cache_value, sizeof(cache_value)); + per_len = (count - total_read) > MAX_RW_LEN ? MAX_RW_LEN : (count - total_read); + + ret = wb_dev_file_read(mask_file_path, offset, mask_value, per_len); + if (ret < 0) { + DEBUG_ERROR("mask_file read failed, mask_file_path: %s, offset: 0x%x, read_len: %u, ret: %d\n", + mask_file_path, offset, per_len, ret); + return ret; + } + + DEBUG_INFO("mask_file read success, mask_file_path: %s, offset: 0x%x, read_len: %u\n", + mask_file_path, offset, per_len); + + ret = wb_dev_file_read(cache_file_path, offset, cache_value, per_len); + if (ret < 0) { + DEBUG_ERROR("cache_file read failed, cache_file_path: %s, offset: 0x%x, read_len: %u, ret: %d\n", + cache_file_path, offset, per_len, ret); + return ret; + } + DEBUG_INFO("cache_file read success, cache_file_path: %s, offset: 0x%x, read_len: %u\n", + cache_file_path, offset, per_len); + + for (i = 0; i < per_len; i++) { + if (mask_value[i] > 0) { + DEBUG_INFO("offset: 0x%x replace origin value: 0x%x to cache value: 0x%x\n", + offset + i, value[total_read + i], cache_value[i]); + value[total_read + i] = cache_value[i]; + } + } + offset += per_len; + total_read += per_len; + } + + return total_read; +} +EXPORT_SYMBOL_GPL(cache_value_read); + +int cache_value_write(const char *mask_file_path, const char *cache_file_path, uint32_t offset, uint8_t *value, uint32_t count) +{ + int ret, i; + u8 mask_value[MAX_RW_LEN]; + u8 cache_value[MAX_RW_LEN]; + uint32_t total_write, per_len; + + if ((mask_file_path == NULL) || (cache_file_path == NULL) || (value == NULL)) { + DEBUG_ERROR("Invalid params, mask_file_path or cache_file_path or value in NULL\n"); + return -EINVAL; + } + + if (count == 0) { + DEBUG_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + DEBUG_INFO("mask_file_path: %s, cache_file_path: %s, offset: 0x%x, count: %u\n", + mask_file_path, cache_file_path, offset, count); + + total_write = 0; + while (total_write < count) { + mem_clear(mask_value, sizeof(mask_value)); + mem_clear(cache_value, sizeof(cache_value)); + per_len = (count - total_write) > MAX_RW_LEN ? MAX_RW_LEN : (count - total_write); + + ret = wb_dev_file_read(mask_file_path, offset, mask_value, per_len); + if (ret < 0) { + DEBUG_ERROR("mask_file read failed, mask_file_path: %s, offset: 0x%x, read_len: %u, ret: %d\n", + mask_file_path, offset, per_len, ret); + return ret; + } + + DEBUG_INFO("mask_file read success, mask_file_path: %s, offset: 0x%x, read_len: %u\n", + mask_file_path, offset, per_len); + + ret = wb_dev_file_read(cache_file_path, offset, cache_value, per_len); + if (ret < 0) { + DEBUG_ERROR("cache_file read failed, cache_file_path: %s, offset: 0x%x, read_len: %u, ret: %d\n", + cache_file_path, offset, per_len, ret); + return ret; + } + DEBUG_INFO("cache_file read success, cache_file_path: %s, offset: 0x%x, read_len: %u\n", + cache_file_path, offset, per_len); + + for (i = 0; i < per_len; i++) { + if (mask_value[i] > 0) { + DEBUG_INFO("cache file: %s offset: 0x%x replace value: 0x%x to value: 0x%x\n", + cache_file_path, offset + i, cache_value[i], value[i]); + cache_value[i] = value[total_write + i]; + } + } + ret = wb_dev_file_write(cache_file_path, offset, cache_value, per_len); + if (ret < 0) { + DEBUG_ERROR("cache_file write failed, cache_file_path: %s, offset: 0x%x, write_len: %u, ret: %d\n", + cache_file_path, offset, per_len, ret); + return ret; + } + DEBUG_INFO("cache_file write success, cache_file_path: %s, offset: 0x%x, write_len: %u\n", + cache_file_path, offset, per_len); + + offset += per_len; + total_write += per_len; + } + + return total_write; +} +EXPORT_SYMBOL_GPL(cache_value_write); + +static int __init logic_dev_init(void) +{ + int ret; + LOGIC_DEV_INFO("logic_dev_init...\n"); + logic_dev_kobj = kobject_create_and_add("logic_dev", NULL); + if (!logic_dev_kobj) { + DEBUG_ERROR("create logic_dev_kobj error.\n"); + return -ENOMEM; + } + + ret = find_kallsyms_lookup_name(); + if (ret < 0) { + DEBUG_ERROR("find kallsyms_lookup_name failed\n"); + kobject_put(logic_dev_kobj); + logic_dev_kobj = NULL; + return -ENXIO; + } + DEBUG_INFO("find kallsyms_lookup_name ok\n"); + LOGIC_DEV_INFO("logic_dev_init success.\n"); + return 0; +} + +static int logic_dev_status_check_read_func(struct device_status_check *status_check, + uint32_t reg, + uint8_t *data_buf, + uint32_t read_len) +{ + int ret; + + if (status_check == NULL) { + DEBUG_ERROR("status_check is NULL\n"); + return -EINVAL; + } + + if (status_check->dev_bus_ops.read == NULL) { + DEBUG_ERROR("status_check read func is NULL\n"); + return -EINVAL; + } + + ret = status_check->dev_bus_ops.read(status_check->dev_name, + reg, + data_buf, + read_len); + + return ret; +} + +static int logic_dev_status_check_write_func(struct device_status_check *status_check, + uint32_t reg, + uint8_t *data_buf, + uint32_t read_len) +{ + int ret; + + if (status_check == NULL) { + DEBUG_ERROR("status_check is NULL\n"); + return -EINVAL; + } + + if (status_check->dev_bus_ops.write == NULL) { + DEBUG_ERROR("status_check write func is NULL\n"); + return -EINVAL; + } + + ret = status_check->dev_bus_ops.write(status_check->dev_name, + reg, + data_buf, + read_len); + + return ret; +} + +static int status_check_read_check(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t reg, + uint8_t *check_val, + uint8_t *mask, + uint32_t type) +{ + int ret; + uint8_t val[MAX_DATA_WIDTH]; + u32 j; + + mem_clear(val, sizeof(val)); + ret = logic_dev_status_check_read_func(status_check, reg, val, data_byte_len); + if (ret < 0) { + DEBUG_ERROR("Soft fail read failed at reg 0x%x: read=0x%x expect=0x%x mask=0x%x\n", + reg, + val[0], + check_val[0], + mask[0]); + + return ret; + } + + for (j = 0; j < data_byte_len; j++) { + DEBUG_VERBOSE("reg 0x%x: read=0x%x expect=0x%x mask=0x%x\n", reg, val[j], check_val[j], mask[j]); + val[j] &= mask[j]; + } + + ret = dev_rw_check(val, check_val, data_byte_len, type, WB_LOGIC_NORMAL); + if (ret < 0) { + DEBUG_ERROR("STATUS_NOT_OK result check failed, ret:%d.\n", ret); + DEBUG_ERROR("Soft fail check failed at reg 0x%x: read=0x%x expect=0x%x mask=0x%x\n", + reg, + val[0], + check_val[0], + mask[0]); + + return ret; + } + + DEBUG_VERBOSE("STATUS_OK rw one time result check success. reg 0x%x: read=0x%x expect=0x%x mask=0x%x\n", + reg, + val[0], + check_val[0], + mask[0]); + + return 0; +} + +static int check_seu(struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + u32 i; + + if (!(status_check->status_check_type_bmp & STATUS_CHECK_SEU)) { + return 0; + } + + for (i = 0; i < status_check->seu_check_num; i++) { + ret = status_check_read_check(status_check, data_byte_len, status_check->seu_checks[i].reg, + status_check->seu_checks[i].value, status_check->seu_checks[i].mask, + STATUS_CHECK_SEU); + if (ret < 0) { + DEBUG_ERROR("status_check_read_check failed\n"); + return ret; + } + } + + DEBUG_VERBOSE("STATUS_OK rw one time result check success."); + return 0; +} + +static int check_selftest_status(struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + uint8_t val[MAX_DATA_WIDTH]; + u32 i; + + if (!(status_check->status_check_type_bmp & STATUS_CHECK_SELFTEST)) { + return 0; + } + + for (i = 0; i < status_check->selftest_check_num; i++) { + ret = logic_dev_status_check_write_func(status_check, + status_check->selftest_checks[i].reg, + status_check->selftest_checks[i].write_value, + data_byte_len); + if (ret < 0) { + DEBUG_ERROR("selftest fail write failed at reg 0x%x: wr_value=0x%x\n", + status_check->selftest_checks[i].reg, + status_check->selftest_checks[i].write_value[0]); + return ret; + } + + mem_clear(val, sizeof(val)); + ret = logic_dev_status_check_read_func(status_check, + status_check->selftest_checks[i].reg, + val, + data_byte_len); + if (ret < 0) { + DEBUG_ERROR("selftest fail read failed at reg 0x%x\n", + status_check->selftest_checks[i].reg); + + return ret; + } + + ret = dev_rw_check(val, status_check->selftest_checks[i].write_value, data_byte_len, STATUS_CHECK_SELFTEST, + status_check->selftest_checks[i].check_mode); + if (ret < 0) { + DEBUG_ERROR("STATUS_NOT_OK result check failed, ret:%d.\n", ret); + DEBUG_ERROR("selftest fail check failed at reg 0x%x: read=0x%x expect=0x%x check_mode=0x%x\n", + status_check->selftest_checks[i].reg, + val[0], + status_check->selftest_checks[i].write_value[0], + status_check->selftest_checks[i].check_mode); + return ret; + } + + DEBUG_ERROR("STATUS_OK rw one time result check success. reg 0x%x: read=0x%x expect=0x%x check_type=0x%x\n", + status_check->selftest_checks[i].reg, + val[0], + status_check->selftest_checks[i].write_value[0], + status_check->selftest_checks[i].check_mode); + } + + DEBUG_VERBOSE("STATUS_OK rw one time result check success."); + return 0; +} + +static int check_scratch_status(struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + uint8_t val[MAX_DATA_WIDTH]; + u32 i; + + if (!(status_check->status_check_type_bmp & STATUS_CHECK_SCRATCH)) { + return 0; + } + + for (i = 0; i < status_check->scratch_num; i++) { + mem_clear(val, sizeof(val)); + ret = logic_dev_status_check_read_func(status_check, + status_check->scratch_checks[i].reg, + val, + data_byte_len); + if (ret < 0) { + DEBUG_ERROR("check scratch fail, read failed at reg 0x%x\n", + status_check->scratch_checks[i].reg); + + return ret; + } + + ret = dev_rw_check(val, status_check->scratch_checks[i].value, data_byte_len, STATUS_CHECK_SCRATCH, + status_check->scratch_checks[i].check_mode); + if (ret < 0) { + DEBUG_ERROR("STATUS_NOT_OK result check failed, ret:%d.\n", ret); + DEBUG_ERROR("Soft fail check failed at reg 0x%x: read=0x%x expect=0x%x check_mode=0x%x\n", + status_check->scratch_checks[i].reg, + val[0], + status_check->scratch_checks[i].value[0], + status_check->scratch_checks[i].check_mode); + + return ret; + } + + DEBUG_VERBOSE("STATUS_OK rw one time result check success. reg 0x%x: read=0x%x expect=0x%x\n", + status_check->scratch_checks[i].reg, + val[0], + status_check->scratch_checks[i].value[0]); + + } + + DEBUG_VERBOSE("STATUS_OK rw one time result check success."); + return 0; +} + +static uint64_t combine_bytes_to_value(uint8_t *buf, uint32_t buf_len, uint32_t width) { + uint64_t val; + int j; + + val = 0; + for (j = 0; (j < width) && (j < buf_len); j++) { + val |= (uint64_t)(buf[j] & 0xff) << (8 * j); + } + + return val; +} + +static int check_cram(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t *status_value) +{ + int ret; + uint8_t val[MAX_DATA_WIDTH]; + + *status_value = CRAM_ALL_BITS_SET; + if (!(status_check->status_check_type_bmp & STATUS_CHECK_CRAM)) { + return 0; + } + + if (data_byte_len < WIDTH_4Byte || data_byte_len > MAX_DATA_WIDTH) { + DEBUG_ERROR("data_byte_len to short. len:%d.\n", data_byte_len); + return -EINVAL; + } + + mem_clear(val, sizeof(val)); + ret = logic_dev_status_check_read_func(status_check, + status_check->cram_checks.reg, + val, + data_byte_len); + if (ret < 0) { + DEBUG_ERROR("check cram fail, read failed at reg 0x%x\n", + status_check->cram_checks.reg); + + return ret; + } + + *status_value = CRAM_STATUS_FROM_BYTE(val); + if (*status_value != CRAM_STATUS_OK) { + DEBUG_ERROR("status_value: 0x%x, ok value 0x%x, status check result failed.\n", *status_value, CRAM_STATUS_OK); + return -EIO; + } + + DEBUG_VERBOSE("STATUS_OK cram result check success. reg 0x%x: status_value=0x%x expect=0x%x\n", + status_check->cram_checks.reg, + *status_value, + CRAM_STATUS_OK); + + return 0; +} + +static int dev_status_check(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t type, + uint32_t *status_value) +{ + int ret, i; + + ret = 0; + for (i = 0; i < LOGIC_DEV_RETRY_TIME; i++) { + if (type == STATUS_CHECK_SEU) { + ret = check_seu(status_check, data_byte_len); + } else if (type == STATUS_CHECK_SELFTEST) { + ret = check_selftest_status(status_check, data_byte_len); + } else if (type == STATUS_CHECK_SCRATCH) { + ret = check_scratch_status(status_check, data_byte_len); + } else if (type == STATUS_CHECK_CRAM) { + ret = check_cram(status_check, data_byte_len, status_value); + } else { + ret = -1; + break; + } + + if (ret < 0) { + DEBUG_ERROR("check STATUS_NOT_OK time: %d, type: 0x%x, ret: %d\n", + i, type, ret); + msleep(LOGIC_DEV_RETRY_DELAY_MS); + continue; + } + break; + } + + return ret; +} + +static int cram_fail_format_device_status_message(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t type, + char *buf, + uint32_t buf_len, + uint32_t status_value) +{ + int ret; + uint8_t val[MAX_DATA_WIDTH]; + u32 i; + uint64_t value_tmp; + int count; + const char *detail; + uint32_t output_status_value; + + DEBUG_VERBOSE("cram_fail_format_device_status_message start."); + + /* Normalize single+multi bit error to multi-bit error. */ + output_status_value = (status_value == CRAM_STATUS_SINGLE_MULTI_BIT_ERROR) ? + CRAM_STATUS_MULTI_BIT_ERROR : status_value; + + /* Return a read-failure detail when CRAM status cannot be parsed. */ + if (output_status_value == CRAM_ALL_BITS_SET) { + return snprintf(buf, buf_len, "0x%x %s\n", output_status_value, CRAM_DETAIL_LOGICDEV_ERROR); + } + + if (output_status_value > CRAM_STATUS_MULTI_BIT_ERROR) { + DEBUG_ERROR("cram_fail_format_device_status_message invalid status value: 0x%x\n", output_status_value); + return -EINVAL; + } + + count = snprintf(buf, buf_len, "0x%x", output_status_value); + + for (i = 0; i < status_check->cram_checks.cram_err_addr_reg_num; i++) { + mem_clear(val, sizeof(val)); + ret = logic_dev_status_check_read_func(status_check, + status_check->cram_checks.cram_err_addr_reg[i], + val, + data_byte_len); + if (ret < 0) { + DEBUG_ERROR("cram_err_addr_reg read fail, read failed at reg 0x%x data_byte_len %d\n", + status_check->cram_checks.cram_err_addr_reg[i], data_byte_len); + count += snprintf(buf + strlen(buf), buf_len - strlen(buf), " fail"); + + continue; + } + + value_tmp = combine_bytes_to_value(val, sizeof(val), data_byte_len); + value_tmp &= status_check->cram_checks.cram_err_addr_reg_mask[i]; + value_tmp = value_tmp >> CRAM_ERR_ADDR_DATA_OFFSET; + + count += snprintf(buf + strlen(buf), buf_len - strlen(buf), " 0x%" PRIX64 "", value_tmp); + + DEBUG_VERBOSE("cram_fail_format_device_status_message reg 0x%x: read=0x%" PRIX64 " data_byte_len %d mask 0x%x\n", + status_check->cram_checks.cram_err_addr_reg[i], + value_tmp, + data_byte_len, + status_check->cram_checks.cram_err_addr_reg_mask[i]); + + } + + detail = NULL; + switch (output_status_value) { + case CRAM_STATUS_SINGLE_BIT_ERROR: + detail = CRAM_DETAIL_SINGLE_BIT_ERROR; + break; + case CRAM_STATUS_MULTI_BIT_ERROR: + detail = CRAM_DETAIL_MULTI_BIT_ERROR; + break; + default: + break; + } + + if (detail != NULL) { + count += snprintf(buf + strlen(buf), buf_len - strlen(buf), " %s", detail); + } + + DEBUG_VERBOSE("cram_fail_format_device_status_message end."); + count += snprintf(buf + strlen(buf), buf_len - strlen(buf), "\n"); + + return count; + +} + +static int format_device_status_message(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t type, + char *buf, + uint32_t buf_len, + uint32_t status, + uint32_t status_value) +{ + int ret; + + ret = 0; + switch (type) { + case STATUS_CHECK_SEU: + case STATUS_CHECK_SELFTEST: + case STATUS_CHECK_SCRATCH: + return snprintf(buf, buf_len, "0x%x\n", status); + break; + case STATUS_CHECK_CRAM: + if (status == LOGIC_DEV_STATUS_OK) { + return snprintf(buf, buf_len, "0x%x\n", status); + } + + return cram_fail_format_device_status_message(status_check, data_byte_len, type, + buf, buf_len, status_value); + + break; + default: + DEBUG_ERROR("not found init func, check type 0x%x\n", type); + return -EINVAL; + } + + return ret; + +} + + +static int dev_status_check_message(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t type, + char *buf, + uint32_t buf_len) +{ + int ret; + u32 status; + uint32_t status_value; + + status = 0; + ret = dev_status_check(status_check, data_byte_len, type, &status_value); + if (ret != 0) { + status = LOGIC_DEV_STATUS_NOT_OK; + } + + ret = format_device_status_message(status_check, data_byte_len, type, buf, buf_len, status, status_value); + + return ret; +} + +static int wb_logic_check_scratch_status_init(struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + u32 i; + + if (status_check == NULL) { + DEBUG_ERROR("param is NULL\n"); + return -EINVAL; + } + + if (data_byte_len > MAX_DATA_WIDTH || data_byte_len == 0) { + DEBUG_ERROR("data_byte_len is error.(data_byte_len: %d)\n", data_byte_len); + return -EINVAL; + } + + for (i = 0; i < status_check->scratch_num; i++) { + ret = logic_dev_status_check_write_func(status_check, + status_check->scratch_checks[i].reg, + status_check->scratch_checks[i].value, + data_byte_len); + if (ret < 0) { + return ret; + } + + status_check->scratch_checks[i].initialized = true; + } + + DEBUG_VERBOSE("STATUS_OK rw one time result check success."); + return 0; +} + +static int wb_logic_check_status_hw_init_with_type(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t check_type) +{ + int ret; + + ret = 0; + switch (check_type) { + case STATUS_CHECK_SEU: + break; + case STATUS_CHECK_SELFTEST: + break; + case STATUS_CHECK_CRAM: + break; + case STATUS_CHECK_SCRATCH: + ret = wb_logic_check_scratch_status_init(status_check, data_byte_len); + if (ret < 0) { + DEBUG_ERROR("wb_logic_check_scratch_status_init fail. ret %d\n", ret); + } + break; + default: + DEBUG_ERROR("not found init func, check type 0x%x\n", check_type); + return -EINVAL; + } + + return ret; +} + + +int wb_logic_check_status_hw_init(struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + int check_type; + int i; + int fail_count; + + fail_count = 0; + if (status_check == NULL) { + DEBUG_ERROR("param is NULL\n"); + return -EINVAL; + } + + ret = 0; + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + check_type = STATUS_CHECK_BITS(i); + if (status_check->status_check_type_bmp & check_type) { + ret = wb_logic_check_status_hw_init_with_type(status_check, data_byte_len, check_type); + if (ret < 0) { + fail_count++; + DEBUG_ERROR("wb_logic_check_status_hw_init_with_type init fail, check type 0x%x ret %d\n", check_type, ret); + } + } else { + DEBUG_INFO("unsupport type skip hw init.(0x%x)\n", check_type); + } + } + + if (fail_count != 0) { + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wb_logic_check_status_hw_init); + +int wb_logic_dev_get_status(struct device_status_check *status_check, + uint32_t data_byte_len, + char *buf, + uint32_t buf_len) +{ + int ret; + u32 val; + u32 check_type; + u32 bit; + uint32_t status_value; + + if (status_check == NULL || buf == NULL) { + DEBUG_ERROR("param is NULL.(status_check: %p, buf: %p)\n", status_check, buf); + return -EINVAL; + } + + if (data_byte_len > MAX_DATA_WIDTH || data_byte_len == 0) { + DEBUG_ERROR("data_byte_len is error.(data_byte_len: %d)\n", data_byte_len); + return -EINVAL; + } + + if (status_check->status_check_type_bmp == 0) { + DEBUG_ERROR("unsupport dev status check.\n"); + return -EOPNOTSUPP; + } + + val = 0; + for (bit = 0; bit < STATUS_CHECK_TYPE_MAX; bit++) { + check_type = STATUS_CHECK_BITS(bit); + if (status_check->status_check_type_bmp & check_type) { + ret = dev_status_check(status_check, data_byte_len, check_type, &status_value); + if (ret != 0) { + val |= check_type; + } + } else { + DEBUG_INFO("unsupport type skip check.(0x%x)\n", check_type); + } + } + + status_check->dev_status = val; + + return snprintf(buf, buf_len, "0x%x\n", status_check->dev_status); +} +EXPORT_SYMBOL_GPL(wb_logic_dev_get_status); + +uint32_t wb_logic_status_type_get_number(uint32_t type_bmp) +{ + int i; + u32 check_type; + uint8_t support_check_number; + + support_check_number = 0; + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + check_type = STATUS_CHECK_BITS(i); + + if (type_bmp & check_type) { + support_check_number++; + } + } + + return support_check_number; +} +EXPORT_SYMBOL_GPL(wb_logic_status_type_get_number); + +static int wb_logic_get_check_type_bit(uint32_t type_bmp) +{ + int i; + u32 check_type_tmp; + uint8_t check_type; + + check_type = -1; + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + check_type_tmp = STATUS_CHECK_BITS(i); + + if (type_bmp & check_type_tmp) { + check_type = i; + break; + } + } + + return check_type; +} + +static int set_last_dev_status_with_type(struct device_status_check *status_check, + uint32_t type, + uint32_t status) +{ + int status_tmp; + int bit_number; + + if (status == LOGIC_DEV_STATUS_OK) { + status_tmp = LOGIC_DEV_STATUS_OK; + } else { + status_tmp = LOGIC_DEV_STATUS_NOT_OK; + } + + bit_number = wb_logic_get_check_type_bit(type); + status_check->type_dev_status[bit_number] = status_tmp; + + return status_tmp; +} + +int wb_logic_dev_get_status_with_type(struct device_status_check *status_check, + uint32_t data_byte_len, + char *buf, + uint32_t buf_len, + uint32_t type) +{ + int ret; + u32 val; + int check_type_number; + + if (status_check == NULL || buf == NULL) { + DEBUG_ERROR("param is NULL.(status_check: %p, buf: %p)\n", status_check, buf); + return -EINVAL; + } + + if (data_byte_len > MAX_DATA_WIDTH || data_byte_len == 0) { + DEBUG_ERROR("data_byte_len is error.(data_byte_len: %d)\n", data_byte_len); + + return -EINVAL; + } + + val = 0; + /* Input parameter detection, only one type */ + check_type_number = wb_logic_status_type_get_number(type); + if (check_type_number != 1) { + DEBUG_ERROR("check_type_number not 1: 0x%x.\n", type); + return -EINVAL; + } + + if (status_check->status_check_type_bmp & type) { + ret = dev_status_check_message(status_check, data_byte_len, type, buf, buf_len); + } else { + DEBUG_ERROR("unsupport dev status check.\n"); + return -EOPNOTSUPP; + } + + set_last_dev_status_with_type(status_check, type, val); + + return ret; +} +EXPORT_SYMBOL_GPL(wb_logic_dev_get_status_with_type); + +/* return: 0:not cache, -x: fail, +x: use cache status */ +int wb_logic_get_cache_status_with_type(struct device_status_check *status_check, + uint32_t check_type, + uint32_t status_cache_ms, + char *buf, + uint32_t buf_len) +{ + int check_type_number; + int bit_number; + + if (status_check == NULL || buf == NULL) { + DEBUG_ERROR("param is NULL.(status_check: %p, buf: %p)\n", status_check, buf); + return -EINVAL; + } + + /* Input parameter detection, only one type */ + check_type_number = wb_logic_status_type_get_number(check_type); + if (check_type_number != 1) { + DEBUG_ERROR("check_type_number not 1: 0x%x.\n", check_type); + return -EINVAL; + } + + /* get bit_number 100% success */ + bit_number = wb_logic_get_check_type_bit(check_type); + if (time_before(jiffies, status_check->type_last_jiffies[bit_number] + msecs_to_jiffies(status_cache_ms))) { + /* Within the time range of status_cache_ms, directly return the last result */ + DEBUG_VERBOSE("time before last time %d ms return last status: %d\n", + status_cache_ms, status_check->type_dev_status[bit_number]); + return snprintf(buf, buf_len, "%u\n", status_check->type_dev_status[bit_number]); + } + + status_check->type_last_jiffies[bit_number] = jiffies; + + return 0; +} +EXPORT_SYMBOL_GPL(wb_logic_get_cache_status_with_type); + +static void set_seu_value_buf(int data_bus_width, int data_num, struct device_status_check *status_check, uint32_t *reg_data_buf) +{ + int i; + int j; + + if (data_num == data_bus_width) { + for (i = 0; i < status_check->seu_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->seu_checks[i].value[j] = reg_data_buf[j]; + } + } + } else { + for (i = 0; i < status_check->seu_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->seu_checks[i].value[j] = reg_data_buf[j + i * data_bus_width]; + } + } + } +} + +static void set_seu_mask_buf_def(int data_bus_width, struct device_status_check *status_check) +{ + int i; + int j; + + for (i = 0; i < status_check->seu_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->seu_checks[i].mask[j] = 0xff; + } + } +} + +static void set_seu_mask_buf(int data_bus_width, int data_num, struct device_status_check *status_check, uint32_t *reg_data_buf) +{ + int i; + int j; + + if (data_num == data_bus_width) { + for (i = 0; i < status_check->seu_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->seu_checks[i].mask[j] = reg_data_buf[j]; + } + } + } else { + for (i = 0; i < status_check->seu_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->seu_checks[i].mask[j] = reg_data_buf[j + i * data_bus_width]; + } + } + } +} + +static void set_cram_mask_buf_def(struct device_status_check *status_check) +{ + int i; + + for (i = 0; i < status_check->cram_checks.cram_err_addr_reg_num; i++) { + status_check->cram_checks.cram_err_addr_reg_mask[i] = CRAM_ALL_BITS_SET; + } +} + +static void set_cram_mask_buf(int data_num, struct device_status_check *status_check, uint32_t *reg_data_buf) +{ + int i; + + if (data_num == CRAM_CONFIG_MASK_MIN_COUNT) { + for (i = 0; i < status_check->cram_checks.cram_err_addr_reg_num; i++) { + status_check->cram_checks.cram_err_addr_reg_mask[i] = reg_data_buf[0]; + } + } else { + for (i = 0; i < status_check->cram_checks.cram_err_addr_reg_num; i++) { + status_check->cram_checks.cram_err_addr_reg_mask[i] = reg_data_buf[i]; + } + } +} + +static void set_selftest_value_buf(int data_bus_width, int data_num, struct device_status_check *status_check, uint32_t *reg_data_buf) +{ + int i; + int j; + + if (data_num == data_bus_width) { + for (i = 0; i < status_check->selftest_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->selftest_checks[i].write_value[j] = reg_data_buf[j]; + } + } + } else { + for (i = 0; i < status_check->selftest_check_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->selftest_checks[i].write_value[j] = reg_data_buf[j + i * data_bus_width]; + } + } + } +} + +static void wb_logic_check_type_status_and_jiffies_init(struct device_status_check *status_check) +{ + int i; + + status_check->last_jiffies = jiffies; + status_check->dev_status = 0; + + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + status_check->type_last_jiffies[i] = jiffies; + status_check->type_dev_status[i] = 0; + } + + return; +} + + +static void set_scratch_value_buf(int data_bus_width, int data_num, struct device_status_check *status_check, uint32_t *reg_data_buf) +{ + int i; + int j; + + if (data_num == data_bus_width) { + for (i = 0; i < status_check->scratch_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->scratch_checks[i].value[j] = reg_data_buf[j]; + } + } + } else { + for (i = 0; i < status_check->scratch_num; i++) { + for (j = 0; j < data_bus_width; j++) { + status_check->scratch_checks[i].value[j] = reg_data_buf[j + i * data_bus_width]; + } + } + } +} + +static void cram_checks_value_init_def(struct device_status_check *status_check) +{ + status_check->cram_checks.cram_err_addr_reg_num = CRAM_ERR_ADDR_NUM_DEF; + status_check->cram_checks.cram_err_addr_reg[0] = status_check->cram_checks.reg; + status_check->cram_checks.cram_err_addr_reg_mask[0] = CRAM_ERR_ADDR_REG_MASK_DEF; +} + +static int of_dev_seu_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + uint32_t reg_buf[MAX_DATA_WIDTH]; + uint32_t reg_data_buf[MAX_REG_DATA_LEN]; + int data_bus_width; + int data_num; + int i; + + ret = of_property_read_u32(dev->of_node, "seu_check_num", &status_check->seu_check_num); + if (ret != 0) { + dev_err(dev, "Failed to get seu_check_num config, ret: %d\n", ret); + return -ENXIO; + } + + if ((status_check->seu_check_num == 0) || (status_check->seu_check_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid seu_check_num: %u\n", status_check->seu_check_num); + return -EINVAL; + } + + /* get reg */ + ret = of_property_read_u32_array(dev->of_node, "seu_reg", reg_buf, status_check->seu_check_num); + if(ret != 0) { + dev_err(dev, "Failed to get seu_reg config, ret: %d\n", ret); + return -ENXIO; + } + + for (i = 0; i < status_check->seu_check_num; i++) { + status_check->seu_checks[i].reg = reg_buf[i]; + } + + data_bus_width = data_byte_len; + /* get seu reg data */ + data_num = of_property_count_elems_of_size(dev->of_node, "seu_reg_data", sizeof(u32)); + if (data_num <= 0) { + dev_err(dev, "Invalid seu_reg_data num: %u\n", data_num); + return -EINVAL; + } + + if (data_num != data_bus_width && data_num != (data_bus_width * status_check->seu_check_num)) { + dev_err(dev, "Fail seu_reg_data num: %u\n", data_num); + return -EINVAL; + } + + for (i = 0; i < data_num; i++) { + ret = of_property_read_u32_index(dev->of_node, "seu_reg_data", i, ®_data_buf[i]); + if (ret < 0) { + dev_err(dev, "Failed to get seu_reg_data config, ret: %d\n", ret); + return -ENXIO; + } + } + + /* set seu value */ + set_seu_value_buf(data_bus_width, data_num, status_check, reg_data_buf); + + /* get seu reg data mask */ + data_num = of_property_count_elems_of_size(dev->of_node, "seu_reg_mask", sizeof(u32)); + if (data_num <= 0) { + set_seu_mask_buf_def(data_bus_width, status_check); + goto mask_out; + } + + if (data_num != data_bus_width && data_num != (data_bus_width * status_check->seu_check_num)) { + dev_err(dev, "Fail seu_reg_mask num: %u\n", data_num); + return -EINVAL; + } + + for (i = 0; i < data_num; i++) { + ret = of_property_read_u32_index(dev->of_node, "seu_reg_mask", i, ®_data_buf[i]); + if (ret < 0) { + dev_err(dev, "Fail to get seu_reg_mask value: %d\n", ret); + return -EINVAL; + } + } + + set_seu_mask_buf(data_bus_width, data_num, status_check, reg_data_buf); + +mask_out: + return 0; +} + +static int of_dev_selftest_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + uint32_t reg_buf[MAX_DATA_WIDTH]; + uint32_t reg_data_buf[MAX_REG_DATA_LEN]; + int data_bus_width; + int data_num; + int i; + + ret = of_property_read_u32(dev->of_node, "selftest_check_num", &status_check->selftest_check_num); + if (ret != 0) { + dev_err(dev, "Failed to get selftest_check_num config, ret: %d\n", ret); + return -ENXIO; + } + + if ((status_check->selftest_check_num == 0) || (status_check->selftest_check_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid selftest_check_num: %u\n", status_check->selftest_check_num); + return -EINVAL; + } + + ret = of_property_read_u32_array(dev->of_node, "selftest_reg", reg_buf, status_check->selftest_check_num); + if(ret != 0) { + dev_err(dev, "Failed to get selftest_reg config, ret: %d\n", ret); + return -ENXIO; + } + + for (i = 0; i < status_check->selftest_check_num; i++) { + status_check->selftest_checks[i].reg = reg_buf[i]; + } + + ret = of_property_read_u32_array(dev->of_node, "selftest_check_mode", reg_buf, status_check->selftest_check_num); + if(ret != 0) { + /* defalut use 0 */ + for (i = 0; i < status_check->selftest_check_num; i++) { + status_check->selftest_checks[i].check_mode = WB_LOGIC_NORMAL; + } + } else { + for (i = 0; i < status_check->selftest_check_num; i++) { + status_check->selftest_checks[i].check_mode = reg_buf[i]; + } + } + + data_bus_width = data_byte_len; + /* get selftest reg data */ + data_num = of_property_count_elems_of_size(dev->of_node, "selftest_reg_data", sizeof(u32)); + if (data_num <= 0) { + dev_err(dev, "Invalid selftest_reg_data num: %u\n", data_num); + return -EINVAL; + } + + if (data_num != data_bus_width && data_num != (data_bus_width * status_check->selftest_check_num)) { + dev_err(dev, "Fail selftest_reg_data num: %u\n", data_num); + return -EINVAL; + } + + for (i = 0; i < data_num; i++) { + ret = of_property_read_u32_index(dev->of_node, "selftest_reg_data", i, ®_data_buf[i]); + if (ret < 0) { + dev_err(dev, "Failed to get selftest_reg_data config, ret: %d\n", ret); + return -ENXIO; + } + } + + /* set selftest value */ + set_selftest_value_buf(data_bus_width, data_num, status_check, reg_data_buf); + + return 0; +} + +static int of_dev_scratch_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + uint32_t reg_buf[MAX_DATA_WIDTH]; + uint32_t reg_data_buf[MAX_REG_DATA_LEN]; + int data_bus_width; + int data_num; + int i; + + ret = of_property_read_u32(dev->of_node, "scratch_check_num", &status_check->scratch_num); + if (ret != 0) { + dev_err(dev, "Failed to get scratch_check_num config, ret: %d\n", ret); + return -ENXIO; + } + + if ((status_check->scratch_num == 0) || (status_check->scratch_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid scratch_num: %u\n", status_check->scratch_num); + return -EINVAL; + } + + ret = of_property_read_u32_array(dev->of_node, "scratch_reg", reg_buf, status_check->scratch_num); + if(ret != 0) { + dev_err(dev, "Failed to get scratch_reg config, ret: %d\n", ret); + return -ENXIO; + } + + for (i = 0; i < status_check->scratch_num; i++) { + status_check->scratch_checks[i].reg = reg_buf[i]; + } + + ret = of_property_read_u32_array(dev->of_node, "scratch_check_mode", reg_buf, status_check->scratch_num); + if(ret != 0) { + /* defalut use 0 */ + for (i = 0; i < status_check->scratch_num; i++) { + status_check->scratch_checks[i].check_mode = WB_LOGIC_NORMAL; + } + } else { + for (i = 0; i < status_check->scratch_num; i++) { + status_check->scratch_checks[i].check_mode = reg_buf[i]; + } + } + + data_bus_width = data_byte_len; + /* get selftest reg data */ + data_num = of_property_count_elems_of_size(dev->of_node, "scratch_reg_data", sizeof(u32)); + if (data_num <= 0) { + dev_err(dev, "Invalid scratch_reg_data num: %u\n", data_num); + return -EINVAL; + } + + if (data_num != data_bus_width && data_num != (data_bus_width * status_check->scratch_num)) { + dev_err(dev, "Fail scratch_reg_data num: %u\n", data_num); + return -EINVAL; + } + + for (i = 0; i < data_num; i++) { + ret = of_property_read_u32_index(dev->of_node, "scratch_reg_data", i, ®_data_buf[i]); + if (ret < 0) { + dev_err(dev, "Failed to get scratch_reg_data config, ret: %d\n", ret); + return -ENXIO; + } + } + + /* set scratch value */ + set_scratch_value_buf(data_bus_width, data_num, status_check, reg_data_buf); + + return 0; +} + +static int of_dev_cram_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + int i; + int data_num; + int data_bus_width; + uint32_t reg_data_buf[MAX_REG_DATA_LEN]; + + ret = of_property_read_u32(dev->of_node, "cram_reg", &status_check->cram_checks.reg); + if(ret != 0) { + dev_err(dev, "Failed to get cram_reg config, ret: %d\n", ret); + return -ENXIO; + } + + ret = of_property_read_u32(dev->of_node, "cram_err_addr_reg_num", &status_check->cram_checks.cram_err_addr_reg_num); + if (ret == 0) { + if ((status_check->cram_checks.cram_err_addr_reg_num == 0) || (status_check->cram_checks.cram_err_addr_reg_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid cram_err_addr_reg_num: %u\n", status_check->cram_checks.cram_err_addr_reg_num); + return -EINVAL; + } + + ret = of_property_read_u32_array(dev->of_node, "cram_err_addr_reg", status_check->cram_checks.cram_err_addr_reg, status_check->cram_checks.cram_err_addr_reg_num); + if(ret != 0) { + dev_err(dev, "Failed to get cram_err_addr_reg config, ret: %d\n", ret); + return -ENXIO; + } + + /* get seu reg data mask */ + data_bus_width = data_byte_len; + data_num = of_property_count_elems_of_size(dev->of_node, "cram_err_addr_reg_mask", sizeof(u32)); + if (data_num <= 0) { + /* use def mask CRAM_ALL_BITS_SET */ + set_cram_mask_buf_def(status_check); + } else { + /* must config one mask or everyone mask */ + if (data_num != CRAM_CONFIG_MASK_MIN_COUNT && data_num != status_check->cram_checks.cram_err_addr_reg_num) { + dev_err(dev, "Fail cram_err_addr_reg_mask num: %u\n", data_num); + return -EINVAL; + } + + for (i = 0; i < data_num; i++) { + ret = of_property_read_u32_index(dev->of_node, "cram_err_addr_reg_mask", i, ®_data_buf[i]); + if (ret < 0) { + dev_err(dev, "Fail to get seu_reg_mask value: %d\n", ret); + return -EINVAL; + } + } + + set_cram_mask_buf(data_num, status_check, reg_data_buf); + } + } else { + cram_checks_value_init_def(status_check); + DEBUG_VERBOSE("use def value.\n"); + } + + return 0; +} + +static int of_dev_status_check_one_type_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t check_type) +{ + int ret; + + switch (check_type) { + case STATUS_CHECK_SEU: + ret = of_dev_seu_status_check_config_init(dev, status_check, data_byte_len); + if (ret != 0) { + dev_err(dev, "seu_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + case STATUS_CHECK_SELFTEST: + ret = of_dev_selftest_status_check_config_init(dev, status_check, data_byte_len); + if (ret != 0) { + dev_err(dev, "selftest_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + case STATUS_CHECK_SCRATCH: + ret = of_dev_scratch_status_check_config_init(dev, status_check, data_byte_len); + if (ret != 0) { + dev_err(dev, "scratch_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + case STATUS_CHECK_CRAM: + ret = of_dev_cram_status_check_config_init(dev, status_check, data_byte_len); + if (ret != 0) { + dev_err(dev, "dev_cram_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + default: + dev_err(dev, "not found init func, check type 0x%x\n", check_type); + return -EINVAL; + } + + return 0; +} + + +static int of_dev_status_check_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + int i; + u32 check_type; + + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + check_type = STATUS_CHECK_BITS(i); + if (status_check->status_check_type_bmp & check_type) { + ret = of_dev_status_check_one_type_init(dev, status_check, data_byte_len, check_type); + if (ret != 0) { + dev_err(dev, "of_dev_status_check_one_type_init fail, check_type 0x%x ret %d\n", check_type, ret); + return ret; + } + } else { + DEBUG_INFO("unsupport type skip init.(0x%x)\n", check_type); + } + } + + return 0; +} + +int of_dev_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + device_func_write read, + device_func_write write, + const char *dev_name) +{ + int ret; + uint32_t type; + int check_type_number; + + if (dev == NULL) { + PRINT_ERROR("dev_status_check_config_init fail, dev is NULL\n"); + return -EINVAL; + } + + if (status_check == NULL || dev_name == NULL) { + dev_err(dev, "param is NULL.(status_check: %p, dev_name = %p)\n", status_check, dev_name); + return -EINVAL; + } + + if (data_byte_len > MAX_DATA_WIDTH || data_byte_len == 0) { + dev_err(dev, "data_byte_len is error.(data_byte_len: %d)\n", data_byte_len); + return -EINVAL; + } + + snprintf(status_check->dev_name, sizeof(status_check->dev_name),"/dev/%s", dev_name); + + ret = of_property_read_u32(dev->of_node, "status_check_type_bmp", &status_check->status_check_type_bmp); + if (ret == 0) { + type = status_check->status_check_type_bmp; + /* Check dts configuration status_check_type_bmp valid */ + check_type_number = wb_logic_status_type_get_number(type); + if (check_type_number == 0) { + dev_err(dev, "Invalid status_check_type: %u\n", type); + return -EINVAL; + } + + if (read == NULL || write == NULL) { + dev_err(dev, "Invalid read or write func\n"); + return -EINVAL; + } + + status_check->dev_bus_ops.read = read; + status_check->dev_bus_ops.write = write; + wb_logic_check_type_status_and_jiffies_init(status_check); + DEBUG_VERBOSE("status_check_type: %u\n", status_check->status_check_type_bmp); + ret = of_dev_status_check_init(dev, status_check, data_byte_len); + if (ret != 0) { + dev_err(dev, "of_dev_status_check_init fail: %d\n", ret); + return ret; + } + } else { + DEBUG_VERBOSE("not support dev status check sysfs.\n"); + } + + return 0; +} +EXPORT_SYMBOL_GPL(of_dev_status_check_config_init); + +static int platform_dev_seu_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data) +{ + int data_bus_width; + int i; + int j; + + status_check->seu_check_num = status_check_data->seu_check_num; + if ((status_check->seu_check_num == 0) || (status_check->seu_check_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid seu_check_num: %u\n", status_check->seu_check_num); + return -EINVAL; + } + + data_bus_width = data_byte_len; + for (i = 0; i < status_check->seu_check_num; i++) { + status_check->seu_checks[i].reg = status_check_data->seu_checks[i].reg; + for (j = 0; j < data_bus_width; j++) { + status_check->seu_checks[i].value[j] = status_check_data->seu_checks[i].value[j]; + if (status_check_data->seu_checks[i].mask[j] == 0) { + status_check->seu_checks[i].mask[j] = 0xff; + } else { + status_check->seu_checks[i].mask[j] = status_check_data->seu_checks[i].mask[j]; + } + } + } + + return 0; +} + +static int platform_dev_selftest_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data) +{ + int data_bus_width; + int i; + int j; + + status_check->selftest_check_num = status_check_data->selftest_check_num; + if ((status_check->selftest_check_num == 0) || (status_check->selftest_check_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid selftest_check_num: %u\n", status_check->selftest_check_num); + return -EINVAL; + } + + data_bus_width = data_byte_len; + for (i = 0; i < status_check->selftest_check_num; i++) { + status_check->selftest_checks[i].reg = status_check_data->selftest_checks[i].reg; + status_check->selftest_checks[i].check_mode = status_check_data->selftest_checks[i].check_mode; + for (j = 0; j < data_bus_width; j++) { + status_check->selftest_checks[i].write_value[j] = status_check_data->selftest_checks[i].write_value[j]; + } + } + + return 0; +} + +static int platform_dev_scratch_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data) +{ + int data_bus_width; + int i; + int j; + + status_check->scratch_num = status_check_data->scratch_num; + if ((status_check->scratch_num == 0) || (status_check->scratch_num > TEST_REG_MAX_NUM)) { + dev_err(dev, "Invalid scratch_num: %u\n", status_check->scratch_num); + return -EINVAL; + } + + data_bus_width = data_byte_len; + for (i = 0; i < status_check->scratch_num; i++) { + status_check->scratch_checks[i].reg = status_check_data->scratch_checks[i].reg; + status_check->scratch_checks[i].check_mode = status_check_data->scratch_checks[i].check_mode; + for (j = 0; j < data_bus_width; j++) { + status_check->scratch_checks[i].value[j] = status_check_data->scratch_checks[i].value[j]; + } + } + + return 0; +} + +static int platform_dev_cram_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data) +{ + int i; + + status_check->cram_checks.reg = status_check_data->cram_checks.reg; + status_check->cram_checks.cram_err_addr_reg_num = status_check_data->cram_checks.cram_err_addr_reg_num; + if ((status_check->cram_checks.cram_err_addr_reg_num == 0) || (status_check->cram_checks.cram_err_addr_reg_num > TEST_REG_MAX_NUM)) { + /* use def value */ + cram_checks_value_init_def(status_check); + return 0; + } + + for (i = 0; i < status_check->cram_checks.cram_err_addr_reg_num; i++) { + status_check->cram_checks.cram_err_addr_reg[i] = status_check_data->cram_checks.cram_err_addr_reg[i]; + + if (status_check_data->cram_checks.cram_err_addr_reg_mask[i] == 0) { + status_check->cram_checks.cram_err_addr_reg_mask[i] = CRAM_ALL_BITS_SET; + } else { + status_check->cram_checks.cram_err_addr_reg_mask[i] = status_check_data->cram_checks.cram_err_addr_reg_mask[i]; + } + } + + return 0; +} + +static int platform_dev_status_check_one_type_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data, + uint32_t check_type) +{ + int ret; + + switch (check_type) { + case STATUS_CHECK_SEU: + ret = platform_dev_seu_status_check_config_init(dev, status_check, data_byte_len, status_check_data); + if (ret != 0) { + dev_err(dev, "platform seu_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + case STATUS_CHECK_SELFTEST: + ret = platform_dev_selftest_status_check_config_init(dev, status_check, data_byte_len, status_check_data); + if (ret != 0) { + dev_err(dev, "platform selftest_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + case STATUS_CHECK_SCRATCH: + ret = platform_dev_scratch_status_check_config_init(dev, status_check, data_byte_len, status_check_data); + if (ret != 0) { + dev_err(dev, "platform scratch_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + case STATUS_CHECK_CRAM: + ret = platform_dev_cram_status_check_config_init(dev, status_check, data_byte_len, status_check_data); + if (ret != 0) { + dev_err(dev, "platform cram_status_check_config_init fail: %d\n", ret); + return ret; + } + break; + + default: + dev_err(dev, "not found init func, check type 0x%x\n", check_type); + return -EINVAL; + } + + return 0; +} + + +static int platform_dev_status_check_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data) +{ + int ret; + int i; + u32 check_type; + + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + check_type = STATUS_CHECK_BITS(i); + if (status_check->status_check_type_bmp & check_type) { + ret = platform_dev_status_check_one_type_init(dev, status_check, data_byte_len, status_check_data, check_type); + if (ret != 0) { + dev_err(dev, "platform_dev_status_check_one_type_init fail, check_type 0x%x ret %d\n", check_type, ret); + return ret; + } + } else { + DEBUG_INFO("unsupport type skip init.(0x%x)\n", check_type); + } + } + + return 0; +} + + +int platform_dev_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data, + device_func_write read, + device_func_write write, + const char *dev_name) +{ + int ret; + int check_type_number; + + if (dev == NULL) { + PRINT_ERROR("dev_status_check_config_init fail, dev is NULL\n"); + return -EINVAL; + } + + if (status_check == NULL || status_check_data == NULL) { + dev_err(dev, "param is NULL.(status_check: %p, status_check_data: %p)\n", status_check, status_check_data); + return -EINVAL; + } + + if (data_byte_len > MAX_DATA_WIDTH || data_byte_len == 0) { + dev_err(dev, "data_byte_len is error.(data_byte_len: %d)\n", data_byte_len); + return -EINVAL; + } + + snprintf(status_check->dev_name, sizeof(status_check->dev_name), "/dev/%s", dev_name); + + status_check->status_check_type_bmp = status_check_data->status_check_type_bmp; + /* Check platform configuration status_check_type_bmp valid */ + check_type_number = wb_logic_status_type_get_number(status_check->status_check_type_bmp); + if (check_type_number == 0) { + DEBUG_INFO("Invalid status_check_type: %u\n", status_check->status_check_type_bmp); + return 0; + } + + if (read == NULL || write == NULL) { + dev_err(dev, "Invalid read or write func\n"); + return -EINVAL; + } + + status_check->dev_bus_ops.read = read; + status_check->dev_bus_ops.write = write; + wb_logic_check_type_status_and_jiffies_init(status_check); + + DEBUG_VERBOSE("status_check_type: %u\n", status_check->status_check_type_bmp); + ret = platform_dev_status_check_init(dev, status_check, data_byte_len, status_check_data); + if (ret != 0) { + dev_err(dev, "platform dev_status_check_init fail: %d\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(platform_dev_status_check_config_init); + +static int wb_logic_scratch_clear_status(struct device_status_check *status_check, + uint32_t data_byte_len) +{ + int ret; + + ret = wb_logic_check_scratch_status_init(status_check, data_byte_len); + if (ret < 0) { + DEBUG_ERROR("scratch status clear fail. ret %d\n", ret); + } + + return ret; +} + +static int wb_logic_clear_status_with_type(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t check_type) +{ + int ret; + + ret = 0; + switch (check_type) { + case STATUS_CHECK_SEU: + break; + case STATUS_CHECK_SELFTEST: + break; + case STATUS_CHECK_CRAM: + break; + case STATUS_CHECK_SCRATCH: + ret = wb_logic_scratch_clear_status(status_check, data_byte_len); + if (ret < 0) { + DEBUG_ERROR("wb_logic_scratch_clear_status fail. ret %d\n", ret); + } + break; + default: + DEBUG_ERROR("not found clear func, check type 0x%x\n", check_type); + return -EINVAL; + } + + return ret; +} + +int wb_logic_clear_status(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t type_bmp) +{ + int ret; + int check_type; + int i; + int fail_count; + + fail_count = 0; + if (status_check == NULL) { + DEBUG_ERROR("param is NULL\n"); + return -EINVAL; + } + + if (wb_logic_status_type_get_number(type_bmp) == 0) { + DEBUG_ERROR("check_type_number is 0\n"); + return -EINVAL; + } + + if (data_byte_len > MAX_DATA_WIDTH || data_byte_len == 0) { + DEBUG_ERROR("data_byte_len is error.(data_byte_len: %d)\n", data_byte_len); + return -EINVAL; + } + + + ret = 0; + for (i = 0; i < STATUS_CHECK_TYPE_MAX; i++) { + check_type = STATUS_CHECK_BITS(i); + if ((type_bmp & check_type) == 0) { + DEBUG_INFO("do nothing. (type_bmp 0x%x, check_type 0x%x)\n", type_bmp, check_type); + continue; + } + + if (status_check->status_check_type_bmp & check_type) { + ret = wb_logic_clear_status_with_type(status_check, data_byte_len, check_type); + if (ret < 0) { + fail_count++; + DEBUG_ERROR("wb_logic_clear_status_with_type fail, check type 0x%x ret %d\n", check_type, ret); + } + } else { + DEBUG_INFO("unsupport type skip hw init.(0x%x)\n", check_type); + } + } + + if (fail_count != 0) { + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(wb_logic_clear_status); + +void sleep_by_lock_mode(int sleep_time, uint32_t lock_mode) +{ + if (lock_mode == WB_MUTEX_LOCK_MODE) { + usleep_range(sleep_time, sleep_time + 1); + } else { + udelay(sleep_time); + } +} +EXPORT_SYMBOL_GPL(sleep_by_lock_mode); + +int wb_logic_lock_mode_check(uint32_t lock_mode, uint32_t func_mode) +{ + if(lock_mode == WB_SPIN_LOCK_MODE) { + switch (func_mode){ + case SYMBOL_I2C_DEV_MODE: + case FILE_MODE: + case SYMBOL_SPI_DEV_MODE: + case SYMBOL_INDIRECT_DEV_MODE: + case SYMBOL_PLATFORM_I2C_DEV_MODE: + DEBUG_ERROR("func mode not support spin lock mode.\n"); + return -EINVAL; + default: + break; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(wb_logic_lock_mode_check); + +static void __exit logic_dev_exit(void) +{ + if (logic_dev_kobj) { + kobject_put(logic_dev_kobj); + } + LOGIC_DEV_INFO("logic_dev_exit success.\n"); +} + +module_init(logic_dev_init); +module_exit(logic_dev_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("sonic logic_dev common methods"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c index d8c08c0e9c..62dd6b4ffa 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c @@ -1,7 +1,6 @@ /* - * An wb_mac_bsc driver for mac bsc function * - * Copyright (C) 2024 Micas Networks Inc. + * Copyright (c) 1998, 1999 Frodo Looijaard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +28,7 @@ #include #include #include -#include +#include #define mem_clear(data, size) memset((data), 0, (size)) @@ -40,31 +39,15 @@ #define MAC_REG_DATA_WIDTH (4) #define MAC_BSC_MAX_TEMP_NUM (16) #define MAC_BSC_MAX_READ_REG_STEP (6) -#define MAC_BSC_MAX_SETUP_NUM (1) +#define MAC_BSC_MAX_SETUP_NUM (16) +#define MAC_BSC_AVS_SYSFS_MAX_NUM (16) +#define MAC_BSC_AVS_REG_MAX_NUM (2) #define MAC_BSC_MAX_RETRY (3) #define MAC_BSC_RETRY_SLEEP_TIME (10000) /* 10ms */ -static const struct i2c_device_id mac_id_table[]; - -static int g_wb_mac_bsc_debug = 0; -static int g_wb_mac_bsc_error = 0; - -module_param(g_wb_mac_bsc_debug, int, S_IRUGO | S_IWUSR); -module_param(g_wb_mac_bsc_error, int, S_IRUGO | S_IWUSR); - -#define WB_MAC_BSC_DEBUG(fmt, args...) do { \ - if (g_wb_mac_bsc_debug) { \ - printk(KERN_INFO "[MAC_BSC][VER][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - -#define WB_MAC_BSC_ERROR(fmt, args...) do { \ - if (g_wb_mac_bsc_error) { \ - printk(KERN_ERR "[MAC_BSC][ERR][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ - } \ -} while (0) - +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); typedef enum{ MAC_TYPE_START, TD4_X9 = 0xb780, @@ -74,9 +57,16 @@ typedef enum{ TD3_X2 = 0xb274, TD4 = 0xb880, TH4 = 0xb990, + TH5 = 0x8900, + TH6 = 0x8910, MAC_TYPE_END, } mac_id; +typedef enum { + TYPE_VTMON = 0, + TYPE_AVS, +} reg_type; + typedef enum { MAC_TEMP_START, MAC_TEMP_INDEX1, @@ -109,20 +99,33 @@ typedef struct i2c_op_s { int read_back; } i2c_op_t; +typedef struct avs_info_s { + uint32_t avs_reg_addr; + uint32_t avs_reg_offset; + uint32_t avs_reg_mask; +} avs_info_t; + typedef struct dev_params_s { int mac_id; i2c_op_t sbus_setup[MAC_BSC_MAX_SETUP_NUM]; i2c_op_t vtmon_read[MAC_BSC_MAX_READ_REG_STEP]; + i2c_op_t avs_read[MAC_BSC_MAX_READ_REG_STEP]; uint32_t vtmon_reg_addrs[MAC_BSC_MAX_TEMP_NUM]; + uint32_t avs_reg_addrs[MAC_BSC_MAX_TEMP_NUM]; uint8_t vtmon_instances; uint32_t vtmon_data_width; + uint8_t avs_instances; + avs_info_t avs_info[MAC_BSC_AVS_SYSFS_MAX_NUM][MAC_BSC_AVS_REG_MAX_NUM]; + uint8_t avs_info_instances; int vtmon_scalar; int vtmon_offset; uint8_t sbus_setup_ops; int vtmon_read_ops; int sbus_addr_op; int sbus_error_op; + uint8_t avs_read_ops; uint32_t sbus_error_mask; + bool not_support_vtmon; } dev_params_t; static dev_params_t mac_temp_conf[] = { @@ -346,6 +349,85 @@ static dev_params_t mac_temp_conf[] = { .sbus_addr_op = 2, .sbus_error_op = -1, }, + { + .mac_id = TH5, + .sbus_setup = {{I2C_WRITE, 0x02879800, 0x00000000}, /* CMICX_M0_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x0287b800, 0x00000000}, /* CMICX_M1_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x0287a800, 0x00000000}, /* CMICX_M2_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x02872800, 0x00000000}, /* CMICX_S0_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x02810798, 0x02078000}, /* CMIC_CMNPL_SBUSPIO_CH15_CMPL_RING_BASE_ADDR_LOWERr = HOST_MEM_BASE */ + {I2C_WRITE, 0x0281079c, 0x00000000}, /* CMIC_CMNPL_SBUSPIO_CH15_CMPL_RING_BASE_ADDR_HIGHr = 0 */ + {I2C_WRITE, 0x028107a0, 0x00000000}, /* CMIC_CMNPL_SBUSPIO_CH15_CMPL_RING_SIZEr = 0x0 */ + {I2C_WRITE, 0x028107a4, 0x02079000}, /* CMIC_CMNPL_SBUSPIO_CH15_POINTER_HOST_ADDR_LOWERr = POINTER_MEM_BASE */ + {I2C_WRITE, 0x028107a8, 0x00000000}, /* CMIC_CMNPL_SBUSPIO_CH15_POINTER_HOST_ADDR_UPPERr = 0 */ + {I2C_WRITE, 0x0280f800, 0x2c200040}, /* CMIC_CMNPL_SBUSPIO_CH15_COMMAND_RING_MEMORYr[0] = 0x2c200040 */ + {I2C_WRITE, 0x028107ac, 0x00000008}}, /* CMIC_CMNPL_SBUSPIO_CH15_CMD_PRODUCER_INDEXr = 8 0x2c200040 */ + .vtmon_read = {{I2C_WRITE, 0x02810780, 0x00000200}, /* CMIC_CMNPL_SBUSPIO_CH15_CTRLr = 0x200 */ + {I2C_WRITE, 0x0280f804, 0x02008800}, /* CMIC_CMNPL_SBUSPIO_CH15_COMMAND_RING_MEMORYr[1] = TOP_PVTMON_0_RESULT_1r */ + {I2C_WRITE, 0x02810780, 0x00000201}, /* CMIC_CMNPL_SBUSPIO_CH15_CTRLr = 0x201 */ + {I2C_READ, 0x02810794}, /* CMIC_CMNPL_SBUSPIO_CH15_STATUSr */ + {I2C_READ, 0x02078000}}, /* Read HOST_MEM_BASE */ + .vtmon_reg_addrs = {0x02008800, 0x02009000, 0x02009800, 0x0200a000, + 0x0200a800, 0x0200b000, 0x0200b800, 0x0200c000, + 0x0200c800, 0x0200d000, 0x0200d800, 0x0200e000, + 0x0200e800, 0x0200f000, 0x0200f800, 0x02010000}, /* "TOP_PVTMON0_RESULT_1" @ 0x02008800, ..... TOP_PVTMON15_RESULT_1 @ 0x02010000 */ + .vtmon_instances = 16, /* TH5 has 16 VTMONs mainly for customer check */ + .vtmon_data_width = 11, /* check in regfile, TH5 TMON_DATA: 11bits */ + .vtmon_scalar = -3177, //Tj= 476.359 - 0.317704xData + .vtmon_offset = 4763590, //Tj= 476.359 - 0.317704xData + .sbus_setup_ops = 11, + .vtmon_read_ops = 5, + .sbus_addr_op = 1, + .sbus_error_op = 3, + .sbus_error_mask = 0x00000002, + }, + { + .mac_id = TH6, + .sbus_setup = {{I2C_WRITE, 0x02879800, 0x00000000}, /* CMICX_M0_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x0287b800, 0x00000000}, /* CMICX_M1_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x0287a800, 0x00000000}, /* CMICX_M2_IDM_IDM_RESET_CONTROLr = 0x0 */ + {I2C_WRITE, 0x02872800, 0x00000000},}, /* CMICX_S0_IDM_IDM_RESET_CONTROLr = 0x0 */ + .avs_read = {{I2C_READ, 0x02840060}}, /* Read DMU_MASTER_PCU_OTP_CONFIG_6r */ + .avs_reg_addrs = {0x02840060, 0x02840064, 0x02840068, 0x0284006c, 0x02840070}, /* DMU_MASTER_PCU_OTP_CONFIG_6r address offset=0x02840060; DMU_MASTER_PCU_OTP_CONFIG_6r:0x02840064; DMU_MASTER_PCU_OTP_CONFIG_6r:0x02840068... */ + .avs_instances = 5, /* Core die and phytile avs status */ + .avs_info = { + { + {0x02840060, 6, 0xff} + }, + { + {0x02840060, 14, 0xff} + }, + { + {0x02840060, 22, 0xff} + }, + { + {0x02840064, 0, 0x3f}, + {0x02840060, 30, 0x3} + }, + { + {0x02840064, 6, 0xff} + }, + { + {0x02840064, 14, 0xff} + }, + { + {0x02840068, 0, 0xff} + }, + { + {0x02840068, 8, 0xff} + }, + { + {0x02840068, 16, 0xff} + }, + }, + .avs_info_instances = 9, + .sbus_setup_ops = 4, + .avs_read_ops = 1, + .sbus_addr_op = 0, + .sbus_error_op = 3, + .sbus_error_mask = 0x00000002, + .not_support_vtmon = 1, + }, }; struct mac_data { @@ -381,14 +463,14 @@ static int bsc_i2c_read(struct i2c_client *client, uint32_t reg_addr, uint32_t * msgs_num = 2; ret = i2c_transfer(client->adapter, msgs, msgs_num); if (ret != msgs_num) { - WB_MAC_BSC_ERROR("i2c_transfer read failed, reg_addr: 0x%x, ret: %d\n", reg_addr, ret); + DEBUG_ERROR("i2c_transfer read failed, reg_addr: 0x%x, ret: %d\n", reg_addr, ret); return -EIO; } val = 0; for (i = 0; i < MAC_REG_DATA_WIDTH; i++) { val |= data_buf[i] << ((MAC_REG_DATA_WIDTH - i -1) * 8); } - WB_MAC_BSC_DEBUG("bsc_i2c_read success, reg_addr: 0x%x, reg_val: 0x%x\n", reg_addr, val); + DEBUG_VERBOSE("bsc_i2c_read success, reg_addr: 0x%x, reg_val: 0x%x\n", reg_addr, val); *reg_val = val; return 0; } @@ -415,11 +497,11 @@ static int bsc_i2c_write(struct i2c_client *client, uint32_t reg_addr, uint32_t ret = i2c_transfer(client->adapter, msgs, 1); if (ret < 0) { - WB_MAC_BSC_DEBUG("i2c_transfer write failed, reg_addr: 0x%x, reg_val: 0x%x, ret: %d\n", + DEBUG_VERBOSE("i2c_transfer write failed, reg_addr: 0x%x, reg_val: 0x%x, ret: %d\n", reg_addr, reg_val, ret); return ret; } - WB_MAC_BSC_DEBUG("i2c_transfer write reg_addr: 0x%x, reg_val: 0x%x success\n", + DEBUG_VERBOSE("i2c_transfer write reg_addr: 0x%x, reg_val: 0x%x success\n", reg_addr, reg_val); return 0; } @@ -430,16 +512,16 @@ static int handle_operation_write(struct i2c_client *client, i2c_op_t *operation uint32_t rd_back_val; ret = bsc_i2c_write(client, operation->reg_addr, operation->reg_val); - WB_MAC_BSC_DEBUG("bsc_i2c_write reg_addr: 0x%x, set val: 0x%x, ret: %d\n", + DEBUG_VERBOSE("bsc_i2c_write reg_addr: 0x%x, set val: 0x%x, ret: %d\n", operation->reg_addr, operation->reg_val, ret); if (operation->read_back) { ret = bsc_i2c_read(client, operation->reg_addr, &rd_back_val); if (rd_back_val != operation->reg_val) { - WB_MAC_BSC_ERROR("bsc_i2c_write failed, reg_addr: 0x%x, set val: 0x%x, read back valu: 0x%x\n", + DEBUG_ERROR("bsc_i2c_write failed, reg_addr: 0x%x, set val: 0x%x, read back valu: 0x%x\n", operation->reg_addr, operation->reg_val, rd_back_val); return -1; } - WB_MAC_BSC_DEBUG("bsc_i2c_write success, reg_addr: 0x%x, set val: 0x%x, read_back val: 0x%x\n", + DEBUG_VERBOSE("bsc_i2c_write success, reg_addr: 0x%x, set val: 0x%x, read_back val: 0x%x\n", operation->reg_addr, operation->reg_val, rd_back_val); } return 0; @@ -453,49 +535,63 @@ static int handle_operation(struct i2c_client *client, i2c_op_t *operation) for (i = 0; i < MAC_BSC_MAX_RETRY; i++) { ret = handle_operation_write(client, operation); if (ret == 0) { - WB_MAC_BSC_DEBUG("handle_operation_write success, retry: %d\n", i); + DEBUG_VERBOSE("handle_operation_write success, retry: %d\n", i); return 0; } if ((i + 1) < MAC_BSC_MAX_RETRY) { usleep_range(MAC_BSC_RETRY_SLEEP_TIME, MAC_BSC_RETRY_SLEEP_TIME + 1); } } - WB_MAC_BSC_DEBUG("handle_operation_write retry: %d failed, ret: %d, ignore it\n", i, ret); + DEBUG_VERBOSE("handle_operation_write retry: %d failed, ret: %d, ignore it\n", i, ret); return 0; } if (operation->op == I2C_READ) { ret = bsc_i2c_read(client, operation->reg_addr, &operation->reg_val); - WB_MAC_BSC_DEBUG("bsc_i2c_read reg_addr: 0x%x, get val: 0x%x, ret: %d\n", + DEBUG_VERBOSE("bsc_i2c_read reg_addr: 0x%x, get val: 0x%x, ret: %d\n", operation->reg_addr, operation->reg_val, ret); return ret; } - WB_MAC_BSC_ERROR("Unsupport operation type: %d\n", operation->op); + DEBUG_ERROR("Unsupport operation type: %d\n", operation->op); return -EINVAL; } -static int get_mac_reg(struct i2c_client *client, uint32_t reg_addr, uint32_t *reg_value) +static int get_mac_reg(struct i2c_client *client, uint32_t reg_addr, uint32_t *reg_value, uint8_t type) { int i, ret; - i2c_op_t *op; + i2c_op_t *op, *tmp_op; struct mac_data *data; dev_params_t *dev_params; uint32_t val_tmp; + int ops; data = i2c_get_clientdata(client); dev_params = &data->dev_param; + + if (type == TYPE_AVS) { + ops = dev_params->avs_read_ops; + tmp_op = dev_params->avs_read; + } else { + ops = dev_params->vtmon_read_ops; + tmp_op = dev_params->vtmon_read; + } + val_tmp = 0; - for (i = 0; i < dev_params->vtmon_read_ops; i++) { - op = &dev_params->vtmon_read[i]; + for (i = 0; i < ops; i++) { + op = tmp_op + i; if (i == dev_params->sbus_addr_op) { - op->reg_val = reg_addr; + if (type == TYPE_AVS) { + op->reg_addr = reg_addr; + } else { + op->reg_val = reg_addr; + } } - WB_MAC_BSC_DEBUG("Start to handle %s operation, step: %d, reg_addr: 0x%x, reg_value: 0x%x, read back flag: %d\n", + DEBUG_VERBOSE("Start to handle %s operation, step: %d, reg_addr: 0x%x, reg_value: 0x%x, read back flag: %d\n", op->op == I2C_READ ? "I2C_READ" : "I2C_WRITE", i, op->reg_addr, op->reg_val, op->read_back); ret = handle_operation(client, op); if (ret < 0) { - WB_MAC_BSC_ERROR("handle operation %d failed, ret: %d\n", i, ret); + DEBUG_ERROR("handle operation %d failed, ret: %d\n", i, ret); return ret; } if (op->op == I2C_READ) { @@ -504,22 +600,22 @@ static int get_mac_reg(struct i2c_client *client, uint32_t reg_addr, uint32_t *r if (i == dev_params->sbus_error_op) { if (val_tmp & dev_params->sbus_error_mask) { - WB_MAC_BSC_ERROR("SBUS error seen, status value: 0x%x\n", op->reg_val); + DEBUG_ERROR("SBUS error seen, status value: 0x%x\n", op->reg_val); return -EIO; } - WB_MAC_BSC_DEBUG("Error status check ok, status: 0x%x, error_mask: 0x%x \n", + DEBUG_VERBOSE("Error status check ok, status: 0x%x, error_mask: 0x%x \n", val_tmp, dev_params->sbus_error_mask); } } if (val_tmp == reg_addr) { - WB_MAC_BSC_ERROR("get mac register error, register value: 0x%x equal to reg_addr: 0x%x\n", + DEBUG_ERROR("get mac register error, register value: 0x%x equal to reg_addr: 0x%x\n", val_tmp, reg_addr); return -EIO; } *reg_value = val_tmp; - WB_MAC_BSC_DEBUG("get_mac_reg success, reg_addr: 0x%x, reg_value: 0x%x", reg_addr, *reg_value); + DEBUG_VERBOSE("get_mac_reg success, reg_addr: 0x%x, reg_value: 0x%x", reg_addr, *reg_value); return 0; } @@ -535,14 +631,15 @@ static int read_vtmon(struct i2c_client *client, uint8_t vtmon, int *temp) dev_params = &data->dev_param; if (vtmon >= dev_params->vtmon_instances) { - WB_MAC_BSC_ERROR("VTMON index [%d] greater or equal to VTMON instance number: %d\n", + DEBUG_ERROR("VTMON index [%d] greater or equal to VTMON instance number: %d\n", vtmon, dev_params->vtmon_instances); return -1; } + reg_addr = dev_params->vtmon_reg_addrs[vtmon]; - ret = get_mac_reg(client, reg_addr, ®_val); + ret = get_mac_reg(client, reg_addr, ®_val, TYPE_VTMON); if (ret < 0) { - WB_MAC_BSC_ERROR("Read VTMON[%d] failed, reg_addr: 0x%x, ret: %d\n", + DEBUG_ERROR("Read VTMON[%d] failed, reg_addr: 0x%x, ret: %d\n", vtmon, reg_addr, ret); return ret; } @@ -551,10 +648,62 @@ static int read_vtmon(struct i2c_client *client, uint8_t vtmon, int *temp) *temp = ((dev_params->vtmon_scalar * vtmon_val) + dev_params->vtmon_offset) / 10; if ((*temp / 1000 < -40) || (*temp / 1000 > 120)) { - WB_MAC_BSC_ERROR("MAC temp invalid, vtmon: %d, temp: %d\n", vtmon, *temp); + DEBUG_ERROR("MAC temp invalid, vtmon: %d, temp: %d\n", vtmon, *temp); return -EINVAL; } - WB_MAC_BSC_DEBUG("Read mac temp success, index: %d, value: %d\n", vtmon + 1, *temp); + DEBUG_VERBOSE("Read mac temp success, index: %d, value: %d\n", vtmon + 1, *temp); + return 0; +} + +static int read_avs(struct i2c_client *client, uint8_t avs_index, uint32_t *avs_val) +{ + struct mac_data *data; + dev_params_t *dev_params; + avs_info_t *avs_info; + int ret, i; + uint32_t tmp_avs_val; + uint32_t avs_reg_addr; + uint32_t avs_reg_offset; + uint32_t avs_reg_mask; + bool avs_read_success = false; + *avs_val = 0; + + data = i2c_get_clientdata(client); + dev_params = &data->dev_param; + + if (avs_index >= dev_params->avs_info_instances) { + DEBUG_ERROR("avs index [%d] greater or equal to avs instance number: %d\n", + avs_index, dev_params->avs_info_instances); + return -EINVAL; + } + + for (i = 0; i < MAC_BSC_AVS_REG_MAX_NUM; i++) { + avs_info = &dev_params->avs_info[avs_index][i]; + avs_reg_addr = avs_info->avs_reg_addr; + avs_reg_offset = avs_info->avs_reg_offset; + avs_reg_mask = avs_info->avs_reg_mask; + + if ((avs_reg_addr == 0) && (avs_reg_offset == 0) && (avs_reg_mask == 0)) { + break; + } + ret = get_mac_reg(client, avs_reg_addr, &tmp_avs_val, TYPE_AVS); + if (ret < 0) { + DEBUG_ERROR("Read avs[%d] index[%d] failed, avs_reg_addr: 0x%x, ret: %d\n", + avs_index, i, avs_reg_addr, ret); + return ret; + } + DEBUG_VERBOSE("Read avs val success, avs%d, index: %d, value: %x\n", avs_index, i, tmp_avs_val); + tmp_avs_val = (tmp_avs_val >> avs_reg_offset) & avs_reg_mask; + *avs_val = (*avs_val << fls(avs_reg_mask)) | tmp_avs_val; + avs_read_success = true; + } + + if (!avs_read_success) { + DEBUG_ERROR("Read avs val fail, avs config error\n"); + return -EINVAL; + } + + DEBUG_VERBOSE("Read avs val success, index: %d, value: %x\n", avs_index + 1, *avs_val); return 0; } @@ -569,12 +718,30 @@ static ssize_t show_mac_temp(struct device *dev, struct device_attribute *da, ch ret = read_vtmon(client, temp_index - 1, &temp); if (ret < 0) { temp = -MAC_TEMP_INVALID; - WB_MAC_BSC_ERROR("get_mactemp index: %d failed, ret = %d\n", temp_index, ret); + DEBUG_ERROR("get_mactemp index: %d failed, ret = %d\n", temp_index, ret); } mutex_unlock(&data->update_lock); return snprintf(buf, PAGE_SIZE, "%d\n", temp); } +static ssize_t show_mac_avs(struct device *dev, struct device_attribute *da, char *buf) +{ + struct mac_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + u32 avs_index = to_sensor_dev_attr(da)->index; + int ret; + u32 avs_val; + + mutex_lock(&data->update_lock); + ret = read_avs(client, avs_index - 1, &avs_val); + mutex_unlock(&data->update_lock); + if (ret < 0) { + DEBUG_ERROR("get_mac_avs index: %d failed, ret = %d\n", avs_index, ret); + return ret; + } + return snprintf(buf, PAGE_SIZE, "0x%02x\n", avs_val); +} + static ssize_t show_mac_max_temp(struct device *dev, struct device_attribute *da, char *buf) { struct mac_data *data = dev_get_drvdata(dev); @@ -590,7 +757,7 @@ static ssize_t show_mac_max_temp(struct device *dev, struct device_attribute *da for (i = 0; i < dev_params->vtmon_instances ; i++) { ret = read_vtmon(client, i, &tmp); if (ret < 0) { - WB_MAC_BSC_ERROR("Get mactemp failed, temp index: %d, ret = %d\n", + DEBUG_ERROR("Get mactemp failed, temp index: %d, ret = %d\n", i, ret); tmp = -MAC_TEMP_INVALID; } @@ -619,6 +786,16 @@ static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_I static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX15); static SENSOR_DEVICE_ATTR(temp99_input, S_IRUGO, show_mac_max_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(avs1, S_IRUGO, show_mac_avs, NULL, 1); +static SENSOR_DEVICE_ATTR(avs2, S_IRUGO, show_mac_avs, NULL, 2); +static SENSOR_DEVICE_ATTR(avs3, S_IRUGO, show_mac_avs, NULL, 3); +static SENSOR_DEVICE_ATTR(avs4, S_IRUGO, show_mac_avs, NULL, 4); +static SENSOR_DEVICE_ATTR(avs5, S_IRUGO, show_mac_avs, NULL, 5); +static SENSOR_DEVICE_ATTR(avs6, S_IRUGO, show_mac_avs, NULL, 6); +static SENSOR_DEVICE_ATTR(avs7, S_IRUGO, show_mac_avs, NULL, 7); +static SENSOR_DEVICE_ATTR(avs8, S_IRUGO, show_mac_avs, NULL, 8); +static SENSOR_DEVICE_ATTR(avs9, S_IRUGO, show_mac_avs, NULL, 9); + static struct attribute *mac_hwmon_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, @@ -636,6 +813,15 @@ static struct attribute *mac_hwmon_attrs[] = { &sensor_dev_attr_temp14_input.dev_attr.attr, &sensor_dev_attr_temp15_input.dev_attr.attr, &sensor_dev_attr_temp99_input.dev_attr.attr, + &sensor_dev_attr_avs1.dev_attr.attr, + &sensor_dev_attr_avs2.dev_attr.attr, + &sensor_dev_attr_avs3.dev_attr.attr, + &sensor_dev_attr_avs4.dev_attr.attr, + &sensor_dev_attr_avs5.dev_attr.attr, + &sensor_dev_attr_avs6.dev_attr.attr, + &sensor_dev_attr_avs7.dev_attr.attr, + &sensor_dev_attr_avs8.dev_attr.attr, + &sensor_dev_attr_avs9.dev_attr.attr, NULL }; ATTRIBUTE_GROUPS(mac_hwmon); @@ -653,11 +839,11 @@ static void mac_bsc_setup(struct i2c_client *client) for (i = 0; i < dev_params->sbus_setup_ops; i++) { ret = bsc_i2c_read(client, dev_params->sbus_setup[i].reg_addr, ®_value); if ((ret < 0) || (reg_value != dev_params->sbus_setup[i].reg_val)) { - WB_MAC_BSC_DEBUG("bsc setup op%d, ret: %d, reg_addr: 0x%x, read value: 0x%x not equal to set value: 0x%x\n", + DEBUG_VERBOSE("bsc setup op%d, ret: %d, reg_addr: 0x%x, read value: 0x%x not equal to set value: 0x%x\n", i, ret, dev_params->sbus_setup[i].reg_addr, reg_value, dev_params->sbus_setup[i].reg_val); bsc_i2c_write(client, dev_params->sbus_setup[i].reg_addr, dev_params->sbus_setup[i].reg_val); } else { - WB_MAC_BSC_DEBUG("bsc setup op%d, reg_addr: 0x%x, read value: 0x%x equal to set value: 0x%x\n", + DEBUG_VERBOSE("bsc setup op%d, reg_addr: 0x%x, read value: 0x%x equal to set value: 0x%x\n", i, dev_params->sbus_setup[i].reg_addr, reg_value, dev_params->sbus_setup[i].reg_val); } } @@ -669,14 +855,14 @@ static int mac_bsc_init(struct i2c_client *client) int ret, mac_id; uint32_t reg_value; - ret = get_mac_reg(client, MAC_ID_REG, ®_value); + ret = get_mac_reg(client, MAC_ID_REG, ®_value, TYPE_VTMON); if (ret < 0) { - WB_MAC_BSC_ERROR("Get MAC ID failed, reg_addr: 0x%x, ret = %d\n", + DEBUG_ERROR("Get MAC ID failed, reg_addr: 0x%x, ret = %d\n", MAC_ID_REG, ret); return ret; } - WB_MAC_BSC_DEBUG("Get MAC ID success, reg_addr: 0x%x, value: 0x%x \n", + DEBUG_VERBOSE("Get MAC ID success, reg_addr: 0x%x, value: 0x%x \n", MAC_ID_REG, reg_value); mac_id = reg_value & 0xffff; return mac_id; @@ -702,10 +888,14 @@ static int mac_bsc_config_check(dev_params_t *dev_params) i2c_op_t *err_op; i2c_op_t *addr_op; + if (dev_params->not_support_vtmon) { + return 0; + } + /* vtmon_instances should not more than the MAC_BSC_MAX_TEMP_NUM */ if ((dev_params->vtmon_instances > MAC_BSC_MAX_TEMP_NUM) || (dev_params->vtmon_instances <= 0)) { - WB_MAC_BSC_ERROR("VTMON instance number %d more than the max number: %d\n", + DEBUG_ERROR("VTMON instance number %d more than the max number: %d\n", dev_params->vtmon_instances, MAC_BSC_MAX_TEMP_NUM); return -1; } @@ -713,7 +903,7 @@ static int mac_bsc_config_check(dev_params_t *dev_params) /* vtmon read operation steps should not more than the MAC_BSC_MAX_READ_REG_STEP */ if ((dev_params->vtmon_read_ops > MAC_BSC_MAX_READ_REG_STEP) || (dev_params->vtmon_read_ops <=0)) { - WB_MAC_BSC_ERROR("VTMON read ops number %d more than the max step: %d\n", + DEBUG_ERROR("VTMON read ops number %d more than the max step: %d\n", dev_params->vtmon_read_ops, MAC_BSC_MAX_READ_REG_STEP); return -1; } @@ -721,7 +911,7 @@ static int mac_bsc_config_check(dev_params_t *dev_params) /* the last operation must be I2C_READ to get temperature register value */ last_op = &dev_params->vtmon_read[dev_params->vtmon_read_ops - 1]; if (last_op->op != I2C_READ) { - WB_MAC_BSC_ERROR("VTMON read ops config error, last operation not I2C_READ, last step: %d, op_code: %d\n", + DEBUG_ERROR("VTMON read ops config error, last operation not I2C_READ, last step: %d, op_code: %d\n", dev_params->vtmon_read_ops - 1, last_op->op); return -1; } @@ -729,7 +919,7 @@ static int mac_bsc_config_check(dev_params_t *dev_params) /* the address operation steps should not more than the vtmon_read_ops and not the last step */ if ((dev_params->sbus_addr_op >= (dev_params->vtmon_read_ops - 1)) || (dev_params->sbus_addr_op < 0)) { - WB_MAC_BSC_ERROR("VTMON addr op step invalid, index %d, read ops: %d\n", + DEBUG_ERROR("VTMON addr op step invalid, index %d, read ops: %d\n", dev_params->sbus_addr_op, dev_params->vtmon_read_ops); return -1; } @@ -737,14 +927,14 @@ static int mac_bsc_config_check(dev_params_t *dev_params) /* the address operation must be I2C_WRITE to set temperature register address */ addr_op = &dev_params->vtmon_read[dev_params->sbus_addr_op]; if (addr_op->op != I2C_WRITE) { - WB_MAC_BSC_ERROR("VTMON addr op config error, addr operation not I2C_WRITE, addr op step: %d, op_code: %d\n", + DEBUG_ERROR("VTMON addr op config error, addr operation not I2C_WRITE, addr op step: %d, op_code: %d\n", dev_params->sbus_addr_op, addr_op->op); return -1; } /* the error status operation steps should not more than the vtmon_read_ops and not the last step */ if (dev_params->sbus_error_op >= (dev_params->vtmon_read_ops - 1)) { - WB_MAC_BSC_ERROR("VTMON error op step invalid, index %d, read ops: %d\n", + DEBUG_ERROR("VTMON error op step invalid, index %d, read ops: %d\n", dev_params->sbus_error_op, dev_params->vtmon_read_ops); return -1; } @@ -753,30 +943,30 @@ static int mac_bsc_config_check(dev_params_t *dev_params) if (dev_params->sbus_error_op >=0) { err_op = &dev_params->vtmon_read[dev_params->sbus_error_op]; if (err_op->op != I2C_READ) { - WB_MAC_BSC_ERROR("VTMON error op config error, error operation not I2C_READ, error op step: %d, op_code: %d\n", + DEBUG_ERROR("VTMON error op config error, error operation not I2C_READ, error op step: %d, op_code: %d\n", dev_params->sbus_error_op, err_op->op); return -1; } } - WB_MAC_BSC_DEBUG("dev_params check ok, instance number: %d, read_ops: %d, addr_op: %d, error_op: %d\n", + DEBUG_VERBOSE("dev_params check ok, instance number: %d, read_ops: %d, addr_op: %d, error_op: %d\n", dev_params->vtmon_instances, dev_params->vtmon_read_ops, dev_params->sbus_addr_op, dev_params->sbus_error_op); return 0; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0) static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id) #else static int mac_probe(struct i2c_client *client) #endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0) + const struct i2c_device_id *id = i2c_client_get_device_id(client); +#endif struct mac_data *data; int ret, mac_id, index; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) - const struct i2c_device_id *id = i2c_match_id(mac_id_table, client); -#endif - WB_MAC_BSC_DEBUG("=========mac_probe(%d-%04x)===========\n", + DEBUG_VERBOSE("=========mac_probe(%d-%04x)===========\n", client->adapter->nr, client->addr); if (!client->adapter->algo->master_xfer) { @@ -793,10 +983,6 @@ static int mac_probe(struct i2c_client *client) data->client = client; i2c_set_clientdata(client, data); - if (!id) { - dev_err(&client->dev, "Failed to match i2c device id.\n"); - return -ENODEV; - } mac_id = id->driver_data; ret = find_mac_config(mac_id, &index); if (ret < 0) { @@ -834,7 +1020,7 @@ static int mac_probe(struct i2c_client *client) } } - WB_MAC_BSC_DEBUG("mac_id: 0x%x, config index: %d\n", mac_id, index); + DEBUG_VERBOSE("mac_id: 0x%x, config index: %d\n", mac_id, index); mutex_init(&data->update_lock); data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, mac_hwmon_groups); @@ -848,7 +1034,7 @@ static int mac_probe(struct i2c_client *client) return 0; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0) static int mac_remove(struct i2c_client *client) #else static void mac_remove(struct i2c_client *client) @@ -857,10 +1043,9 @@ static void mac_remove(struct i2c_client *client) struct mac_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0) return 0; -#else - return; #endif } @@ -870,6 +1055,8 @@ static const struct i2c_device_id mac_id_table[] = { { "wb_mac_bsc_td4", TD4 }, { "wb_mac_bsc_th3", TH3 }, { "wb_mac_bsc_th4", TH4 }, + { "wb_mac_bsc_th5", TH5 }, + { "wb_mac_bsc_th6", TH6 }, {} }; MODULE_DEVICE_TABLE(i2c, mac_id_table); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.c new file mode 100644 index 0000000000..de455b7a89 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.c @@ -0,0 +1,600 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_mdio_dev.h" + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static int phy_read_ext(mdio_dev_info_t *phy, u32 reg_addr) +{ + int ret; + + ret = mdiobus_write(phy->bus, phy->addr, PHY_EXTERN_ADDR_REG, reg_addr); + if (ret < 0) + { + return ret; + } + + return mdiobus_read(phy->bus, phy->addr, PHY_EXTERN_DATA_REG); +} + +static int phy_write_ext(mdio_dev_info_t *phy, u32 reg_addr, u16 val) +{ + int ret; + + ret = mdiobus_write(phy->bus, phy->addr, PHY_EXTERN_ADDR_REG, reg_addr); + if (ret < 0) + { + return ret; + } + + return mdiobus_write(phy->bus, phy->addr, PHY_EXTERN_DATA_REG, val); +} + +static int phy_dev_read(mdio_dev_info_t *phy, u32 reg_addr) +{ + if (reg_addr > PHY_EXTERN_DATA_REG) { + return phy_read_ext(phy, reg_addr); + } + + return mdiobus_read(phy->bus, phy->addr, reg_addr); +} + +static int phy_dev_write(mdio_dev_info_t *phy, u32 reg_addr, u16 val) +{ + if (reg_addr > PHY_EXTERN_DATA_REG) { + return phy_write_ext(phy, reg_addr, val); + } + + return mdiobus_write(phy->bus, phy->addr, reg_addr, val); +} + +static bool ends_with_suffix(const char *str, const char *suffix) { + size_t str_len = strlen(str); + size_t suffix_len = strlen(suffix); + + if (str_len < suffix_len) { + return false; + } + + return strncmp(str + str_len - suffix_len, suffix, suffix_len) == 0; +} + +static int of_mdio_dev_config_init(mdio_dev_info_t *mdio_dev) +{ + struct device *dev; + int num_regs, i, ret = 0; + dev = mdio_dev->dev; + + ret += of_property_read_string(dev->of_node, "mdio_name", &mdio_dev->name); + ret += of_property_read_string(dev->of_node, "mdio_bus_name", &mdio_dev->mdio_bus_name); + ret += of_property_read_u32(dev->of_node, "addr", &mdio_dev->addr); + if (ret != 0) { + DEBUG_ERROR("Missing required properties\n"); + return -EINVAL; + } + + if (of_property_read_string(dev->of_node, "dev_alias", &mdio_dev->alias)) { + mdio_dev->alias = mdio_dev->name; + } + + num_regs = of_property_count_elems_of_size(dev->of_node, "phy_init_regs", sizeof(u32)); + if (num_regs < 0) { + mdio_dev->phy_need_init = 0; + dev_info(dev, "Not need init.\n"); + return 0; + } + if (num_regs == 0 || num_regs > PHY_REG_INIT_INFO_MAX) { + dev_err(dev, "Invalid reg count %d\n", num_regs); + return -EINVAL; + } + + mdio_dev->phy_need_init = 1; + mdio_dev->reg_init_num = 0; + for (i = 0; i < num_regs; i++) { + ret = of_property_read_u32_index(dev->of_node, "phy_init_regs", i, + &mdio_dev->phy_reg_init[i].phy_reg); + ret += of_property_read_u32_index(dev->of_node, "init_values", i, + &mdio_dev->phy_reg_init[i].init_value); + if (ret) { + dev_err(dev, "Failed to get config%d ret=%d.\n", i, ret); + return ret; + } + + mdio_dev->phy_reg_init[i].mask = 0xffff; + of_property_read_u32_index(dev->of_node, "masks", i, + &mdio_dev->phy_reg_init[i].mask); + + mdio_dev->phy_reg_init[i].delay = 0; + of_property_read_u32_index(dev->of_node, "delays", i, + &mdio_dev->phy_reg_init[i].delay); + + mdio_dev->reg_init_num++; + } + + return 0; +} + +static int mdio_dev_config_init(mdio_dev_info_t *mdio_dev) +{ + mdio_dev_device_t *mdio_dev_device; + + if (mdio_dev->dev->platform_data == NULL) { + dev_err(mdio_dev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + mdio_dev_device = mdio_dev->dev->platform_data; + mdio_dev->name = mdio_dev_device->dev_name; + mdio_dev->alias = mdio_dev_device->dev_name; + mdio_dev->mdio_bus_name = mdio_dev_device->mdio_bus_name; + mdio_dev->addr = mdio_dev_device->addr; + mdio_dev->phy_need_init = 0; + + return 0; +} + +static int mdio_phy_reg_init(mdio_dev_info_t *mdio_dev) +{ + int ret, i; + int value; + + if (!mdio_dev->phy_need_init) { + dev_info(mdio_dev->dev, "Not need init, do nothing\n"); + return 0; + } + + for (i = 0; i < mdio_dev->reg_init_num; i++) { + /* read origin register value */ + DEBUG_VERBOSE("mdio_phy_reg_init: phy_reg:0x%x, init_value:0x%x, mask:0x%x", + mdio_dev->phy_reg_init[i].phy_reg, mdio_dev->phy_reg_init[i].init_value, mdio_dev->phy_reg_init[i].mask); + + if (mdio_dev->phy_reg_init[i].delay != 0) { + usleep_range(mdio_dev->phy_reg_init[i].delay, mdio_dev->phy_reg_init[i].delay + 1); + } + + value = phy_dev_read(mdio_dev, mdio_dev->phy_reg_init[i].phy_reg); + if (value < 0) { + DEBUG_ERROR("read phy addr: 0x%x failed, ret: %d\n", mdio_dev->phy_reg_init[i].phy_reg, value); + return -EIO; + } + DEBUG_VERBOSE("read phy addr 0x%x success, value: 0x%x\n", mdio_dev->phy_reg_init[i].phy_reg, value); + DEBUG_VERBOSE("write to phy raw value: 0x%x\n", mdio_dev->phy_reg_init[i].init_value); + value &= ~(mdio_dev->phy_reg_init[i].mask); + value |= mdio_dev->phy_reg_init[i].init_value; + + ret = phy_dev_write(mdio_dev, mdio_dev->phy_reg_init[i].phy_reg, value); + if (ret < 0) { + dev_err(mdio_dev->dev, "write phy addr: 0x%x failed, ret: %d\n", mdio_dev->phy_reg_init[i].phy_reg, ret); + return -EIO; + } + dev_info(mdio_dev->dev, "write phy addr 0x%x success, value: 0x%x\n", mdio_dev->phy_reg_init[i].phy_reg, value); + } + return 0; +} + +static ssize_t alias_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + + if (!mdio_dev) { + DEBUG_ERROR("alias show mdio dev is null.\n"); + return -ENODEV; + } + return snprintf(buf, PAGE_SIZE, "%s\n", mdio_dev->alias); +} + +static int phy_id_read(mdio_dev_info_t *mdio_dev, uint32_t *phy_id) +{ + int id1, id2; + + id1 = phy_dev_read(mdio_dev, MII_PHYSID1); + id2 = phy_dev_read(mdio_dev, MII_PHYSID2); + if (id1 < 0 || id2 < 0) { + DEBUG_ERROR("phy_id read fail, ret1:%d, ret2:%d.\n",id1, id2); + return -EIO; + } + + *phy_id = ((id1 << 16) | id2); + if (*phy_id == 0 || *phy_id == 0xffffffff) { + DEBUG_ERROR("illegal phy_id :0x%x.\n", *phy_id); + return -EINVAL; + } + + return 0; +} + +static ssize_t phy_id_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + int ret; + uint32_t phy_id; + + if (!mdio_dev) { + DEBUG_ERROR("phy_id show mdio dev is null.\n"); + return -ENODEV; + } + + mutex_lock(&mdio_dev->lock); + ret = phy_id_read(mdio_dev, &phy_id); + mutex_unlock(&mdio_dev->lock); + if (ret < 0) { + DEBUG_ERROR("phy_id read fail, ret:%d.\n", ret); + return ret; + } + + return snprintf(buf, PAGE_SIZE, "0x%x\n", phy_id); +} + +static ssize_t phy_type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + int ret, phy_id, i; + + if (!mdio_dev) { + DEBUG_ERROR("phy_type show mdio dev is null.\n"); + return -ENODEV; + } + + mutex_lock(&mdio_dev->lock); + ret = phy_id_read(mdio_dev, &phy_id); + mutex_unlock(&mdio_dev->lock); + if (ret < 0) { + DEBUG_ERROR("phy_id read fail, ret:%d.\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(phy_type_infos); i++) { + if (phy_type_infos[i].phy_id == phy_id) { + return snprintf(buf, PAGE_SIZE, "%s\n", phy_type_infos[i].phy_type); + } + } + + return snprintf(buf, PAGE_SIZE, "%s\n", UNKNOWN_PHY_TYPE); +} + +static int phy_status_read(mdio_dev_info_t *mdio_dev) +{ + int ret, i; + + /* link status need read twice */ + for (i = 0; i < 2; i++) { + ret = phy_dev_read(mdio_dev, MII_BMSR); + if (ret < 0) { + DEBUG_ERROR("link_status read fail, ret:%d.\n", ret); + return -EIO; + } + } + DEBUG_VERBOSE("link_status read success, ret:0x%x.\n", ret); + return ret; +} + +static ssize_t phy_link_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + int phy_status; + + if (!mdio_dev) { + DEBUG_ERROR("phy_link_status show mdio dev is null.\n"); + return -ENODEV; + } + + mutex_lock(&mdio_dev->lock); + phy_status = phy_status_read(mdio_dev); + mutex_unlock(&mdio_dev->lock); + if (phy_status < 0) { + DEBUG_ERROR("phy_status read fail, ret:%d.\n", phy_status); + return -EIO; + } + + if (phy_status & BMSR_LSTATUS) { + return snprintf(buf, PAGE_SIZE, "%d\n", PHY_LINK_STS_UP); + } + return snprintf(buf, PAGE_SIZE, "%d\n", PHY_LINK_STS_DOWN); +} + +static ssize_t phy_reset_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + int phy_control; + + if (!mdio_dev) { + DEBUG_ERROR("phy_control show mdio dev is null.\n"); + return -ENODEV; + } + + mutex_lock(&mdio_dev->lock); + phy_control = phy_dev_read(mdio_dev, MII_BMCR); + mutex_unlock(&mdio_dev->lock); + if (phy_control < 0) { + DEBUG_ERROR("phy_control read fail, ret:%d.\n", phy_control); + return -EIO; + } + + if (phy_control & PHY_RESET_BIT) { + return snprintf(buf, PAGE_SIZE, "%d\n", PHY_RESET_ENABLE); + } + return snprintf(buf, PAGE_SIZE, "%d\n", PHY_RESET_DISABLE); +} + +static ssize_t phy_reset_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + u8 val; + int ret, phy_control; + u16 wr_val = 0; + + if (!mdio_dev) { + DEBUG_ERROR("phy_reset_store mdio dev is null.\n"); + return -ENODEV; + } + + val = 0; + ret = kstrtou8(buf, 0, &val); + if (ret) { + DEBUG_ERROR("Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + + if ((val != PHY_RESET_ENABLE) && (val != PHY_RESET_DISABLE)) { + DEBUG_ERROR("input value [%d] not equal 0 or 1\n", val); + return -EINVAL; + } + + mutex_lock(&mdio_dev->lock); + phy_control = phy_dev_read(mdio_dev, MII_BMCR); + if (phy_control < 0) { + DEBUG_ERROR("phy_control read fail, ret:%d.\n", phy_control); + mutex_unlock(&mdio_dev->lock); + return -EIO; + } + + if (val == PHY_RESET_ENABLE) { + wr_val = phy_control | PHY_RESET_BIT; + } else { + wr_val = phy_control & ~PHY_RESET_BIT; + } + + ret = phy_dev_write(mdio_dev, MII_BMCR, wr_val); + mutex_unlock(&mdio_dev->lock); + if (ret < 0) { + DEBUG_ERROR("phy_reset failed, wr_val:0x%x, ret: %d\n", wr_val, ret); + return -EIO; + } + DEBUG_VERBOSE("phy_reset success, wr_val:0x%x\n", wr_val); + return count; +} + +static ssize_t phy_reg_dump(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + int i, offset = 0; + int rd_val; + + if (!mdio_dev) { + DEBUG_ERROR("phy_reg_dump mdio dev is null.\n"); + return -ENODEV; + } + + mutex_lock(&mdio_dev->lock); + for (i = 0; i < ARRAY_SIZE(phy_reg_infos); i++) { + rd_val = phy_dev_read(mdio_dev, phy_reg_infos[i].reg_addr); + if (rd_val < 0) { + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "(0x%02x)%-20s: fail(%d)\n", phy_reg_infos[i].reg_addr, phy_reg_infos[i].reg_name, rd_val); + } else { + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "(0x%02x)%-20s: 0x%04x\n", phy_reg_infos[i].reg_addr, phy_reg_infos[i].reg_name, rd_val); + } + } + mutex_unlock(&mdio_dev->lock); + return offset; +} + +static ssize_t mdio_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + mdio_dev_info_t *mdio_dev = container_of(kobj, mdio_dev_info_t, kobj); + int ret, i, mdio_status; + uint32_t phy_id; + + if (!mdio_dev) { + DEBUG_ERROR("mdio_status show mdio dev is null.\n"); + return -ENODEV; + } + + mutex_lock(&mdio_dev->lock); + for (i = 0; i < MAX_RETRY; i++) { + ret = phy_id_read(mdio_dev, &phy_id); + if (ret < 0) { + mdio_status = MDIO_STATUS_NOT_OK; + DEBUG_ERROR("phy_id read fail, ret:%d.\n", ret); + } else { + mdio_status = MDIO_STATUS_OK; + break; + } + } + mutex_unlock(&mdio_dev->lock); + return snprintf(buf, PAGE_SIZE, "%d\n", mdio_status); +} + +static struct kobj_attribute alias_attribute = __ATTR(alias, S_IRUGO, alias_show, NULL); +static struct kobj_attribute phy_id_attribute = __ATTR(phy_id, S_IRUGO, phy_id_show, NULL); +static struct kobj_attribute phy_type_attribute = __ATTR(phy_type, S_IRUGO, phy_type_show, NULL); +static struct kobj_attribute link_status_attribute = __ATTR(link_status, S_IRUGO, phy_link_status_show, NULL); +static struct kobj_attribute reset_attribute = __ATTR(reset, S_IRUGO | S_IWUSR, phy_reset_show, phy_reset_store); +static struct kobj_attribute phy_reg_dump_attribute = __ATTR(phy_reg_dump, S_IRUGO, phy_reg_dump, NULL); +static struct kobj_attribute mdio_status_attribute = __ATTR(mdio_status, S_IRUGO, mdio_status_show, NULL); + +static struct attribute *mdio_dev_attrs[] = { + &alias_attribute.attr, + &phy_id_attribute.attr, + &link_status_attribute.attr, + &reset_attribute.attr, + &phy_reg_dump_attribute.attr, + &phy_type_attribute.attr, + &mdio_status_attribute.attr, + NULL, +}; + +static struct attribute_group mdio_dev_attr_group = { + .attrs = mdio_dev_attrs, +}; + +static ssize_t mdio_dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct kobj_attribute *attribute; + + attribute = container_of(attr, struct kobj_attribute, attr); + + if (!attribute->show) { + DEBUG_ERROR("mdio dev attr show is null.\n"); + return -ENOSYS; + } + + return attribute->show(kobj, attribute, buf); +} + +static ssize_t mdio_dev_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t len) +{ + struct kobj_attribute *attribute; + + attribute = container_of(attr, struct kobj_attribute, attr); + + if (!attribute->store) { + DEBUG_ERROR("mdio dev attr store is null.\n"); + return -ENOSYS; + } + + return attribute->store(kobj, attribute, buf, len); +} + +static const struct sysfs_ops mdio_dev_sysfs_ops = { + .show = mdio_dev_attr_show, + .store = mdio_dev_attr_store, +}; + +static void mdio_dev_obj_release(struct kobject *kobj) +{ + return; +} + +static struct kobj_type mdio_dev_ktype = { + .sysfs_ops = &mdio_dev_sysfs_ops, + .release = mdio_dev_obj_release, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0) + .default_attrs = NULL, +#endif +}; + +static int mdio_dev_probe(struct platform_device *pdev) +{ + mdio_dev_info_t *mdio_dev; + int ret; + + mdio_dev = devm_kzalloc(&pdev->dev, sizeof(mdio_dev_info_t), GFP_KERNEL); + if (!mdio_dev) { + dev_err(&pdev->dev, "mdio_dev memory allocation failed\n"); + return -ENOMEM; + } + mdio_dev->dev = &pdev->dev; + mutex_init(&mdio_dev->lock); + + if (pdev->dev.of_node) { + ret = of_mdio_dev_config_init(mdio_dev); + } else { + ret = mdio_dev_config_init(mdio_dev); + } + if (ret) { + dev_err(&pdev->dev, "mdio_dev_config_init fail, ret: %d\n", ret); + return -EINVAL; + } + + if (!ends_with_suffix(mdio_dev->name, MDIO_NAME_SUFFIX)) { + dev_err(&pdev->dev, "mdio_name:%s config err, not end with phy:%s.\n", mdio_dev->name, MDIO_NAME_SUFFIX); + return -EINVAL; + } + + mdio_dev->bus = mdio_find_bus(mdio_dev->mdio_bus_name); + if (!mdio_dev->bus) { + dev_err(&pdev->dev, "find mdio bus name: %s fail.\n", mdio_dev->mdio_bus_name); + return -ENOMEM; + } + + ret = mdio_phy_reg_init(mdio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "mdio_phy_reg_init fail, ret: %d\n", ret); + return ret; + } + + /* creat parent dir by dev name in /sys/logic_dev */ + ret = kobject_init_and_add(&mdio_dev->kobj, &mdio_dev_ktype, logic_dev_kobj, "%s", mdio_dev->name); + if (ret) { + kobject_put(&mdio_dev->kobj); + dev_err(&pdev->dev, "Failed to creat parent dir: %s, ret: %d\n", mdio_dev->name, ret); + return ret; + } + + mdio_dev->sysfs_group = &mdio_dev_attr_group; + ret = sysfs_create_group(&mdio_dev->kobj, mdio_dev->sysfs_group); + if (ret) { + dev_err(&pdev->dev, "Failed to create %s sysfs group, ret: %d\n", mdio_dev->name, ret); + goto remove_parent_kobj; + } + platform_set_drvdata(pdev, mdio_dev); + + dev_info(&pdev->dev, "registered %s with mdio bus: %s, phy address: 0x%x success\n", + mdio_dev->name, mdio_dev->mdio_bus_name, mdio_dev->addr); + return 0; +remove_parent_kobj: + kobject_put(&mdio_dev->kobj); + return ret; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,11,0) +static void mdio_dev_remove(struct platform_device *pdev) +#else +static int mdio_dev_remove(struct platform_device *pdev) +#endif +{ + mdio_dev_info_t *mdio_dev; + mdio_dev = platform_get_drvdata(pdev); + + if (mdio_dev->sysfs_group) { + dev_dbg(&pdev->dev, "Unregister %s mdio_dev sysfs group\n", mdio_dev->name); + sysfs_remove_group(&mdio_dev->kobj, (const struct attribute_group *)mdio_dev->sysfs_group); + kobject_put(&mdio_dev->kobj); + mdio_dev->sysfs_group = NULL; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0) + return 0; +#endif +} + +static const struct of_device_id mdio_dev_of_match[] = { + { .compatible = MDIO_DEV_COMPATIBLE_NAME }, + {} +}; + +static struct platform_driver mdio_dev_driver = { + .probe = mdio_dev_probe, + .remove = mdio_dev_remove, + .driver = { + .name = "wb_mdio_dev", + .owner = THIS_MODULE, + .of_match_table = mdio_dev_of_match, + }, +}; + +module_platform_driver(mdio_dev_driver); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("MDIO Device Driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.h new file mode 100644 index 0000000000..47ee65e028 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_dev.h @@ -0,0 +1,97 @@ +#ifndef __WB_MDIO_DEV_H__ +#define __WB_MDIO_DEV_H__ +#include +#include +#include + +#define MDIO_DEV_COMPATIBLE_NAME "wb_mdio_dev" + +#define PHY_REG_INIT_INFO_MAX (16) +#define NAME_LEN (32) +#define MAX_RETRY (3) +#define PHY_EXTERN_ADDR_REG (0x1e) +#define PHY_EXTERN_DATA_REG (0x1f) + +#define PHY_LINK_STS_UP (1) +#define PHY_LINK_STS_DOWN (0) +#define PHY_RESET_BIT BIT(15) +#define PHY_RESET_ENABLE (1) +#define PHY_RESET_DISABLE (0) +#define MDIO_STATUS_OK (0) +#define MDIO_STATUS_NOT_OK (1) +#define UNKNOWN_PHY_TYPE "NA" +#define MDIO_NAME_SUFFIX "_phy" + +typedef struct { + const char phy_type[NAME_LEN]; + uint32_t phy_id; +} phy_type_info_t; + +phy_type_info_t phy_type_infos[] = { + {.phy_type = "BCM53134O_GPHY", .phy_id = 0xae025350}, + {.phy_type = "B50210S", .phy_id = 0x600d8595}, + {.phy_type = "YT8010", .phy_id = 0x00000309}, + {.phy_type = "YT8010AS", .phy_id = 0x4f51eb19}, + {.phy_type = "YT8510", .phy_id = 0x00000109}, + {.phy_type = "YT8511", .phy_id = 0x0000010a}, + {.phy_type = "YT8512", .phy_id = 0x00000118}, + {.phy_type = "YT8512B", .phy_id = 0x00000128}, + {.phy_type = "YT8521", .phy_id = 0x0000011a}, + {.phy_type = "YT8531S", .phy_id = 0x4f51e91a}, + {.phy_type = "YT8531", .phy_id = 0x4f51e91b}, + {.phy_type = "YT8614", .phy_id = 0x4F51E899}, + {.phy_type = "YT8618", .phy_id = 0x0000e889}, + {.phy_type = "YT8821", .phy_id = 0x4f51ea10}, + {.phy_type = "BCM53134O_SGMII", .phy_id = 0x143bff0}, +}; + +typedef struct { + const char reg_name[NAME_LEN]; + uint32_t reg_addr; +} phy_reg_info_t; + +phy_reg_info_t phy_reg_infos[] = { + {.reg_name = "CONTROL", .reg_addr = MII_BMCR}, + {.reg_name = "STATUS", .reg_addr = MII_BMSR}, + {.reg_name = "PHYS_ID1", .reg_addr = MII_PHYSID1}, + {.reg_name = "PHYS_ID2", .reg_addr = MII_PHYSID2}, + {.reg_name = "ADVERTISEMENT", .reg_addr = MII_ADVERTISE}, + {.reg_name = "LPA", .reg_addr = MII_LPA}, + {.reg_name = "EXPANSION", .reg_addr = MII_EXPANSION}, + {.reg_name = "CTRL1000", .reg_addr = MII_CTRL1000}, + {.reg_name = "STAT1000", .reg_addr = MII_STAT1000}, + {.reg_name = "MMD_CTRL", .reg_addr = MII_MMD_CTRL}, + {.reg_name = "MMD_DATA", .reg_addr = MII_MMD_DATA}, +}; + +typedef struct { + uint32_t phy_reg; + uint32_t init_value; + uint32_t mask; + uint32_t delay; +} phy_reg_init_info_t; + +typedef struct mdio_dev_info { + const char *name; + const char *alias; + const char *mdio_bus_name; + struct attribute_group *sysfs_group; + uint32_t addr; + struct mii_bus *bus; + phy_reg_init_info_t phy_reg_init[PHY_REG_INIT_INFO_MAX]; + int phy_need_init; + uint32_t reg_init_num; + struct device *dev; + struct kobject kobj; + struct mutex lock; +} mdio_dev_info_t; + +typedef struct mdio_dev_device_s { + const char *dev_name; + const char *alias; + const char *mdio_bus_name; + uint32_t addr; + int device_flag; +} mdio_dev_device_t; + +#endif /* __WB_MDIO_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_rc32312.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_rc32312.c new file mode 100644 index 0000000000..a85d0b05ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_rc32312.c @@ -0,0 +1,895 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RC32312_PAGE_REG (0xfd) +#define RC32312_APLL_EVENT_REG (0x6e) +#define RC32312_APLL_CLEAR_VAL (0x03) +#define RC32312_APLL_CLEAR_MASK (0x03) +#define RC32312_APLL_LOL_EVENT_REG (0x6f) +#define RC32312_APLL_LOL_EVENT_CLEAR_VAL (0x0) +#define RC32312_APLL_LOL_EVENT_CLEAR_MASK (0x0f) +#define RC32312_APLL_EVENT_CLEAR_VAL (0x7f) +#define RC32312_APLL_EVENT_CLEAR_MASK (0x7f) +#define RC32312_APLL_EXT_EVENT_REG (0x70) +#define RC32312_XTAL_LOS_CNT_REG (0x79) + +#define RC32312_APLL_PAGE (2) +#define RC32312_APLL_STS_REG (0x71) +#define RC32312_OUT_CTRL_EN (0x0001) +#define RC32312_OUT_CTRL_DIS (0x0002) + +#define RC32312_XTAL_LOS_PAGE (1) +#define RC32312_XTAL_LOS_EVT_REG (0x78) +#define RC32312_XTAL_LOS_STS_REG (0x7a) + +#define RC32312_CLOCK_REG_INFO_MASK (0x1) +#define RC32312_CLOCK_FAULT_XTAL (0) +#define RC32312_CLOCK_FAULT_BUS (1) +#define RC32312_CLOCK_FAULT_APLL (4) + +#define RC32312_VENDOR_ID_PAGE (0) +#define RC32312_VENDOR_ID_REG (0x0) +#define RC32312_VENDOR_ID (0x1033) + +#define RC32312_CLOCK_STATUS_NORMAL (0) +#define RC32312_CLOCK_STATUS_ABNORMAL (1) + +#define RC21012_LOSMON_PAGE (0) +#define RC21012_LOSMON4_STS_REG (0x99) +#define RC21012_LOSMON4_CNT_REG (0x9b) +#define RC21012_LOSMON4_CNT_CLEAR_VAL (0x0) +#define RC21012_LOSMON4_CNT_CLEAR_MASK (0x0f) + +#define RC21012_APLL_PAGE (1) +#define RC21012_APLL_STS_REG (0x3f) +#define RC21012_APLL_LOL_CNT_REG (0x41) +#define RC21012_APLL_LOL_CNT_CLEAR_VAL (0x0) +#define RC21012_APLL_LOL_CNT_CLEAR_MASK (0x0f) + +/* RC38112 register definitions */ +#define RC38112_XTAL_PAGE (8) /* Page number for RC38112 registers */ +#define RC38112_XTAL_LOS_EVT_REG (0x08) +#define RC38112_XTAL_LOS_EVT_CLEAR_VAL (0x3) +#define RC38112_XTAL_LOS_EVT_CLEAR_MASK (0x3) + +#define RC38112_XTAL_LOS_CNT_REG (0x09) +#define RC38112_XTAL_LOS_CNT_CLEAR_VAL (0x0) +#define RC38112_XTAL_LOS_CNT_CLEAR_MASK (0x0f) + +#define RC38112_APLL_EVENT_REG (0xba) +#define RC38112_APLL_EVENT_CLEAR_VAL (0x7f) +#define RC38112_APLL_EVENT_CLEAR_MASK (0x7f) + +#define RC38112_APLL_LOL_EVENT_REG (0xbb) +#define RC38112_APLL_LOL_EVENT_CLEAR_VAL (0x0) +#define RC38112_APLL_LOL_EVENT_CLEAR_MASK (0x0f) + +#define RC38112_APLL_LOL_CLEAR_REG (0xbc) +#define RC38112_APLL_LOL_CLEAR_CLEAR_VAL (0x1) +#define RC38112_APLL_LOL_CLEAR_CLEAR_MASK (0x0f) + +#define RC38112_APLL_STS_REG (0xbd) +#define RC38112_APLL_STS_MASK (0x1) + +#define RC38112_XTAL_LOS_STS_REG (0x0a) +#define RC38112_XTAL_LOS_STS_MASK (0x1) + +#define RC38112_APLL_PAGE (0) /* Page number for RC38112 registers */ + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +enum attrs { + APLL_STATUS, + APLL_COUNT, + APLL_EVENT, + XTAL_LOS_EVT, + XTAL_LOS_CNT, + XTAL_LOS_STS, + LOSMON4_STS, + LOSMON4_CNT, +}; + +typedef struct { + int attr; + int page; + int reg; +} rc32312_attr_match_t; + +rc32312_attr_match_t rc21012_attr_infos[] = { + {APLL_STATUS, RC21012_APLL_PAGE, RC21012_APLL_STS_REG}, + {APLL_COUNT, RC21012_APLL_PAGE, RC21012_APLL_LOL_CNT_REG}, + {LOSMON4_STS, RC21012_LOSMON_PAGE, RC21012_LOSMON4_STS_REG}, + {LOSMON4_CNT, RC21012_LOSMON_PAGE, RC21012_LOSMON4_CNT_REG}, +}; + +rc32312_attr_match_t rc32312_attr_infos[] = { + {APLL_STATUS, RC32312_APLL_PAGE, RC32312_APLL_STS_REG}, + {APLL_COUNT, RC32312_APLL_PAGE, RC32312_APLL_LOL_EVENT_REG}, + {APLL_EVENT, RC32312_APLL_PAGE, RC32312_APLL_EVENT_REG}, + {XTAL_LOS_EVT, RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_EVT_REG}, + {XTAL_LOS_CNT, RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_CNT_REG}, + {XTAL_LOS_STS, RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_STS_REG}, +}; + +rc32312_attr_match_t rc38112_attr_infos[] = { + {APLL_STATUS, RC38112_APLL_PAGE, RC38112_APLL_STS_REG}, + {APLL_COUNT, RC38112_APLL_PAGE, RC38112_APLL_LOL_EVENT_REG}, + {APLL_EVENT, RC38112_APLL_PAGE, RC38112_APLL_EVENT_REG}, + {XTAL_LOS_EVT, RC38112_XTAL_PAGE, RC38112_XTAL_LOS_EVT_REG}, + {XTAL_LOS_CNT, RC38112_XTAL_PAGE, RC38112_XTAL_LOS_CNT_REG}, + {XTAL_LOS_STS, RC38112_XTAL_PAGE, RC38112_XTAL_LOS_STS_REG}, +}; + +enum chips { + rc32312, + rc21012, + rc38112, +}; + +struct rc32312_data { + struct i2c_client *client; + struct mutex update_lock; + struct attribute_group *sysfs_group; + int page_reg; + int chip; + int vendor_id; +}; + +struct rc32312_clear_op { + int page; + u8 reg; + u8 val; + u8 mask; +}; + +static const struct rc32312_clear_op rc32312_clear_ops[] = { + { RC32312_APLL_PAGE, RC32312_APLL_EVENT_REG, RC32312_APLL_EVENT_CLEAR_VAL, RC32312_APLL_EVENT_CLEAR_MASK }, + { RC32312_APLL_PAGE, RC32312_APLL_LOL_EVENT_REG, RC32312_APLL_LOL_EVENT_CLEAR_VAL, RC32312_APLL_LOL_EVENT_CLEAR_MASK }, + { RC32312_APLL_PAGE, RC32312_APLL_EXT_EVENT_REG, RC32312_APLL_CLEAR_VAL, RC32312_APLL_LOL_EVENT_CLEAR_MASK }, + { RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_EVT_REG, RC32312_APLL_CLEAR_VAL, RC32312_APLL_LOL_EVENT_CLEAR_MASK }, + { RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_CNT_REG, RC32312_APLL_LOL_EVENT_CLEAR_VAL, RC32312_APLL_LOL_EVENT_CLEAR_MASK }, +}; + +static const struct rc32312_clear_op rc38112_clear_ops[] = { + { RC38112_XTAL_PAGE, RC38112_XTAL_LOS_EVT_REG, RC38112_XTAL_LOS_EVT_CLEAR_VAL, RC38112_XTAL_LOS_EVT_CLEAR_MASK }, + { RC38112_XTAL_PAGE, RC38112_XTAL_LOS_CNT_REG, RC38112_XTAL_LOS_CNT_CLEAR_VAL, RC38112_XTAL_LOS_CNT_CLEAR_MASK }, + { RC38112_APLL_PAGE, RC38112_APLL_EVENT_REG, RC38112_APLL_EVENT_CLEAR_VAL, RC38112_APLL_EVENT_CLEAR_MASK }, + { RC38112_APLL_PAGE, RC38112_APLL_LOL_EVENT_REG, RC38112_APLL_LOL_EVENT_CLEAR_VAL, RC38112_APLL_LOL_EVENT_CLEAR_MASK }, + { RC38112_APLL_PAGE, RC38112_APLL_LOL_CLEAR_REG, RC38112_APLL_LOL_CLEAR_CLEAR_VAL, RC38112_APLL_LOL_CLEAR_CLEAR_MASK }, +}; + + +int rc32312_set_page(struct i2c_client *client, int page) +{ + struct rc32312_data *data = i2c_get_clientdata(client); + int rv; + + rv = i2c_smbus_write_byte_data(client, data->page_reg, page); + if (rv < 0) { + DEBUG_ERROR("rc32312 wirte page failed page_reg 0x%x target page %d, errno: %d\n", data->page_reg, page, rv); + return rv; + } + + rv = i2c_smbus_read_byte_data(client, data->page_reg); + if (rv < 0) { + DEBUG_ERROR("rc32312 read page failed page_reg 0x%x target page %d, errno: %d\n", data->page_reg, page, rv); + return rv; + } + + if (rv != page) { + DEBUG_ERROR("rc32312 current page %d != target page %d \n", rv, page); + return -EIO; + } + DEBUG_VERBOSE("rc32312 set to page: %d success \n", page); + return 0; +} + +static s32 rc32312_read_byte_data(struct i2c_client *client, int page, u8 reg) +{ + int rv; + + rv = rc32312_set_page(client, page); + if (rv < 0) { + DEBUG_ERROR("rc32312 read byte setting page failed errno: %d\n", rv); + return rv; + } + + return i2c_smbus_read_byte_data(client, reg); +} + +static s32 rc32312_read_word_data(struct i2c_client *client, int page, u8 reg) +{ + int rv; + + rv = rc32312_set_page(client, page); + if (rv < 0) { + DEBUG_ERROR("rc32312 read word setting page failed errno: %d\n", rv); + return rv; + } + + return i2c_smbus_read_word_data(client, reg); +} + +static int rc32312_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) +{ + int rv; + + rv = rc32312_set_page(client, page); + if (rv < 0) { + DEBUG_ERROR("rc32312 write byte setting page failed errno: %d\n", rv); + return rv; + } + + return i2c_smbus_write_byte_data(client, reg, value); +} + +static int rc32312_write_word_data(struct i2c_client *client, int page, u8 reg, u16 value) +{ + int rv; + + rv = rc32312_set_page(client, page); + if (rv < 0) { + DEBUG_ERROR("rc32312 write byte setting page failed errno: %d\n", rv); + return rv; + } + + return i2c_smbus_write_word_data(client, reg, value); +} + +static ssize_t show_rc32312_value_word(struct device *dev, struct device_attribute *da, char *buf) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int reg = to_sensor_dev_attr_2(da)->index; + int page = to_sensor_dev_attr_2(da)->nr; + s32 status; + + status = -1; + mutex_lock(&data->update_lock); + status = rc32312_read_word_data(client, page, reg); + if (status < 0) { + DEBUG_ERROR("rc32312 show value failed page [%d] reg [0x%x], errno: %d\n", page, reg, status); + mutex_unlock(&data->update_lock); + return status; + } + DEBUG_VERBOSE("rc32312 show value success page [%d] reg[0x%x] read value[0x%x]\n", page, reg, status); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "0x%x\n", status & 0xffff); +} + +int rc32312_get_page_reg_from_attr(struct rc32312_data *data, int attr, int *page, int *reg) +{ + int i; + rc32312_attr_match_t *tmp_attr_infos; + int attr_infos_len; + + switch (data->chip) { + case rc32312: + tmp_attr_infos = rc32312_attr_infos; + attr_infos_len = ARRAY_SIZE(rc32312_attr_infos); + break; + case rc21012: + tmp_attr_infos = rc21012_attr_infos; + attr_infos_len = ARRAY_SIZE(rc21012_attr_infos); + break; + case rc38112: + tmp_attr_infos = rc38112_attr_infos; + attr_infos_len = ARRAY_SIZE(rc38112_attr_infos); + break; + default: + DEBUG_ERROR("Unknown chip %d\n", data->chip); + return -ENODEV; + } + for (i = 0; i < attr_infos_len; i++) { + if (tmp_attr_infos[i].attr == attr) { + *reg = tmp_attr_infos[i].reg; + *page = tmp_attr_infos[i].page; + DEBUG_VERBOSE("get_page_reg_from_attr success, chip[%d], attr[%d], page[%d], reg[%d]\n", + data->chip, attr, *page, *reg); + return 0; + } + } + + DEBUG_ERROR("get_page_reg_from_attr fail, chip[%d], attr[%d]\n", data->chip, attr); + return -ENODEV; +} + +static ssize_t show_common_value(struct device *dev, struct device_attribute *da, char *buf) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int attr = to_sensor_dev_attr_2(da)->nr; + int reg, page; + int ret; + s32 status; + + ret = rc32312_get_page_reg_from_attr(data, attr, &page, ®); + if (ret < 0) { + return ret; + } + + status = -1; + mutex_lock(&data->update_lock); + status = rc32312_read_byte_data(client, page, reg); + if (status < 0) { + DEBUG_ERROR("rc32312 show value failed page [%d] reg [0x%x], errno: %d\n", page, reg, status); + mutex_unlock(&data->update_lock); + return status; + } + DEBUG_VERBOSE("rc32312 show value success page [%d] reg[0x%x] read value[0x%x]\n", page, reg, status); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "0x%x\n", status & 0xff); +} + +static ssize_t set_common_value(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int attr = to_sensor_dev_attr_2(da)->nr; + int reg, page; + u8 val; + int ret; + + val = 0; + ret = kstrtou8(buf, 0, &val); + if (ret) { + DEBUG_ERROR("Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + + ret = rc32312_get_page_reg_from_attr(data, attr, &page, ®); + if (ret < 0) { + return ret; + } + + mutex_lock(&data->update_lock); + ret = rc32312_write_byte_data(client, page, reg, val); + if (ret < 0) { + DEBUG_ERROR("rc32312 set value failed page [%d] reg [0x%x] val [0x%x], errno: %d\n", page, reg, val, ret); + mutex_unlock(&data->update_lock); + return ret; + } + DEBUG_VERBOSE("rc32312 set value success page [%d] reg[0x%x] value[0x%x]\n", page, reg, val); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_rc32312_out_ctrl_value(struct device *dev, struct device_attribute *da, char *buf) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int reg = to_sensor_dev_attr_2(da)->index; + int page = to_sensor_dev_attr_2(da)->nr; + s32 status; + + status = -1; + mutex_lock(&data->update_lock); + status = rc32312_read_word_data(client, page, reg); + if (status < 0) { + DEBUG_ERROR("rc32312 read word data failed page [%d] reg [0x%x], errno: %d\n", page, reg, status); + mutex_unlock(&data->update_lock); + return status; + } + DEBUG_VERBOSE("rc32312 read word data success page [%d] reg[0x%x] read value[0x%x]\n", page, reg, status); + + mutex_unlock(&data->update_lock); + if (status == RC32312_OUT_CTRL_EN) { + return snprintf(buf, PAGE_SIZE, "1\n"); + } + + if (status == RC32312_OUT_CTRL_DIS) { + return snprintf(buf, PAGE_SIZE, "0\n"); + } + + return snprintf(buf, PAGE_SIZE, "0x%04x\n", status & 0xffff); +} + +static ssize_t show_rc32312_bus_status(struct device *dev, struct device_attribute *da, char *buf) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + struct i2c_client *client; + s32 read_vendor_id; + int bus_status; + + if (!data || !data->client) { + DEBUG_ERROR("rc32312 invalid data or client pointer\n"); + return -EINVAL; + } + + if (data->vendor_id == 0) { + DEBUG_ERROR("rc32312 vendor_id is 0\n"); + return -EINVAL; + } + + client = data->client; + mutex_lock(&data->update_lock); + read_vendor_id = rc32312_read_word_data(client, RC32312_VENDOR_ID_PAGE, RC32312_VENDOR_ID_REG); + mutex_unlock(&data->update_lock); + if (read_vendor_id < 0) { + DEBUG_ERROR("rc32312 read vendor_id failed errno: %d\n", read_vendor_id); + return read_vendor_id; + } + + bus_status = ((read_vendor_id & 0xffff) == data->vendor_id) ? + RC32312_CLOCK_STATUS_NORMAL : RC32312_CLOCK_STATUS_ABNORMAL; + + return snprintf(buf, PAGE_SIZE, "%d\n", bus_status); +} + +static ssize_t set_rc32312_out_ctrl_value(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int reg = to_sensor_dev_attr_2(da)->index; + int page = to_sensor_dev_attr_2(da)->nr; + u16 val; + int ret; + + val = 0; + ret = kstrtou16(buf, 0, &val); + if (ret) { + dev_err(&client->dev, "Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + + if ((val != 0) && (val != 1)) { + dev_err(&client->dev, "Unsupport value: %d, please enter 0 or 1\n", val); + return -EINVAL; + } + + if (val == 0) { + val = RC32312_OUT_CTRL_DIS; + } else { + val = RC32312_OUT_CTRL_EN; + } + + mutex_lock(&data->update_lock); + ret = rc32312_write_word_data(client, page, reg, val); + if (ret < 0) { + DEBUG_ERROR("rc32312 write word data failed page [%d] reg [0x%x] val [0x%x], errno: %d\n", page, reg, val, ret); + mutex_unlock(&data->update_lock); + return ret; + } + DEBUG_VERBOSE("rc32312 write word data success page [%d] reg[0x%x] value[0x%x]\n", page, reg, val); + mutex_unlock(&data->update_lock); + return count; +} + +static int clear_rc32312_value(struct rc32312_data *data, int page, u8 reg, u8 val, u8 mask) +{ + struct i2c_client *client; + s32 ori_status; + u8 clear_value; + int ret; + + if (!data || !data->client) { + DEBUG_ERROR("Invalid data or client pointer\n"); + return -EINVAL; + } + client = data->client; + + mutex_lock(&data->update_lock); + ori_status = rc32312_read_byte_data(client, page, reg); + if (ori_status < 0) { + DEBUG_ERROR("rc32312 read value failed page [%d] reg [0x%x], errno: %d\n", page, reg, ori_status); + mutex_unlock(&data->update_lock); + return ori_status; + } + clear_value = (((u8)ori_status & ~(mask)) | (val & (mask))); + + ret = rc32312_write_byte_data(client, page, reg, clear_value); + if (ret < 0) { + DEBUG_ERROR("rc32312 write value failed page [%d] reg [0x%x] val [0x%x], errno: %d\n", page, reg, clear_value, ret); + mutex_unlock(&data->update_lock); + return ret; + } + + DEBUG_VERBOSE("rc32312 clear value success page [%d] reg [0x%x] value [0x%x]\n", page, reg, clear_value); + mutex_unlock(&data->update_lock); + + return 0; +} + +static int clear_common_values(struct rc32312_data *data) +{ + const struct rc32312_clear_op *clear_ops = NULL; + size_t clear_ops_size; + const struct rc32312_clear_op *op; + int ret; + int i; + + /* Select the appropriate clear operations based on chip type */ + switch (data->chip) { + case rc32312: + clear_ops = rc32312_clear_ops; + clear_ops_size = ARRAY_SIZE(rc32312_clear_ops); + break; + case rc38112: + clear_ops = rc38112_clear_ops; + clear_ops_size = ARRAY_SIZE(rc38112_clear_ops); + break; + case rc21012: + default: + DEBUG_ERROR("not support chip type %d\n", data->chip); + return -ENODEV; + } + + for (i = 0; i < clear_ops_size; i++) { + op = &clear_ops[i]; + ret = clear_rc32312_value(data, op->page, op->reg, op->val, op->mask); + if (ret < 0) { + DEBUG_ERROR("rc32312 clear reg[%d] failed, errno: %d\n", i, ret); + return ret; + } + } + + return 0; +} + +static int rc32312_get_status(struct rc32312_data *data, int *status) +{ + struct i2c_client *client; + s32 read_vendor_id; + s32 xtal_los_evt; + s32 xtal_los_sts; + s32 apll_los_evt; + s32 apll_los_sts; + int bus_status; + int xtal_status; + int apll_status; + + if (!data || !data->client || !status) { + DEBUG_ERROR("rc32312 invalid data, client or status pointer\n"); + return -EINVAL; + } + + if (data->vendor_id == 0) { + DEBUG_ERROR("rc32312 vendor_id is 0\n"); + return -EINVAL; + } + + client = data->client; + read_vendor_id = rc32312_read_word_data(client, RC32312_VENDOR_ID_PAGE, RC32312_VENDOR_ID_REG); + if (read_vendor_id < 0) { + DEBUG_ERROR("rc32312 read vendor_id failed errno: %d\n", read_vendor_id); + return read_vendor_id; + } + + xtal_los_evt = rc32312_read_byte_data(client, RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_EVT_REG); + if (xtal_los_evt < 0) { + DEBUG_ERROR("rc32312 read xtal_los_evt failed errno: %d\n", xtal_los_evt); + return xtal_los_evt; + } + + xtal_los_sts = rc32312_read_byte_data(client, RC32312_XTAL_LOS_PAGE, RC32312_XTAL_LOS_STS_REG); + if (xtal_los_sts < 0) { + DEBUG_ERROR("rc32312 read xtal_los_sts failed errno: %d\n", xtal_los_sts); + return xtal_los_sts; + } + + apll_los_evt = rc32312_read_byte_data(client, RC32312_APLL_PAGE, RC32312_APLL_EVENT_REG); + if (apll_los_evt < 0) { + DEBUG_ERROR("rc32312 read apll_event failed errno: %d\n", apll_los_evt); + return apll_los_evt; + } + + apll_los_sts = rc32312_read_byte_data(client, RC32312_APLL_PAGE, RC32312_APLL_STS_REG); + if (apll_los_sts < 0) { + DEBUG_ERROR("rc32312 read apll_los_sts failed errno: %d\n", apll_los_sts); + return apll_los_sts; + } + + bus_status = ((read_vendor_id & 0xffff) == data->vendor_id) ? + RC32312_CLOCK_STATUS_NORMAL : RC32312_CLOCK_STATUS_ABNORMAL; + + xtal_status = ((xtal_los_evt & RC32312_CLOCK_REG_INFO_MASK) | + (xtal_los_sts & RC32312_CLOCK_REG_INFO_MASK)) ? + RC32312_CLOCK_STATUS_ABNORMAL : RC32312_CLOCK_STATUS_NORMAL; + + apll_status = ((apll_los_evt & RC32312_CLOCK_REG_INFO_MASK) | + !(apll_los_sts & RC32312_CLOCK_REG_INFO_MASK)) ? + RC32312_CLOCK_STATUS_ABNORMAL : RC32312_CLOCK_STATUS_NORMAL; + + *status = (bus_status << RC32312_CLOCK_FAULT_BUS) | + (xtal_status << RC32312_CLOCK_FAULT_XTAL) | + (apll_status << RC32312_CLOCK_FAULT_APLL); + + return 0; +} + +static ssize_t show_rc32312_status(struct device *dev, struct device_attribute *da, char *buf) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + int status; + int ret; + + if (!data || !data->client) { + DEBUG_ERROR("rc32312 invalid data or client pointer\n"); + return -EINVAL; + } + + mutex_lock(&data->update_lock); + ret = rc32312_get_status(data, &status); + mutex_unlock(&data->update_lock); + if (ret < 0) { + DEBUG_ERROR("rc32312 get status failed, errno: %d\n", ret); + return ret; + } + + ret = clear_common_values(data); + if (ret < 0) { + DEBUG_ERROR("rc32312 clear values failed, errno: %d\n", ret); + return ret; + } + + return snprintf(buf, PAGE_SIZE, "0x%x\n", status); +} + +static ssize_t clear_rc32312_reg_value(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct rc32312_data *data = dev_get_drvdata(dev); + u16 val; + int ret; + + if (!data || !data->client) { + return -EINVAL; + } + + val = 0; + ret = kstrtou16(buf, 0, &val); + if (ret) { + DEBUG_ERROR("Invaild input value [%s], errno: %d\n", buf, ret); + return -EINVAL; + } + + if (val != 1) { + DEBUG_ERROR("Unsupport value: %d, please enter 1\n", val); + return -EINVAL; + } + + ret = clear_common_values(data); + if (ret < 0) { + DEBUG_ERROR("rc32312 clear values failed, errno: %d\n", ret); + return ret; + } + + return count; +} + +static int rc32312_init(struct rc32312_data *data) +{ + int ret = 0; + + if (!data) { + DEBUG_ERROR("Invalid data pointer\n"); + return -EINVAL; + } + + switch (data->chip) { + case rc32312: + ret = clear_rc32312_value(data, RC32312_APLL_PAGE, RC32312_APLL_EVENT_REG, RC32312_APLL_CLEAR_VAL, RC32312_APLL_CLEAR_MASK); + ret += clear_rc32312_value(data, RC32312_APLL_PAGE, RC32312_APLL_LOL_EVENT_REG, RC32312_APLL_LOL_EVENT_CLEAR_VAL, RC32312_APLL_LOL_EVENT_CLEAR_MASK); + break; + case rc21012: + ret = clear_rc32312_value(data, RC21012_LOSMON_PAGE, RC21012_LOSMON4_CNT_REG, RC21012_LOSMON4_CNT_CLEAR_VAL, RC21012_LOSMON4_CNT_CLEAR_MASK); + ret += clear_rc32312_value(data, RC21012_APLL_PAGE, RC21012_APLL_LOL_CNT_REG, RC21012_APLL_LOL_CNT_CLEAR_VAL, RC21012_APLL_LOL_CNT_CLEAR_MASK); + break; + case rc38112: + ret += clear_rc32312_value(data, RC38112_APLL_PAGE, RC38112_APLL_EVENT_REG, RC38112_APLL_EVENT_CLEAR_VAL, RC38112_APLL_EVENT_CLEAR_MASK); + ret += clear_rc32312_value(data, RC38112_APLL_PAGE, RC38112_APLL_LOL_EVENT_REG, RC38112_APLL_LOL_EVENT_CLEAR_VAL, RC38112_APLL_LOL_EVENT_CLEAR_MASK); + break; + default: + dev_dbg(&data->client->dev, "Unknown chip id %d, skip\n", data->chip); + return -ENODEV; + } + + if (ret < 0) { + dev_warn(&data->client->dev, "RC32312 init fail\n"); + return ret; + } + dev_dbg(&data->client->dev, "RC32312 init success.\n"); + return ret; +} + +static SENSOR_DEVICE_ATTR_2(apll_event, S_IRUGO | S_IWUSR, show_common_value, set_common_value, APLL_EVENT, 0); +static SENSOR_DEVICE_ATTR_2(apll_lol_event, S_IRUGO | S_IWUSR, show_common_value, set_common_value, APLL_COUNT, 0); +static SENSOR_DEVICE_ATTR_2(apll_sts, S_IRUGO, show_common_value, NULL, APLL_STATUS, 0); +static SENSOR_DEVICE_ATTR_2(xtal_los_evt, S_IRUGO | S_IWUSR, show_common_value, set_common_value, XTAL_LOS_EVT, 0); +static SENSOR_DEVICE_ATTR_2(xtal_los_cnt, S_IRUGO | S_IWUSR, show_common_value, set_common_value, XTAL_LOS_CNT, 0); +static SENSOR_DEVICE_ATTR_2(xtal_los_sts, S_IRUGO, show_common_value, NULL, XTAL_LOS_STS, 0); +static SENSOR_DEVICE_ATTR_2(clear_reg, S_IWUSR, NULL, clear_rc32312_reg_value, 0, 0); +static SENSOR_DEVICE_ATTR_2(vendor_id, S_IRUGO, show_rc32312_value_word, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(device_id, S_IRUGO, show_rc32312_value_word, NULL, 0, 0x2); +static SENSOR_DEVICE_ATTR_2(device_pgm, S_IRUGO, show_rc32312_value_word, NULL, 0, 0x6); +static SENSOR_DEVICE_ATTR_2(bus_status, S_IRUGO, show_rc32312_bus_status, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(status, S_IRUGO, show_rc32312_status, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_0, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x04); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_1, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x0c); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_2, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x14); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_3, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x1c); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_4, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x24); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_5, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x2c); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_6, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x34); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_7, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x3c); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_8, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x44); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_9, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x4c); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_10, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x54); +static SENSOR_DEVICE_ATTR_2(out_en_ctrl_11, S_IRUGO | S_IWUSR, show_rc32312_out_ctrl_value, set_rc32312_out_ctrl_value, 1, 0x5c); + +static struct attribute *rc32312_sysfs_attrs[] = { + &sensor_dev_attr_apll_event.dev_attr.attr, + &sensor_dev_attr_apll_lol_event.dev_attr.attr, + &sensor_dev_attr_apll_sts.dev_attr.attr, + &sensor_dev_attr_xtal_los_evt.dev_attr.attr, + &sensor_dev_attr_xtal_los_cnt.dev_attr.attr, + &sensor_dev_attr_xtal_los_sts.dev_attr.attr, + &sensor_dev_attr_clear_reg.dev_attr.attr, + &sensor_dev_attr_vendor_id.dev_attr.attr, + &sensor_dev_attr_device_id.dev_attr.attr, + &sensor_dev_attr_device_pgm.dev_attr.attr, + &sensor_dev_attr_bus_status.dev_attr.attr, + &sensor_dev_attr_status.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_0.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_1.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_2.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_3.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_4.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_5.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_6.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_7.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_8.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_9.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_10.dev_attr.attr, + &sensor_dev_attr_out_en_ctrl_11.dev_attr.attr, + NULL +}; + +static struct attribute_group rc32312_sysfs_group = { + .attrs = rc32312_sysfs_attrs, +}; + +static SENSOR_DEVICE_ATTR_2(losmon4_sts, S_IRUGO, show_common_value, NULL, LOSMON4_STS, 0); +static SENSOR_DEVICE_ATTR_2(losmon4_cnt, S_IRUGO | S_IWUSR, show_common_value, set_common_value, LOSMON4_CNT, 0); + +static struct attribute *rc21012_sysfs_attrs[] = { + &sensor_dev_attr_vendor_id.dev_attr.attr, + &sensor_dev_attr_device_pgm.dev_attr.attr, + &sensor_dev_attr_apll_sts.dev_attr.attr, + &sensor_dev_attr_apll_lol_event.dev_attr.attr, + &sensor_dev_attr_losmon4_sts.dev_attr.attr, + &sensor_dev_attr_losmon4_cnt.dev_attr.attr, + NULL +}; + +static struct attribute_group rc21012_sysfs_group = { + .attrs = rc21012_sysfs_attrs, +}; + +static struct attribute *rc38112_sysfs_attrs[] = { + &sensor_dev_attr_apll_event.dev_attr.attr, + &sensor_dev_attr_apll_lol_event.dev_attr.attr, + &sensor_dev_attr_apll_sts.dev_attr.attr, + &sensor_dev_attr_xtal_los_evt.dev_attr.attr, + &sensor_dev_attr_xtal_los_cnt.dev_attr.attr, + &sensor_dev_attr_xtal_los_sts.dev_attr.attr, + &sensor_dev_attr_clear_reg.dev_attr.attr, + &sensor_dev_attr_vendor_id.dev_attr.attr, + &sensor_dev_attr_device_id.dev_attr.attr, + &sensor_dev_attr_device_pgm.dev_attr.attr, + &sensor_dev_attr_bus_status.dev_attr.attr, + &sensor_dev_attr_status.dev_attr.attr, + NULL +}; + +static struct attribute_group rc38112_sysfs_group = { + .attrs = rc38112_sysfs_attrs, +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0) +static int rc32312_probe(struct i2c_client *client) +#else +static int rc32312_probe(struct i2c_client *client, const struct i2c_device_id *id) +#endif +{ + struct rc32312_data *data; + int ret; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0) + const struct i2c_device_id *id = i2c_client_get_device_id(client); +#endif + + dev_dbg(&client->dev, "RC32312 enter probe\n"); + data = devm_kzalloc(&client->dev, sizeof(struct rc32312_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "RC32312 alloc memory failed\n"); + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->chip = id->driver_data; + + switch (id->driver_data) { + case rc32312: + data->sysfs_group = &rc32312_sysfs_group; + data->page_reg = RC32312_PAGE_REG; + data->vendor_id = RC32312_VENDOR_ID; + break; + case rc21012: + data->sysfs_group = &rc21012_sysfs_group; + data->page_reg = RC32312_PAGE_REG; + data->vendor_id = RC32312_VENDOR_ID; + break; + case rc38112: + data->sysfs_group = &rc38112_sysfs_group; + data->page_reg = RC32312_PAGE_REG; + data->vendor_id = RC32312_VENDOR_ID; + break; + default: + dev_err(&client->dev, "Unknown chip id %ld\n", id->driver_data); + return -ENODEV; + } + + (void)rc32312_init(data); + ret = sysfs_create_group(&client->dev.kobj, data->sysfs_group); + if (ret < 0) { + dev_err(&client->dev, "RC32312 sysfs_create_group failed %d\n", ret); + } + + dev_info(&client->dev, "init %s success\n", client->name); + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0) +static void rc32312_remove(struct i2c_client *client) +#else +static int rc32312_remove(struct i2c_client *client) +#endif +{ + struct rc32312_data *data = i2c_get_clientdata(client); + + if (data->sysfs_group) { + dev_info(&client->dev, "RC32312 unregister sysfs group\n"); + sysfs_remove_group(&client->dev.kobj, (const struct attribute_group *)data->sysfs_group); + } + dev_info(&client->dev, "RC32312 removed\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0) + return 0; +#endif +} + +static const struct i2c_device_id rc32312_id[] = { + { "wb_rc32312", rc32312 }, + { "wb_rc21012", rc21012 }, + { "wb_rc38112", rc38112 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, rc32312_id); + +static struct i2c_driver wb_rc32312_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_rc32312", + }, + .probe = rc32312_probe, + .remove = rc32312_remove, + .id_table = rc32312_id, +}; + +module_i2c_driver(wb_rc32312_driver); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("RC32312 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_master.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_master.c new file mode 100644 index 0000000000..9f7ce7de56 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_master.c @@ -0,0 +1,111 @@ +/* Provides functionality spi_busnum_to_master() in earlier versions of the kernel */ + +#include +#include +#include + +#include "wb_spi_master.h" + +static int g_wb_spi_master_debug = 0; +static int g_wb_spi_master_error = 0; + +module_param(g_wb_spi_master_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_master_error, int, S_IRUGO | S_IWUSR); + +#define WB_SPI_MASTER_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_master_debug) { \ + printk(KERN_INFO "[WB_SPI_MASTER][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_SPI_MASTER_ERROR(fmt, args...) do { \ + if (g_wb_spi_master_error) { \ + printk(KERN_ERR "[WB_SPI_MASTER][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct device g_wb_spi_device; +/* point to spi_master_class in drivers/spi/spi.c */ +static struct class *g_wb_spi_master_class = NULL; +static struct spi_controller *g_wb_spi_controller = NULL; + +static int __spi_controller_match(struct device *dev, const void *data) +{ + struct spi_controller *ctlr; + const u16 *bus_num = data; + + ctlr = container_of(dev, struct spi_controller, dev); + return ctlr->bus_num == *bus_num; +} + +/** + * wb_spi_master_busnum_to_master - look up master associated with bus_num + * @bus_num: the master's bus number + * Context: can sleep + * + * Return: the SPI master structure on success, else NULL. + */ +struct spi_controller *wb_spi_master_busnum_to_master(u16 bus_num) +{ + struct device *dev; + struct spi_controller *ctlr = NULL; + + WB_SPI_MASTER_VERBOSE("Enter.\n"); + + if (g_wb_spi_master_class == NULL) { + WB_SPI_MASTER_ERROR("get g_wb_spi_master_class fail.\n"); + return NULL; + } + + dev = class_find_device(g_wb_spi_master_class, NULL, &bus_num, __spi_controller_match); + if (dev) { + ctlr = container_of(dev, struct spi_controller, dev); + } + /* reference got in class_find_device */ + return ctlr; +} +EXPORT_SYMBOL_GPL(wb_spi_master_busnum_to_master); + +static int __init wb_spi_master_init(void) +{ + struct device *dev; + struct spi_board_info chip; + + WB_SPI_MASTER_VERBOSE("Enter!\n"); + + device_initialize(&g_wb_spi_device); + + g_wb_spi_controller = spi_alloc_master(&g_wb_spi_device, sizeof(struct spi_board_info)); + if (g_wb_spi_controller == NULL) { + WB_SPI_MASTER_ERROR("spi_alloc_master failed.\n"); + return -ENOMEM; + } + + g_wb_spi_master_class = g_wb_spi_controller->dev.class; + if (g_wb_spi_master_class == NULL) { + WB_SPI_MASTER_ERROR("get class_spi_master failed.\n"); + kfree(g_wb_spi_controller); + g_wb_spi_controller = NULL; + return -EINVAL; + } + printk(KERN_INFO "WB spi master init success."); + + return 0; +} + +static void __exit wb_spi_master_exit(void) +{ + WB_SPI_MASTER_VERBOSE("Enter!\n"); + if (g_wb_spi_controller != NULL) { + kfree(g_wb_spi_controller); + } + + return; +} + +module_init(wb_spi_master_init); +module_exit(wb_spi_master_exit); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("create spi device"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c index 4664916314..2046b59290 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c @@ -47,6 +47,14 @@ #define SPIOC_MAX_DIV (0x0E) #define SPIOC_DIV(div) (((div) & 0x0f) << 4) +/* spioc_mode = 1: divider occupies bit3~bit7 (5 bits), valid range 0~0x1E */ +#define SPIOC_DIV_5BIT_MASK (0xf8) +#define SPIOC_DIV_5BIT_MAX (0x1E) +#define SPIOC_DIV_5BIT(div) (((div) & 0x1f) << 3) + +#define SPIOC_MODE_DEFAULT (0) +#define SPIOC_MODE_DIV_5BIT (1) + #define SPIOC_STS (0x01) #define SPIOC_INTR_STS BIT(0) #define SPIOC_BUSY_STS BIT(1) @@ -126,6 +134,7 @@ struct spioc { uint32_t freq; uint32_t big_endian; uint32_t irq_flag; + uint32_t spioc_mode; struct device *dev; int transfer_busy_flag; }; @@ -455,10 +464,10 @@ static inline u32 oc_spi_getreg(struct spioc *spioc, int reg) static int spioc_get_clkdiv(struct spioc *spioc, u32 speed) { - u32 rate, div; + u32 rate, div, max_div; rate = spioc->freq; - SPI_OC_VERBOSE("clk get rate:%u, speed:%u\n", rate, speed); + SPI_OC_VERBOSE("clk get rate:%u, speed:%u, spioc_mode:%u\n", rate, speed, spioc->spioc_mode); /* fs = fw/((DIV+2)*2) */ if (speed > (rate / 4)) { @@ -468,8 +477,9 @@ static int spioc_get_clkdiv(struct spioc *spioc, u32 speed) return div; } div = (rate/(2 * speed)) - 2; - if (div > SPIOC_MAX_DIV) { - SPI_OC_ERROR("Unsupport spi device speed, div:%u.\n", div); + max_div = (spioc->spioc_mode == SPIOC_MODE_DIV_5BIT) ? SPIOC_DIV_5BIT_MAX : SPIOC_MAX_DIV; + if (div > max_div) { + SPI_OC_ERROR("Unsupport spi device speed, div:%u, max_div:%u.\n", div, max_div); return -1; } SPI_OC_VERBOSE("DIV is:0x%x\n", div); @@ -609,7 +619,11 @@ static int spioc_setup_transfer(struct spi_device *spi, struct spi_transfer *tra SPI_OC_ERROR("get div error, div:%d.\n", div); return -EINVAL; } - ctrl |= SPIOC_DIV(div); + if (spioc->spioc_mode == SPIOC_MODE_DIV_5BIT) { + ctrl |= SPIOC_DIV_5BIT(div); + } else { + ctrl |= SPIOC_DIV(div); + } SPI_OC_VERBOSE("ctrl:[0x%x].\n", ctrl); @@ -892,6 +906,10 @@ static int ocores_spi_config_init(struct spioc *spioc) spioc->irq_flag = 0; ret = 0; } + ret = of_property_read_u32(dev->of_node, "spioc_mode", &spioc->spioc_mode); + if (ret != 0) { + spioc->spioc_mode = SPIOC_MODE_DEFAULT; + } } else { if (spioc->dev->platform_data == NULL) { SPI_OC_ERROR("platform data config error.\n"); @@ -909,12 +927,13 @@ static int ocores_spi_config_init(struct spioc *spioc) spioc->reg_access_mode = spi_ocores_device->reg_access_mode; spioc->num_chipselect = spi_ocores_device->num_chipselect; spioc->irq_flag = spi_ocores_device->irq_flag; + spioc->spioc_mode = spi_ocores_device->spioc_mode; } SPI_OC_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, clock-frequency:0x%x.\n", spioc->dev_name, spioc->base_addr, spioc->reg_shift, spioc->reg_io_width, spioc->freq); - SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u, irq_flag: %u\n", - spioc->reg_access_mode, spioc->num_chipselect, spioc->irq_flag); + SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u, irq_flag: %u, spioc_mode: %u\n", + spioc->reg_access_mode, spioc->num_chipselect, spioc->irq_flag, spioc->spioc_mode); return ret; } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h index e94a770552..38f52d707f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h @@ -36,6 +36,7 @@ typedef struct spi_ocores_device_s { uint32_t clock_frequency; uint32_t num_chipselect; uint32_t irq_flag; + uint32_t spioc_mode; int device_flag; } spi_ocores_device_t; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.c new file mode 100644 index 0000000000..18076cd4e7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.c @@ -0,0 +1,269 @@ +#include +#include +#include +#include +#include +#include +#include +#include "wb_mdio_dev.h" +#include "wb_switch_dev.h" + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +uint32_t bcm53134_phy_addr[BCM53134_MAX_DEV_NUMBER] = {0x0, 0x1, 0x2, 0x3, 0x04}; + +static const struct of_device_id wb_switch_match[] = { + { .compatible = "bcm53134", .data = (void *)BCM53134}, + {}, +}; +MODULE_DEVICE_TABLE(of, wb_switch_match); + +static const struct platform_device_id wb_switch_id_table[] = { + { "bcm53134", BCM53134 }, + { } +}; +MODULE_DEVICE_TABLE(platform, wb_switch_id_table); + + +static void switch_dev_device_release(struct device *dev) +{ + return; +} + +static int get_dev_reg_info(int dev_type, uint32_t **phy_addr, int *num) +{ + switch(dev_type) + { + case BCM53134: + *phy_addr = bcm53134_phy_addr; + *num = BCM53134_MAX_DEV_NUMBER; + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +static int of_switch_dev_config_init(switch_dev_info_t *switch_dev) +{ + struct device *dev; + int num_phys, i, ret = 0; + uint32_t *phy_addr; + int max_num_phy; + const struct of_device_id *match; + + dev = switch_dev->dev; + + /* Match device type from device tree */ + match = of_match_node(wb_switch_match, dev->of_node); + if (!match) { + dev_err(dev, "dev type match fail.\n"); + return -EINVAL; + } + switch_dev->dev_type = (enum chips)(unsigned long)of_device_get_match_data(dev); + + ret = get_dev_reg_info(switch_dev->dev_type, &phy_addr, &max_num_phy); + if (ret != 0) { + DEBUG_ERROR("get_dev_reg_info fail, ret:%d\n", ret); + return ret; + } + + ret = of_property_read_string(dev->of_node, "mdio_bus_name", &switch_dev->mdio_bus_name); + if (ret != 0) { + DEBUG_ERROR("Missing required properties\n"); + return -EINVAL; + } + + num_phys = of_property_count_strings(dev->of_node, "mdio_names"); + if (num_phys <= 0) { + dev_err(dev, "phy num[%d] err.\n", num_phys); + return -EINVAL; + } + + if ((num_phys != max_num_phy) || (num_phys > MAX_MDIO_DEVICES) ) { + dev_err(dev, "phy num[%d] config err, not equal dev_count:%d or exceed max:%d.\n", num_phys, max_num_phy, MAX_MDIO_DEVICES); + return -EINVAL; + } + + switch_dev->dev_num = 0; + for (i = 0; i < num_phys; i++) { + switch_dev->mdio_dev_device[i].mdio_bus_name = switch_dev->mdio_bus_name; + ret = of_property_read_string_index(dev->of_node, "mdio_names", i, + &switch_dev->mdio_dev_device[i].dev_name); + if (ret != 0) { + dev_err(dev, "mdio device[%d] config err.\n", i); + return -EINVAL; + } + + switch_dev->mdio_dev_device[i].addr = phy_addr[i]; + switch_dev->platform_device[i].name = MDIO_DEV_COMPATIBLE_NAME; + switch_dev->platform_device[i].id = i; + switch_dev->platform_device[i].dev.platform_data = &switch_dev->mdio_dev_device[i]; + switch_dev->platform_device[i].dev.release = switch_dev_device_release; + switch_dev->dev_num++; + } + + return 0; +} + +static void mdio_device_register(switch_dev_info_t *switch_dev) +{ + int i, ret = 0; + for (i = 0; i < switch_dev->dev_num; i++) { + ret = platform_device_register(&switch_dev->platform_device[i]); + if (ret < 0) { + switch_dev->mdio_dev_device[i].device_flag = -1; /* device register failed, set flag -1 */ + dev_info(switch_dev->dev, "wb-switch-dev.%d register failed!\n", i + 1); + } else { + switch_dev->mdio_dev_device[i].device_flag = 0; /* device register suucess, set flag 0 */ + } + } +} + +static void mdio_device_unregister(switch_dev_info_t *switch_dev) +{ + int i; + for (i = switch_dev->dev_num - 1; i >= 0; i--) { + if (switch_dev->mdio_dev_device[i].device_flag == 0) { + platform_device_unregister(&switch_dev->platform_device[i]); + } + } +} + + +static int switch_dev_config_init(switch_dev_info_t *switch_dev) +{ + switch_dev_info_t *platform_switch_info; + int i, ret; + uint32_t *phy_addr; + int max_num_phy, num_phys; + struct platform_device *pdev = to_platform_device(switch_dev->dev); + const struct platform_device_id *pid; + + num_phys = 0; + + platform_switch_info = switch_dev->dev->platform_data; + if (platform_switch_info == NULL) { + dev_err(switch_dev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + + /* Configure switch_dev based on platform_switch_info */ + switch_dev->mdio_bus_name = platform_switch_info->mdio_bus_name; + + /* Get device type from platform_device_id table */ + pid = platform_get_device_id(pdev); + if (!pid) { + dev_err(switch_dev->dev, "Failed to get platform device ID\n"); + return -ENODEV; + } + + /* Set device type based on platform_device_id */ + switch_dev->dev_type = pid->driver_data; + + /* Get device configuration based on device type */ + ret = get_dev_reg_info(switch_dev->dev_type, &phy_addr, &max_num_phy); + if (ret != 0) { + dev_err(switch_dev->dev, "get_dev_reg_info fail, ret:%d\n", ret); + return ret; + } + + /* Calculate number of devices by checking valid dev_name in platform_switch_info */ + num_phys = 0; + for (i = 0; i < MAX_MDIO_DEVICES; i++) { + if (platform_switch_info->mdio_dev_device[i].dev_name) { + num_phys++; + } else { + break; + } + } + + if (num_phys <= 0 || num_phys > MAX_MDIO_DEVICES) { + dev_err(switch_dev->dev, "phy num[%d] err.\n", num_phys); + return -EINVAL; + } + + if (num_phys != max_num_phy) { + dev_err(switch_dev->dev, "phy num[%d] config err, not equal dev_count:%d.\n", + num_phys, max_num_phy); + return -EINVAL; + } + + switch_dev->dev_num = num_phys; + for (i = 0; i < num_phys; i++) { + switch_dev->mdio_dev_device[i].dev_name = platform_switch_info->mdio_dev_device[i].dev_name; + switch_dev->mdio_dev_device[i].alias = platform_switch_info->mdio_dev_device[i].dev_name; + switch_dev->mdio_dev_device[i].mdio_bus_name = switch_dev->mdio_bus_name; /* Use the switch device's bus name */ + switch_dev->mdio_dev_device[i].addr = phy_addr[i]; + switch_dev->mdio_dev_device[i].device_flag = 0; + + /* Setup platform device */ + switch_dev->platform_device[i].name = MDIO_DEV_COMPATIBLE_NAME; + switch_dev->platform_device[i].id = i; + switch_dev->platform_device[i].dev.platform_data = &switch_dev->mdio_dev_device[i]; + switch_dev->platform_device[i].dev.release = switch_dev_device_release; + } + + return 0; +} + +static int wb_switch_dev_probe(struct platform_device *pdev) +{ + switch_dev_info_t *switch_dev; + int ret; + + switch_dev = devm_kzalloc(&pdev->dev, sizeof(switch_dev_info_t), GFP_KERNEL); + if (!switch_dev) { + dev_err(&pdev->dev, "switch_dev memory allocation failed\n"); + return -ENOMEM; + } + + switch_dev->dev = &pdev->dev; + + /* Try to get device type from device tree if available */ + if (pdev->dev.of_node) { + ret = of_switch_dev_config_init(switch_dev); + } else { + ret = switch_dev_config_init(switch_dev); + } + + if (ret) { + dev_err(&pdev->dev, "wb_switch_dev config_init fail, ret: %d\n", ret); + return -EINVAL; + } + + platform_set_drvdata(pdev, switch_dev); + mdio_device_register(switch_dev); + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,11,0) +static void wb_switch_dev_remove(struct platform_device *pdev) +#else +static int wb_switch_dev_remove(struct platform_device *pdev) +#endif +{ + switch_dev_info_t *switch_dev; + + switch_dev = platform_get_drvdata(pdev); + mdio_device_unregister(switch_dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0) + return 0; +#endif +} + +static struct platform_driver wb_switch_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = wb_switch_match, + }, + .probe = wb_switch_dev_probe, + .remove = wb_switch_dev_remove, + .id_table = wb_switch_id_table, +}; + +module_platform_driver(wb_switch_driver); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("Driver for WB Switch Device with Multiple MDIO Devices"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.h new file mode 100644 index 0000000000..c07f99e51f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_switch_dev.h @@ -0,0 +1,22 @@ +#ifndef __WB_SWITCH_DEV_H__ +#define __WB_SWITCH_DEV_H__ + +#define MAX_MDIO_DEVICES 5 + +enum chips { + BCM53134 +}; + +typedef struct switch_dev_info { + mdio_dev_device_t mdio_dev_device[MAX_MDIO_DEVICES]; + struct device *dev; + uint32_t dev_num; + struct platform_device platform_device[MAX_MDIO_DEVICES]; + const char *mdio_bus_name; + int dev_type; + int device_flag; +} switch_dev_info_t; + +#define BCM53134_MAX_DEV_NUMBER (5) + +#endif /* __WB_SWITCH_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.c new file mode 100644 index 0000000000..e08162abf2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.c @@ -0,0 +1,286 @@ +/* + * wb_vr_common.c + * ko to read the PMBUS_IC_DEVICE_ID to determine the VR device type and load the driver. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmbus.h" +#include "wb_vr_common.h" +#include + +#define PROXY_NAME "wb-vr-common" +#define PMBUS_RETRY_SLEEP_TIME (10000) /* 10ms */ +#define PMBUS_RETRY_TIME (3) + +static int g_wb_vr_common_debug = 0; +static int g_wb_vr_common_error = 0; + +module_param(g_wb_vr_common_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_vr_common_error, int, S_IRUGO | S_IWUSR); + +#define WB_VR_COMMON_VERBOSE(fmt, args...) do { \ + if (g_wb_vr_common_debug) { \ + printk(KERN_INFO "[WB_VR_COMMON][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_VR_COMMON_ERROR(fmt, args...) do { \ + if (g_wb_vr_common_error) { \ + printk(KERN_ERR "[WB_VR_COMMON][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static int of_vr_common_config_init(struct platform_device *pdev, wb_vr_common_t *wb_vr_common_dev) +{ + int ret = 0; + + ret += of_property_read_u32(pdev->dev.of_node, "i2c_bus", &wb_vr_common_dev->i2c_bus); + ret += of_property_read_u32(pdev->dev.of_node, "i2c_addr", &wb_vr_common_dev->i2c_addr); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret); + return -ENXIO; + } + + WB_VR_COMMON_VERBOSE("i2c_bus: %d, i2c_addr: 0x%x\n", wb_vr_common_dev->i2c_bus, wb_vr_common_dev->i2c_addr); + + return 0; +} + +static int vr_common_config_init(struct platform_device *pdev, wb_vr_common_t *wb_vr_common_dev) +{ + wb_vr_common_device_t *wb_vr_common_device; + + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + wb_vr_common_device = pdev->dev.platform_data; + + wb_vr_common_dev->i2c_bus = wb_vr_common_device->i2c_bus; + wb_vr_common_dev->i2c_addr = wb_vr_common_device->i2c_addr; + + WB_VR_COMMON_VERBOSE("i2c_bus: %d, i2c_addr: 0x%x\n", wb_vr_common_dev->i2c_bus, wb_vr_common_dev->i2c_addr); + + return 0; +} + +static int vr_common_probe(struct platform_device *pdev) +{ + wb_vr_common_t *wb_vr_common_dev; + struct i2c_client *client = NULL; + char device_id[DEVICE_ID_LEN]; + struct i2c_adapter *adapter; + struct i2c_board_info board_info; + u8 buf[I2C_SMBUS_BLOCK_MAX]; + int i, ret, len, offset; + + wb_vr_common_dev = devm_kzalloc(&pdev->dev, sizeof(wb_vr_common_t), GFP_KERNEL); + if (!wb_vr_common_dev) { + dev_err(&pdev->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + if (pdev->dev.of_node) { + ret = of_vr_common_config_init(pdev, wb_vr_common_dev); + } else { + ret = vr_common_config_init(pdev, wb_vr_common_dev); + } + + if (ret < 0) { + return ret; + } + + adapter = i2c_get_adapter(wb_vr_common_dev->i2c_bus); + if (!adapter) { + dev_err(&pdev->dev, "Failed to get I2C adapter for bus %d\n", wb_vr_common_dev->i2c_bus); + wb_vr_common_dev->adap = NULL; + return -ENODEV; + } + wb_vr_common_dev->adap = adapter; + + client = i2c_new_dummy_device(adapter, wb_vr_common_dev->i2c_addr); + if (IS_ERR(client)) { + dev_err(&pdev->dev, "%s: new dummy i2c device failed\n", __func__); + ret = PTR_ERR(client); + goto put_adapter; + } + + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); + if (ret >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + if (ret < 0) { + dev_info(&pdev->dev, "PMBus set page 0 failed!\n"); + } + + /* Enable PEC if the controller supports it */ + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); + if (ret >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + // if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)){ + // client->flags |= I2C_CLIENT_PEC; + // } + + for(i = 0; i < PMBUS_RETRY_TIME; i++) { + mem_clear(buf, sizeof(buf)); + len = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); + if (len >= 0) { + break; + } + usleep_range(PMBUS_RETRY_SLEEP_TIME, PMBUS_RETRY_SLEEP_TIME + 1); + } + if (len < 0) { + dev_err(&pdev->dev, "read i2c block data failed, ret:%d.\n", len); + i2c_unregister_device(client); + ret = -ENODEV; + goto put_adapter; + } + i2c_unregister_device(client); + client = NULL; + + offset = 0; + mem_clear(device_id, sizeof(device_id)); + for (i = 0; i < len; i++) { + offset += scnprintf(device_id + offset, DEVICE_ID_LEN - offset, "0x%02x ", buf[i]); + } + dev_info(&pdev->dev, "get vr dev device id success, id: %s.\n", device_id); + + mem_clear(&board_info, sizeof(struct i2c_board_info)); + ret = -ENODEV; + for (i = 0; i < ARRAY_SIZE(pmbus_dev_infos); i++) { + if ((len == pmbus_dev_infos[i].dev_id_len) && (memcmp(buf, pmbus_dev_infos[i].device_id, len) == 0)) { + dev_info(&pdev->dev, "find vr device success, device name: %s, i2c bus: %d, i2c addr: 0x%x.\n", + pmbus_dev_infos[i].device_name, wb_vr_common_dev->i2c_bus, wb_vr_common_dev->i2c_addr); + strscpy(board_info.type, pmbus_dev_infos[i].device_name, I2C_NAME_SIZE); + board_info.addr = wb_vr_common_dev->i2c_addr; + client = i2c_new_client_device(adapter, &board_info); + if (IS_ERR(client)) { + dev_err(&pdev->dev, "register device i2c client fail, device name: %s, i2c bus: %d, i2c addr: 0x%x.\n", + pmbus_dev_infos[i].device_name, wb_vr_common_dev->i2c_bus, wb_vr_common_dev->i2c_addr); + ret = PTR_ERR(client); + goto put_adapter; + } + wb_vr_common_dev->client = client; + platform_set_drvdata(pdev, wb_vr_common_dev); + ret = 0; + break; + } + } + + if (ret == 0) { + dev_info(&pdev->dev, "register vr device success, device name: %s, i2c bus: %d, i2c addr: 0x%x.\n", + pmbus_dev_infos[i].device_name, wb_vr_common_dev->i2c_bus, wb_vr_common_dev->i2c_addr); + } else { + dev_err(&pdev->dev, "find vr device fail, not support device id : %s.\n", device_id); + } + +put_adapter: + i2c_put_adapter(adapter); + return ret; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,11,0) +static void vr_common_remove(struct platform_device *pdev) +#else +static int vr_common_remove(struct platform_device *pdev) +#endif +{ + wb_vr_common_t *wb_vr_common_dev; + int i2c_bus, i2c_addr; + struct i2c_adapter *adap; + + wb_vr_common_dev = platform_get_drvdata(pdev); + if (wb_vr_common_dev == NULL) { + dev_warn(&pdev->dev, "wb_vr_common_dev is NULL, exit\n"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0) + return 0; +#endif + } + + i2c_bus = wb_vr_common_dev->i2c_bus; + i2c_addr = wb_vr_common_dev->i2c_addr; + WB_VR_COMMON_VERBOSE("Enter vr_common_remove, i2c_bus: %d, i2c addr: 0x%02x\n", i2c_bus, i2c_addr); + + adap = i2c_get_adapter(i2c_bus); + if (adap == NULL) { + dev_warn(&pdev->dev, "i2c adapter-%d is NULL, skip to unregister i2c client: %d-%04x\n", i2c_bus, i2c_bus, i2c_addr); + goto exit; + } + if (adap != wb_vr_common_dev->adap) { + dev_warn(&pdev->dev, "i2c adapter-%d address changed, origin addr: %pK, new addr: %pK, skip to unregister i2c client: %d-%04x\n", + i2c_bus, wb_vr_common_dev->adap, adap, i2c_bus, i2c_addr); + goto exit_i2c_put; + } + + if (wb_vr_common_dev->client != NULL) { + WB_VR_COMMON_VERBOSE("Starting unregister i2c client: %d-%04x\n", i2c_bus, i2c_addr); + if (device_is_registered(&wb_vr_common_dev->client->dev)) { + i2c_unregister_device(wb_vr_common_dev->client); + dev_info(&pdev->dev, "Unregister i2c client: %d-%04x success\n", i2c_bus, i2c_addr); + } else { + dev_warn(&pdev->dev, "i2c client: %d-%04x already unregister\n", i2c_bus,i2c_addr); + } + wb_vr_common_dev->client = NULL; + } else { + dev_warn(&pdev->dev, "i2c client: %d-%04x is NULL\n", i2c_bus,i2c_addr); + } +exit_i2c_put: + i2c_put_adapter(adap); +exit: + wb_vr_common_dev->adap = NULL; + platform_set_drvdata(pdev, NULL); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0) + return 0; +#endif +} + +static struct of_device_id vr_common_match[] = { + { + .compatible = "wb-vr-common", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, vr_common_match); + +static struct platform_driver wb_vr_common_driver = { + .probe = vr_common_probe, + .remove = vr_common_remove, + .driver = { + .owner = THIS_MODULE, + .name = PROXY_NAME, + .of_match_table = vr_common_match, + }, +}; + +static int __init wb_vr_common_init(void) +{ + return platform_driver_register(&wb_vr_common_driver); +} + +static void __exit wb_vr_common_exit(void) +{ + platform_driver_unregister(&wb_vr_common_driver); +} + +module_init(wb_vr_common_init); +module_exit(wb_vr_common_exit); +MODULE_DESCRIPTION("vr common driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.h new file mode 100644 index 0000000000..432af3d018 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_vr_common.h @@ -0,0 +1,27 @@ +#ifndef __WB_VR_COMMON_H__ +#define __WB_VR_COMMON_H__ + +#include + +#define DEVICE_ID_LEN (256) + +typedef struct wb_vr_common_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + struct i2c_client *client; + struct i2c_adapter *adap; +} wb_vr_common_t; + +typedef struct wb_vr_common_device_s { + uint32_t i2c_bus; + uint32_t i2c_addr; + int device_flag; +} wb_vr_common_device_t; + +typedef struct { + char device_name[I2C_NAME_SIZE]; + uint8_t device_id[DEVICE_ID_LEN]; + uint32_t dev_id_len; +} vr_dev_info_t; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c index 7200b6f66d..b16b4bca99 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c @@ -59,6 +59,11 @@ module_param(g_wb_xdpe132g5_pmbus_error, int, S_IRUGO | S_IWUSR); #define XDPE132G5C_PROT_VR13_5MV (0x07) /* VR13.0 mode, 5-mV DAC */ #define RETRY_TIME (15) +enum chips { + XDPE132G5C, + XDPE1A2G5B +}; + typedef struct xdpe_vout_data_s { u8 vout_mode; int vout_precision; @@ -329,25 +334,45 @@ static int xdpe132g5c_identify(struct i2c_client *client, struct pmbus_driver_in return 0; } -static struct pmbus_driver_info xdpe132g5c_info = { - .pages = XDPE132G5C_PAGE_NUM, - .format[PSC_VOLTAGE_IN] = linear, - .format[PSC_VOLTAGE_OUT] = linear, - .format[PSC_TEMPERATURE] = linear, - .format[PSC_CURRENT_IN] = linear, - .format[PSC_CURRENT_OUT] = linear, - .format[PSC_POWER] = linear, - .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN +static struct pmbus_driver_info xdpe1x2g5_info[] = { + [XDPE132G5C] = { + .pages = XDPE132G5C_PAGE_NUM, + .format[PSC_VOLTAGE_IN] = linear, + .format[PSC_VOLTAGE_OUT] = linear, + .format[PSC_TEMPERATURE] = linear, + .format[PSC_CURRENT_IN] = linear, + .format[PSC_CURRENT_OUT] = linear, + .format[PSC_POWER] = linear, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, - .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN + .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, - .groups = xdpe132g5_attribute_groups, - .identify = xdpe132g5c_identify, + .groups = xdpe132g5_attribute_groups, + .identify = xdpe132g5c_identify, + }, + [XDPE1A2G5B] = { + .pages = XDPE132G5C_PAGE_NUM, + .format[PSC_VOLTAGE_IN] = linear, + .format[PSC_VOLTAGE_OUT] = linear, + .format[PSC_TEMPERATURE] = linear, + .format[PSC_CURRENT_IN] = linear, + .format[PSC_CURRENT_OUT] = linear, + .format[PSC_POWER] = linear, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, + .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | + PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, + .groups = xdpe132g5_attribute_groups, + }, }; #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) @@ -356,15 +381,18 @@ static int xdpe132g5c_probe(struct i2c_client *client, const struct i2c_device_i static int xdpe132g5c_probe(struct i2c_client *client) #endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) + const struct i2c_device_id *id = i2c_client_get_device_id(client); +#endif int status; struct pmbus_driver_info *info; - info = devm_kmemdup(&client->dev, &xdpe132g5c_info, sizeof(*info), GFP_KERNEL); + info = devm_kmemdup(&client->dev, &xdpe1x2g5_info[id->driver_data], sizeof(*info), GFP_KERNEL); if (!info) { return -ENOMEM; } - status = pmbus_do_probe(client, &xdpe132g5c_info); + status = pmbus_do_probe(client, info); if (status != 0) { WB_XDPE132G5_PMBUS_ERROR("pmbus probe error %d\n", status); return status; @@ -394,14 +422,16 @@ static void xdpe132g5c_remove(struct i2c_client *client) } static const struct i2c_device_id xdpe132g5c_id[] = { - {"wb_xdpe132g5c_pmbus", 0}, + {"wb_xdpe132g5c_pmbus", XDPE132G5C}, + {"wb_xdpe1a2g5b_pmbus", XDPE1A2G5B}, {} }; MODULE_DEVICE_TABLE(i2c, xdpe132g5c_id); static const struct of_device_id __maybe_unused xdpe132g5c_of_match[] = { - {.compatible = "infineon,wb_xdpe132g5c_pmbus"}, + {.compatible = "infineon,wb_xdpe132g5c_pmbus", .data = (void *)XDPE132G5C}, + {.compatible = "infineon,wb_xdpe1a2g5b_pmbus", .data = (void *)XDPE1A2G5B}, {} }; MODULE_DEVICE_TABLE(of, xdpe132g5c_of_match); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_i2c_debug.h b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_i2c_debug.h new file mode 100644 index 0000000000..c0cd88891a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_i2c_debug.h @@ -0,0 +1,280 @@ +/* wb_bsp_i2c_debug.h */ +#ifndef __WB_BSP_I2C_DEBUG_H__ +#define __WB_BSP_I2C_DEBUG_H__ + +#include +#include +#include +#include +#include +#include +#include "wb_bsp_kernel_debug.h" + +/* 0x12caddb9 looks a lot like "i2c ad dbg". */ +#define MAGIC_NUM (0x12caddb9) +#define DEBUG_ALL_VALID_BITS \ + (DEBUG_ERR_LEVEL | DEBUG_WARN_LEVEL | DEBUG_INFO_LEVEL | DEBUG_VER_LEVEL) +/* + * The struct i2c_adapter_debug must be the first member + * of the private structure of the I2C controller. + */ +struct i2c_adapter_debug { + int magic_num; + int debug_level; +}; + +/** + * create_adapter_dbg - Create debug info entry for the specified adapter + * @adapter: specified i2c_adapter + * + * Returns 0 on success, negative error code on failure + */ +static inline int create_adapter_dbg(struct i2c_adapter *adapter) +{ + struct i2c_adapter_debug *dbg; + + if (adapter == NULL) { + return -EINVAL; + } + + dbg = (struct i2c_adapter_debug *)(i2c_get_adapdata(adapter)); + if (dbg == NULL) { + return -EINVAL; + } + + dbg->magic_num = MAGIC_NUM; + dbg->debug_level = 0; + + return 0; +} + +/** + * destroy_adapter_dbg - Remove debug info entry for the specified adapter + * @adapter: specified i2c_adapter + */ +static inline void destroy_adapter_dbg(struct i2c_adapter *adapter) +{ + struct i2c_adapter_debug *dbg; + + if (adapter == NULL) { + return; + } + + dbg = (struct i2c_adapter_debug *)(i2c_get_adapdata(adapter)); + if (dbg == NULL) { + return; + } + dbg->magic_num = 0; + dbg->debug_level = 0; + + return; +} + +/** + * get_adapter_dbg - Get debug info pointer for the specified adapter + * @adapter: specified i2c_adapter + * + * Returns pointer to debug info, or NULL if not found + */ +static inline struct i2c_adapter_debug *get_adapter_dbg(struct i2c_adapter *adapter) +{ + struct i2c_adapter_debug *dbg; + + if (adapter == NULL) { + return NULL; + } + + dbg = (struct i2c_adapter_debug *)(i2c_get_adapdata(adapter)); + if ((dbg != NULL) && (dbg->magic_num != MAGIC_NUM)) { + return NULL; + } + + return dbg; +} + +/* sysfs show function, displays debug enable status */ +static ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct i2c_adapter *adap; + struct i2c_adapter_debug *dbg; + int offset; + + adap = container_of(kobj, struct i2c_adapter, dev.kobj); + dbg = get_adapter_dbg(adap); + + if (dbg == NULL || dbg->magic_num != MAGIC_NUM || dbg->debug_level == 0) { + return scnprintf(buf, PAGE_SIZE, "Current debug status: %s\n", "disabled"); + } + + offset = scnprintf(buf, PAGE_SIZE, "Current debug status: %s\n", "enabled"); + if (dbg->debug_level & DEBUG_ERR_LEVEL) { + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\terror\n"); + } + if (dbg->debug_level & DEBUG_WARN_LEVEL) { + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\twarn\n"); + } + if (dbg->debug_level & DEBUG_INFO_LEVEL) { + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\tinfo\n"); + } + if (dbg->debug_level & DEBUG_VER_LEVEL) { + offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\tverbose\n"); + } + + return offset; +} + +/* sysfs store function, sets debug enable status */ +static ssize_t debug_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_adapter *adap; + struct i2c_adapter_debug *dbg; + unsigned long input_val; + int ret; + + adap = container_of(kobj, struct i2c_adapter, dev.kobj); + dbg = get_adapter_dbg(adap); + if (dbg == NULL) { + return -EINVAL; + } + + input_val = 0; + ret = kstrtoul(buf, 0, &input_val); + if (ret) { + return -EINVAL; + } + + if ((input_val & ~DEBUG_ALL_VALID_BITS) != 0) { + return -EINVAL; + } + + dbg->debug_level = input_val; + + pr_info("i2c adapter %d debug level set to 0x%lx\n", adap->nr, input_val); + + return count; +} + +static struct kobj_attribute debug_attribute = + __ATTR(debug, 0664, debug_show, debug_store); + +/** + * i2c_adapter_debug_init - Initialize debug info and create sysfs file for adapter + * @adap: specified i2c_adapter + * + * Returns 0 on success, negative error code on failure + */ +static inline int i2c_adapter_debug_init(struct i2c_adapter *adap) +{ + int ret; + + ret = create_adapter_dbg(adap); + if (ret) { + return ret; + } + + ret = sysfs_create_file(&adap->dev.kobj, &debug_attribute.attr); + if (ret) { + /* On failure, rollback created debug info */ + destroy_adapter_dbg(adap); + } + return ret; +} + +/** + * I2C_ADAPTER_DEBUG_INIT - Debug initialization macro (compile-time check + runtime init) + * @dev_type: Structure type (e.g., struct dw_i2c_dev) + * @dev_ptr: Pointer to the structure instance (e.g., dev) + * @dbg_member: Name of the debug member in the structure (e.g., i2c_ada_dbg) + * + * Description: + * 1. Compile-time check: Ensures the debug member is the first member of the structure + * (offset must be 0; fails compilation if not). + * 2. Runtime initialization: Calls the debug initialization function to bind I2C adapter + * with debug functionality (sysfs nodes, debug level management, etc.). + */ +#define I2C_ADAPTER_DEBUG_INIT(adapter, dev_type, dbg_member) do { \ + /* Compile-time check: Debug struct must be the first member (offset 0) */ \ + BUILD_BUG_ON(offsetof(dev_type, dbg_member) != 0); \ + /* Runtime initialization: Initialize debug features for the I2C adapter */ \ + (void)i2c_adapter_debug_init(adapter); \ +} while (0) + +/** + * i2c_adapter_debug_exit - Cleanup debug info and remove sysfs file for adapter + * @adap: specified i2c_adapter + */ +static inline void i2c_adapter_debug_exit(struct i2c_adapter *adap) +{ + struct i2c_adapter_debug *dbg; + + dbg = get_adapter_dbg(adap); + if (dbg == NULL) { + return; + } + + sysfs_remove_file(&adap->dev.kobj, &debug_attribute.attr); + destroy_adapter_dbg(adap); +} + +static inline bool i2c_adapter_debug_enabled(struct i2c_adapter *adap, int level) +{ + struct i2c_adapter_debug *dbg; + + if (adap == NULL) { + return false; + } + + dbg = get_adapter_dbg(adap); + if (dbg == NULL) { + return false; + } + + return (dbg->debug_level & level) != 0; +} + +static inline int i2c_adapter_get_nr(struct i2c_adapter *adap) +{ + return (adap == NULL) ? -1 : adap->nr; +} + +#define i2c_pr_fmt(fmt, nr) "[func:%s line:%d][i2c-%d]" fmt, __func__, __LINE__, (nr) + +/* Debug print macros, depend on external variable debug and DEBUG_*_LEVEL macros */ +#define DEBUG_ERROR_I2C_ADAPTER(adapter, fmt, ...) \ + do { \ + if ((debug & DEBUG_ERR_LEVEL) || i2c_adapter_debug_enabled(adapter, DEBUG_ERR_LEVEL)) { \ + printk(KERN_ERR "[ERR]"i2c_pr_fmt(fmt, i2c_adapter_get_nr(adapter)), ##__VA_ARGS__); \ + } else { \ + pr_debug(fmt, ##__VA_ARGS__); \ + } \ + } while(0) + +#define DEBUG_WARN_I2C_ADAPTER(adapter, fmt, ...) \ + do { \ + if ((debug & DEBUG_WARN_LEVEL) || i2c_adapter_debug_enabled(adapter, DEBUG_WARN_LEVEL)) { \ + printk(KERN_WARNING "[WARN]"i2c_pr_fmt(fmt, i2c_adapter_get_nr(adapter)), ##__VA_ARGS__); \ + } else { \ + pr_debug(fmt, ##__VA_ARGS__); \ + } \ + } while(0) + +#define DEBUG_INFO_I2C_ADAPTER(adapter, fmt, ...) \ + do { \ + if ((debug & DEBUG_INFO_LEVEL) || i2c_adapter_debug_enabled(adapter, DEBUG_INFO_LEVEL)) { \ + printk(KERN_INFO "[INFO]"i2c_pr_fmt(fmt, i2c_adapter_get_nr(adapter)), ##__VA_ARGS__); \ + } else { \ + pr_debug(fmt, ##__VA_ARGS__); \ + } \ + } while(0) + +#define DEBUG_VERBOSE_I2C_ADAPTER(adapter, fmt, ...) \ + do { \ + if ((debug & DEBUG_VER_LEVEL) || i2c_adapter_debug_enabled(adapter, DEBUG_VER_LEVEL)) { \ + printk(KERN_DEBUG "[VER]"i2c_pr_fmt(fmt, i2c_adapter_get_nr(adapter)), ##__VA_ARGS__); \ + } else { \ + pr_debug(fmt, ##__VA_ARGS__); \ + } \ + } while(0) + +#endif /* __WB_BSP_I2C_DEBUG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_kernel_debug.h b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_kernel_debug.h new file mode 100644 index 0000000000..4997993806 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_bsp_kernel_debug.h @@ -0,0 +1,65 @@ +/* kernel_debug.h */ +#include +#ifndef __WB_BSP_KERNEL_DEBUG_H__ +#define __WB_BSP_KERNEL_DEBUG_H__ + +/********************************** start ***********************************/ +/** + * Module input parameters control debug printing. + * Dynamic debug printing is used by default, controlled by debugfs + */ +#define DEBUG_ERR_LEVEL (0x1) +#define DEBUG_WARN_LEVEL (0x2) +#define DEBUG_INFO_LEVEL (0x4) +#define DEBUG_VER_LEVEL (0x8) +/* This macro definition is specifically designed for printing logic device driver data and is not intended for any other debugging purposes. */ +#define DEBUG_DUMP_DATA_LEVEL (0x8000) + +#define mem_clear(data, size) memset((data), 0, (size)) + +#define DEBUG_ERROR(fmt, args...) \ + do { \ + if (debug & DEBUG_ERR_LEVEL) { \ + printk(KERN_ERR "[ERR][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_WARN(fmt, args...) \ + do { \ + if (debug & DEBUG_WARN_LEVEL) { \ + printk(KERN_WARNING "[WARN][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_INFO(fmt, args...) \ + do { \ + if (debug & DEBUG_INFO_LEVEL) { \ + printk(KERN_INFO "[INFO][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define DEBUG_VERBOSE(fmt, args...) \ + do { \ + if (debug & DEBUG_VER_LEVEL) { \ + printk(KERN_DEBUG "[VER][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } else { \ + pr_debug(fmt, ## args); \ + } \ + } while(0) + +#define PRINT_ERROR(fmt, args...) \ + do { \ + printk(KERN_ERR "[ERR][func:%s line:%d] "fmt, __func__, __LINE__, ## args); \ + } while(0) + +#define COMMON_ERROR_PRINT(buf, buf_size, fmt, ...) \ + snprintf((buf), (buf_size), "ERROR: "fmt"", ##__VA_ARGS__) +/********************************** end ***********************************/ + +#endif /* #ifndef __WB_BSP_KERNEL_DEBUG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_kernel_io.h b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_kernel_io.h new file mode 100644 index 0000000000..3c12565c71 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_kernel_io.h @@ -0,0 +1,80 @@ +#ifndef __WB_KERNEL_IO_H__ +#define __WB_KERNEL_IO_H__ + +#include +#include +#include "wb_logic_dev_common.h" + +/* + * wb_io_fn_t - Function pointer type for read/write operations + * @file: pointer to struct file representing the file + * @buf: buffer to read from or write to + * @count: number of bytes to read/write + * @pos: pointer to file position offset + * + * Returns number of bytes read/written on success, negative error code on failure. + */ +typedef ssize_t (*wb_io_fn_t)(struct file *, char *, size_t, loff_t *); + +/* + * wb_iov_iter_read - Read data from file into iov_iter using buffer + * @iocb: pointer to kiocb structure containing file and position info + * @to: iov_iter representing destination of data (user or kernel space) + * @rw_func: callback function to perform actual read operation + * + * Returns total bytes read on success, or negative error code on failure. + */ +static inline ssize_t wb_iov_iter_read(struct kiocb *iocb, struct iov_iter *to, wb_io_fn_t rw_func) +{ + char buffer[MAX_RW_LEN]; + ssize_t ret; + size_t read_size; + + read_size = iov_iter_count(to); + if (read_size > MAX_RW_LEN) { + read_size = MAX_RW_LEN; + } + + /* Call user-provided read function */ + ret = rw_func(iocb->ki_filp, buffer, read_size, &iocb->ki_pos); + if (ret <= 0) { + return ret; + } + + return copy_to_iter(buffer, ret, to); +} + +/* + * wb_iov_iter_write - Write data from iov_iter to file using intermediate buffer + * @iocb: pointer to kiocb structure containing file and position info + * @from: iov_iter representing source of data (user or kernel space) + * @rw_func: callback function to perform actual write operation + * + * Returns total bytes written on success, or negative error code on failure. + */ +static inline ssize_t wb_iov_iter_write(struct kiocb *iocb, struct iov_iter *from, + wb_io_fn_t rw_func) +{ + char buffer[MAX_RW_LEN]; + ssize_t ret; + size_t write_size; + + write_size = iov_iter_count(from); + if (write_size > MAX_RW_LEN) { + write_size = MAX_RW_LEN; + } + + /* + * Copy data from iov_iter to internal buffer. + * copy_from_iter() returns bytes NOT copied. + */ + ret = copy_from_iter(buffer, write_size, from); + if (ret < 0) { + return -EFAULT; + } + + /* Call user-provided write function */ + return rw_func(iocb->ki_filp, buffer, write_size, &iocb->ki_pos); +} + +#endif /* __WB_KERNEL_IO_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_logic_dev_common.h b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_logic_dev_common.h new file mode 100644 index 0000000000..1d38ae72dd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_logic_dev_common.h @@ -0,0 +1,301 @@ +#ifndef __WB_LOGIC_DEV_COMMON_H__ +#define __WB_LOGIC_DEV_COMMON_H__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef PRIu64 +#define PRIu64 "llu" +#endif + +#ifndef PRIX64 +#define PRIX64 "llx" +#endif + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) +#define SYMBOL_SPI_DEV_MODE (5) +#define SYMBOL_INDIRECT_DEV_MODE (6) +#define SYMBOL_PLATFORM_I2C_DEV_MODE (7) +#define SYMBOL_SPI_DEV_ATOMIC_MODE (8) /* spi atomic mode, use for irq mode access spi dev */ + +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) +#define MAX_DATA_WIDTH (8) +#define MAX_DEV_NUM (64) +#define MAX_RW_LEN (256) +#define MAX_NAME_SIZE (32) +#define LOGIC_DEV_DUMP_NAME_LEN (64) +#define LOGIC_DEV_DUMP_MAX_NUM (8) +#define LOGIC_DEV_DUMP_REG_END_DEFAULT (0xff) + +#define CACHE_FILE_PATH "/tmp/.%s_cache" +#define MASK_FILE_PATH "/tmp/.%s_mask" + +#define LOGIC_DEV_RETRY_TIME (3) +#define LOGIC_DEV_RETRY_TIMEOUT (3000) +#define LOGIC_DEV_RETRY_DELAY_MS (10) +#define LOGIC_DEV_STATUS_OK (0) +#define LOGIC_DEV_STATUS_NOT_OK (1) + +static inline int wb_logic_get_retry_time(int retry_time) +{ + return retry_time > 0 ? retry_time : 1; +} + +#define TEST_REG_MAX_NUM (8) +#define INIT_TEST_DATA (0x5a) +#define MAX_REG_DATA_LEN (MAX_DATA_WIDTH * TEST_REG_MAX_NUM) + +/* Device read/write enable flag */ +#define WB_DEV_AVAILABLE_FLAG (1) +#define WB_DEV_UNAVAILABLE_FLAG (0) + +typedef enum dev_status_check_type_s { + NOT_SUPPORT_CHECK_STATUS = 0, /* Not support status check */ + READ_BACK_CHECK = 1, /* Readback verification */ + READ_BACK_NAGATIVE_CHECK = 2, /* Readback anti-verification */ + READ_ONLY_CHECK = 3, /* Read only */ + SUPPORT_CHECK_MAX, +} dev_status_check_type_t; + +typedef enum { + WB_SPIN_LOCK_MODE = 1, + WB_MUTEX_LOCK_MODE = 2, +} cs_lock_mode_t; + +#define BSP_KEY_DEVICE_LOG_SIZE (256) +#define BSP_KEY_DEVICE_NUM_MAX (64) +#define BSP_KEY_DEV_INDEX_TO_ADDR(index) ((index) & 0xffff) +#define BSP_KEY_DEV_INDEX_TO_SIZE(index) (((index) >> 16) & 0xffff) +#define BSP_LOG_DIR "/var/log/bsp_tech/" +#define BSP_LOG_TS_BUFF_SIZE (32) +#define WB_BSP_LOG_MAX (1 * 1024 * 1024) +#define BSP_LOG_DEV_NAME_MAX_LEN (64) + +/* CRAM */ +#define CRAM_REG_OFFSET (14) +#define CRAM_REG_BYTE_INDEX (1) +#define CRAM_REG_BYTE_OFFSET (6) +#define CRAM_REG_MASK (0x3) +#define CRAM_STATUS(value) ((value >> CRAM_REG_OFFSET) & CRAM_REG_MASK) +#define CRAM_STATUS_FROM_BYTE(value) ((value[CRAM_REG_BYTE_INDEX] >> CRAM_REG_BYTE_OFFSET) & CRAM_REG_MASK) +#define CRAM_CE_STATUS (0x1) +#define CRAM_UE_STATUS (0x2) +#define CRAM_STATUS_OK (0) +#define CRAM_ALL_BITS_SET (~0) +#define CRAM_CONFIG_MASK_MIN_COUNT (1) +#define CRAM_ERR_ADDR_DATA_OFFSET (2) +#define CRAM_ERR_ADDR_NUM_DEF (1) +#define CRAM_ERR_ADDR_REG_MASK_DEF (0xfc) +#define CRAM_STATUS_SINGLE_BIT_ERROR (0x1) +#define CRAM_STATUS_MULTI_BIT_ERROR (0x2) +#define CRAM_STATUS_SINGLE_MULTI_BIT_ERROR (0x3) +#define CRAM_DETAIL_SINGLE_BIT_ERROR "SingleBit_Error" +#define CRAM_DETAIL_MULTI_BIT_ERROR "MultiBit_Error" +#define CRAM_DETAIL_LOGICDEV_ERROR "LogicDevRead_Error" + + +typedef struct { + uint32_t log_num; + uint32_t log_index[BSP_KEY_DEVICE_NUM_MAX]; + struct mutex file_lock; +} wb_bsp_key_device_log_node_t; + +#define DEBUG_BUF_MAX_LEN (256) + +extern struct kobject *logic_dev_kobj; +extern unsigned long (*kallsyms_lookup_name_fun)(const char *name); + +typedef int (*device_func_write)(const char *, uint32_t, uint8_t *, size_t); +typedef int (*device_func_read)(const char *, uint32_t, uint8_t *, size_t ); +typedef int (*get_pci_dev_func)(const char *, struct pci_dev **); +typedef int (*wb_cs_func)(uint32_t cs_index); + +typedef struct logic_dev_dump_cfg_s { + char logic_dev_name[LOGIC_DEV_DUMP_NAME_LEN]; + int logic_dev_func_mode; + int logic_dev_reg_start; + int logic_dev_reg_end; +} logic_dev_dump_cfg_t; + +typedef struct logic_dev_dump_s { + const char *logic_dev_name; + uint32_t logic_dev_func_mode; + uint32_t logic_dev_reg_start; + uint32_t logic_dev_reg_end; + unsigned long logic_dev_write_intf_addr; + unsigned long logic_dev_read_intf_addr; +} logic_dev_dump_t; + +typedef struct logic_dev_dump_cfg_info_s { + uint32_t dump_logic_dev_num; + logic_dev_dump_cfg_t dump_logic_dev_cfg[LOGIC_DEV_DUMP_MAX_NUM]; +} logic_dev_dump_cfg_info_t; + +typedef struct logic_dev_dump_info_s { + uint32_t dump_logic_dev_num; + logic_dev_dump_t dump_logic_dev_cfg[LOGIC_DEV_DUMP_MAX_NUM]; +} logic_dev_dump_info_t; + +int find_intf_addr(unsigned long *write_intf_addr, unsigned long *read_intf_addr, uint32_t mode); +int cache_value_read(const char *mask_file_path, const char *cache_file_path, uint32_t offset, uint8_t *value, uint32_t width); +int cache_value_write(const char *mask_file_path, const char *cache_file_path, uint32_t offset, uint8_t *value, uint32_t width); +int dev_rw_check(uint8_t *rd_buf, uint8_t *wr_buf, uint32_t len, uint32_t type, uint32_t check_mode); +int wb_bsp_key_device_log(char *dev_name, char *log_name, int log_size, + wb_bsp_key_device_log_node_t *log_node, uint32_t offset, uint8_t *buf, size_t size); +void logic_dev_dump_data(const char *dev_name, uint32_t offset, u8 *val, size_t count, bool read_flag); +int find_cs_intf_addr(unsigned long *cs_enable_intf_addr, unsigned long *cs_disable_intf_addr); +int logic_dev_dump_of_node_init(logic_dev_dump_info_t *dump_info, struct device *dev); +int logic_dev_dump_cfg_info_init(logic_dev_dump_info_t *dump_info, struct device *dev, + const logic_dev_dump_cfg_info_t *dump_logic_dev_cfg_info); +void logic_dev_dump_regs(logic_dev_dump_info_t *dump_info, struct device *dev, const char *log_tag); + +typedef enum logic_dev_status_check_type_e { + STATUS_CHECK_SEU_E = 0, + STATUS_CHECK_SELFTEST_E = 1, + STATUS_CHECK_SCRATCH_E = 2, + STATUS_CHECK_CRAM_E = 3, + STATUS_CHECK_TYPE_MAX, +} logic_dev_status_check_type_t; + +typedef enum dev_status_check_mode_e { + WB_LOGIC_NORMAL = 0, + WB_LOGIC_NAGATIVE_MODE = 1, /* anti-verification */ + WB_LOGIC_SUPPORT_CHECK_MODE_MAX, +} dev_status_check_mode_t; + +typedef enum logic_dev_cram_check_type_e { + CRAM_CHECK_CE_E = 0, + CRAM_CHECK_UE_E = 1, + CRAM_TYPE_MAX, +} logic_dev_cram_check_type_t; + +/* status check function */ +#define STATUS_CHECK_BITS(type) (1UL << type) +#define STATUS_CHECK_SEU STATUS_CHECK_BITS(STATUS_CHECK_SEU_E) +#define STATUS_CHECK_SELFTEST STATUS_CHECK_BITS(STATUS_CHECK_SELFTEST_E) +#define STATUS_CHECK_SCRATCH STATUS_CHECK_BITS(STATUS_CHECK_SCRATCH_E) +#define STATUS_CHECK_CRAM STATUS_CHECK_BITS(STATUS_CHECK_CRAM_E) + +typedef struct reg_check { + u32 reg; + uint8_t value[MAX_DATA_WIDTH]; + uint8_t mask[MAX_DATA_WIDTH]; +} reg_check_t; + +struct seu_reg_check { + u32 reg; + uint8_t value[MAX_DATA_WIDTH]; + uint8_t mask[MAX_DATA_WIDTH]; +}; + +struct selftest_check { + u32 reg; + uint8_t write_value[MAX_DATA_WIDTH]; + u32 check_mode; /* write mode */ +}; + +struct scratch_check { + u32 reg; + uint8_t value[MAX_DATA_WIDTH]; + bool initialized; + u32 check_mode; /* write mode */ +}; + +struct cram_check { + u32 reg; + u32 cram_err_addr_reg_num; + u32 cram_err_addr_reg[TEST_REG_MAX_NUM]; + u32 cram_err_addr_reg_mask[TEST_REG_MAX_NUM]; +}; + +struct device_bus_ops { + device_func_read read; + device_func_write write; +}; + +typedef struct device_status_check { + u32 status_check_type_bmp; + char dev_name[MAX_NAME_SIZE]; + + u32 seu_check_num; + struct seu_reg_check seu_checks[TEST_REG_MAX_NUM]; + + u32 selftest_check_num; + struct selftest_check selftest_checks[TEST_REG_MAX_NUM]; + + u32 scratch_num; + struct scratch_check scratch_checks[TEST_REG_MAX_NUM]; + + struct cram_check cram_checks; + + struct device_bus_ops dev_bus_ops; + unsigned long last_jiffies; /* The number of jiffies when the device status was last obtained */ + u32 dev_status; /* Total status of check type */ + unsigned long type_last_jiffies[STATUS_CHECK_TYPE_MAX]; /* last jiffies by check type */ + u32 type_dev_status[STATUS_CHECK_TYPE_MAX]; /* status by check type */ +} device_status_check_t; + +int wb_logic_check_status_hw_init(struct device_status_check *status_check, + uint32_t data_byte_len); + +int wb_logic_dev_get_status(struct device_status_check *status_check, + uint32_t data_byte_len, + char *buf, + uint32_t buf_len); + +uint32_t wb_logic_status_type_get_number(uint32_t type); +int wb_logic_dev_get_status_with_type(struct device_status_check *status_check, + uint32_t data_byte_len, + char *buf, + uint32_t buf_len, + uint32_t type); + +int of_dev_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + device_func_write read, + device_func_write write, + const char *dev_name); + +int platform_dev_status_check_config_init(struct device *dev, + struct device_status_check *status_check, + uint32_t data_byte_len, + struct device_status_check *status_check_data, + device_func_write read, + device_func_write write, + const char *dev_name); + +int wb_logic_get_cache_status_with_type(struct device_status_check *status_check, + uint32_t check_type, + uint32_t status_cache_ms, + char *buf, + uint32_t buf_len); + +int wb_logic_clear_status(struct device_status_check *status_check, + uint32_t data_byte_len, + uint32_t type_bmp); + +/* end status check function */ +void sleep_by_lock_mode(int sleep_time, uint32_t lock_mode); + +int wb_logic_lock_mode_check(uint32_t lock_mode, uint32_t func_mode); + +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_platform_common.h b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_platform_common.h new file mode 100644 index 0000000000..ed7647283b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_platform_common.h @@ -0,0 +1,14 @@ +#ifndef __WB_PLATFORM_COMMON_H__ +#define __WB_PLATFORM_COMMON_H__ + +#define PRODUCT_STRATEGY_DEFAULT 0 +#define PRODUCT_STRATEGY_1 1 +#define PRODUCT_STRATEGY_2 2 + +#define PRODUCT_STRATEGY PRODUCT_STRATEGY_DEFAULT +#define CONFIG_FILE_PATH "/etc/" +#define SWITCH_STATUS_UNKNOWN "UNKNOWN" +#define S3IP_SYSFS_NAME "s3ip" +#define WB_HOST_MISC_DIR "/etc/sonic/" + +#endif /* WB_PLATFORM_COMMON_H */ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_spi_master.h b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_spi_master.h new file mode 100644 index 0000000000..ac749e7dd7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/public/include/wb_spi_master.h @@ -0,0 +1,16 @@ +#ifndef __WB_SPI_MASTER_H__ +#define __WB_SPI_MASTER_H__ + +#include +#include + +/** + * wb_spi_master_busnum_to_master - look up master associated with bus_num + * @bus_num: the master's bus number + * Context: can sleep + * + * Return: the SPI master structure on success, else NULL. + */ +struct spi_controller *wb_spi_master_busnum_to_master(u16 bus_num); + +#endif /* #ifndef __WB_SPI_MASTER_H__ */ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku-cpo.sh b/platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku-cpo.sh new file mode 100644 index 0000000000..8a181ffc28 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku-cpo.sh @@ -0,0 +1,203 @@ +#!/bin/bash +# +# This script is used to print, list and set the hwskus under the same platform. +# Regular user can print and list the current hwsku and all available hwskus. +# To change the hwsku, you will need root access. The main idea of the script +# was that each hwsku reserves it's own portmaping, minigraph, json etc. When we change the hwsku, +# the script will pickup the right configuration files and reboot the box to take effect +# (script will ask for reboot confirmation). This will override the existing configuration. +# The following command line help should explain the syntax +# +display_help() { + echo "Usage: $0 [-h] [-p] [-l] [-s HWSKU]" >&2 + echo + echo " -h, --help Print this usage page" + echo " -p, --print Print the current HWSKU" + echo " -l, --list List the available HWSKUs" + echo " -s, --set Set the HWSKU" + exit 0 +} + +HWSKU_ROOT='/usr/share/sonic/device/' +onie_platform=`grep onie_platform /host/machine.conf` +platform=${onie_platform#*=} +printf -v target_hwsku "%s%s%s%s" $HWSKU_ROOT $platform '/' "default_sku" +default_sku=`cat ${target_hwsku}` +sku_array=($default_sku) +current_hwsku=${sku_array[0]} +RUNNING_PATH='/etc/sonic/' + +config_hwsku_exec_1803() { + config_hwsku=$1 + while true; do + read -p "This will reset to the initial configuration with the port mode specified and restart all services. [Y/N] " yn + case $yn in + [Yy]* ) break;; + [Nn]* ) echo "No changes were made"; exit;; + * ) echo "Please input yes or no.";; + esac + done + + printf -v hwsku_minigraph "%s%s%s%s%s" $HWSKU_ROOT $platform '/' $config_hwsku '/' "minigraph.xml" + printf -v target_minigraph "%s%s%s%s" $HWSKU_ROOT $platform '/' "minigraph.xml" + running_minigraph=$RUNNING_PATH + running_minigraph+="minigraph.xml" + # default_sku + printf -v hwsku "%s%s%s%s%s%s" $HWSKU_ROOT $platform '/' $config_hwsku '/' "default_sku" + printf -v target_hwsku "%s%s%s%s" $HWSKU_ROOT $platform '/' "default_sku" + + if [ ! -e $hwsku_minigraph ]; then echo "Error: $hwsku_minigraph: No such file"; exit 1; fi + if [ ! -e $hwsku ]; then echo "Error: $hwsku: No such file"; exit 1; fi + + #echo copy $hwsku_minigraph " to " $target_minigraph + cp $hwsku_minigraph $target_minigraph + cp $hwsku_minigraph $running_minigraph + #echo copy $hwsku " to " $target_hwsku + cp $hwsku $target_hwsku + + #load minigraph + echo "Loading the new configuration" + config load_minigraph -y + + # save the json after backup + echo "Backup the old config_db.json to .bak file and save the new one." + target_json=$RUNNING_PATH + target_json+="config_db.json" + backup_json=$target_json".bak" + #echo copy $target_json to $backup_json + cp $target_json $backup_json + + config save -y + sync + echo "The configuration has been updated. Please reboot the system!" +} + +config_hwsku_exec() { + config_hwsku=$1 + while true; do + read -p "This will reset to the initial configuration with the port mode specified. [Y/N] " yn + case $yn in + [Yy]* ) break;; + [Nn]* ) echo "No changes were made"; exit;; + * ) echo "Please input yes or no.";; + esac + done + + # default_sku + printf -v hwsku "%s%s%s%s%s%s" $HWSKU_ROOT $platform '/' $config_hwsku '/' "default_sku" + printf -v target_hwsku "%s%s%s%s" $HWSKU_ROOT $platform '/' "default_sku" + + #echo copy $hwsku " to " $target_hwsku + if [ ! -e $hwsku ]; then echo "Error: $hwsku: No such file"; exit 1; fi + cp $hwsku $target_hwsku + + # save the json after backup + echo "Backup the old config_db.json to .bak file and save the new one." + target_json=$RUNNING_PATH + target_json+="config_db.json" + backup_json=$target_json".bak" + #echo copy $target_json to $backup_json + cp $target_json $backup_json + + #load default_sku + CONFIG_DB_INDEX=4 + cursor=0 + Ethernet="*Ethernet*" + echo "Loading the new configuration" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) + sonic-cfggen -H -k ${PRESET[0]} --preset ${PRESET[1]} > /etc/sonic/config_db.json + while true; do + result=$(redis-cli -n $CONFIG_DB_INDEX SCAN $cursor MATCH $Ethernet ) + cursor=$(echo "$result" | head -n 1) + + keys=$(echo "$result" | tail -n +2) + + if [ ! -z "$keys" ]; then + redis-cli -n $CONFIG_DB_INDEX DEL $keys >/dev/null 2>&1 + fi + + if [ "$cursor" == "0" ]; then + break + fi + done + + echo "The configuration is being updated, please wait for 20s." + sleep 20s + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + + config save -y + sync + echo "The configuration has been updated. Please reboot the system!" +} + +check_supported_hwskus() { + # Check the available HWSKUs + platform_dir="$HWSKU_ROOT""$platform"/ + supported_hwskus=`ls -l $platform_dir | egrep '^d' | awk '{print $9}' | grep -v plugins | grep -v led-code | grep -v cancun | grep -v pycache` +} +config_hwsku_fun() { + + config_hwsku=$1 + # Check root privileges + if [ "$EUID" -ne 0 ] + then + echo "Please run as root" + exit + fi + + if [ "$config_hwsku" == "$current_hwsku" ]; then + echo "The input HWSKU configuration is running, no changes were made" + exit + fi + + + # Check the available HWSKUs + check_supported_hwskus + + sonic_version=`grep build_version /etc/sonic/sonic_version.yml` + array=(${sonic_version//./ }) + branch=`echo ${array[1]} | sed $'s/\'//g'` + for hwsku in $supported_hwskus + do + if [ $config_hwsku == $hwsku ]; then + if [[ $branch =~ "201803" ]]; then + config_hwsku_exec_1803 "$config_hwsku" + else + config_hwsku_exec "$config_hwsku" + fi + exit + fi + done + + # Not matching any HWSKU names, print error + echo "Please use one of the options:" + echo -e "$supported_hwskus" + exit 1 +} + +main() { + case "$1" in + -h | --help) + display_help + ;; + -p | --print) + echo $current_hwsku + ;; + -l | --list) + check_supported_hwskus + echo -e "$supported_hwskus" + ;; + -s | --set) + config_hwsku=$2 + config_hwsku_fun "$config_hwsku" + ;; + *) + echo "Please use options as following:" >&2 + display_help + ;; + esac +} + +main "$@" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku.sh b/platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku.sh new file mode 100644 index 0000000000..19f650e68d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/config-hwsku.sh @@ -0,0 +1,260 @@ +#!/bin/bash +########################################################################### +# SONiC default HwSKU Setup utility # +# # +# This script is used to set HWSKU in deafult_sku # +# # +########################################################################### + +# Check for user permissions +check_permissions() +{ + if [ "$EUID" != "0" ]; then + echo "Root privileges are required for this operation" + exit 1 + fi +} + +# Command usage and help +usage() +{ + cat << EOF + Usage: config-hwsku < list | set [-y]> + -l - Display supported list HWSKU for this platform. + -s - Set user provided HwSKU as default SKU. + -y - Use this option to skip user confirmation + -p - Display current HWSKU +EOF +} + +# Collect all information needed to get list of HWSKU +get_platform_info() +{ + # Initialize variables + PLATFORM="" + + # Method 1: Try sonic-cfggen + if command -v sonic-cfggen &> /dev/null; then + # Use printf to ensure clean output and remove any carriage returns + PLATFORM=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform 2>/dev/null | tr -d '\r\n' | xargs) + fi + + # Method 2: Use machine.conf directly (most reliable) + if [ -z "$PLATFORM" ] && [ -f /host/machine.conf ]; then + PLATFORM=$(grep "^onie_platform=" /host/machine.conf | cut -d'=' -f2 | tr -d '\r\n' | xargs) + fi + + # Method 3: Use platform.json as fallback + if [ -z "$PLATFORM" ] && [ -f /etc/sonic/platform.json ]; then + PLATFORM=$(python3 -c "import json; f=open('/etc/sonic/platform.json'); d=json.load(f); print(d.get('platform', '')); f.close()" 2>/dev/null | tr -d '\r\n' | xargs) + fi + + # Final validation + if [ -z "$PLATFORM" ]; then + echo "Error: Cannot determine platform" + echo "Please check: /host/machine.conf or /etc/sonic/platform.json" + exit 1 + fi + + # Remove any remaining non-printable characters + PLATFORM=$(echo "$PLATFORM" | tr -cd '[:alnum:][:space:]-_.' | xargs) + + # Set platform directory + PLATFORM_DIR="/usr/share/sonic/device/$PLATFORM" + + if [ ! -d "$PLATFORM_DIR" ]; then + echo "Error: Platform directory not found: $PLATFORM_DIR" + echo "Available directories:" + ls -la /usr/share/sonic/device/ + exit 1 + fi + + # Get default SKU + if [ -f "$PLATFORM_DIR/default_sku" ]; then + # Read and clean the default_sku line + DEFAULT_SKU_LINE=$(head -n 1 "$PLATFORM_DIR/default_sku" | tr -d '\r\n' | xargs) + PRESET=($DEFAULT_SKU_LINE) + if [ ${#PRESET[@]} -ge 2 ]; then + HWSKU_STR_START=${PRESET[0]:0:4} + DEFAULT_PRESET=${PRESET[1]} + else + HWSKU_STR_START="" + DEFAULT_PRESET="" + fi + else + HWSKU_STR_START="" + DEFAULT_PRESET="" + echo "Warning: No default_sku found in $PLATFORM_DIR" + fi + + # Get current HWSKU + PRESENT_HWSKU="" + if command -v sonic-cfggen &> /dev/null; then + PRESENT_HWSKU=$(sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' 2>/dev/null | tr -d '\r\n' | xargs) + fi + + if [ -z "$PRESENT_HWSKU" ] && [ -f /etc/sonic/config_db.json ]; then + PRESENT_HWSKU=$(python3 -c "import json; f=open('/etc/sonic/config_db.json'); d=json.load(f); print(d.get('DEVICE_METADATA', {}).get('localhost', {}).get('hwsku', '')); f.close()" 2>/dev/null | tr -d '\r\n' | xargs) + fi +} + +# Display HWSKUs supported on current platform +list_hwskus() +{ + echo "List of supported HWSKU:" + if [ ! -d "$PLATFORM_DIR" ]; then + echo "Error: Platform directory not found" + return 1 + fi + + for sku in "$PLATFORM_DIR"/*/; do + if [ -d "$sku" ]; then + sku="${sku%/}" + sku="${sku##*/}" + + # Skip non-matching prefixes if defined + if [ -n "$HWSKU_STR_START" ] && [ "$HWSKU_STR_START" != "${sku:0:4}" ]; then + continue + fi + + if [ "$sku" = "$PRESENT_HWSKU" ]; then + echo "$sku (Present)" + else + echo "$sku" + fi + fi + done +} + +# Set requested HWSKU +set_hwsku() +{ + # Parse arguments passed + HWSKU=$(echo "$1" | tr -d '\r\n' | xargs) + + # Validate HWSKU is not empty + if [ -z "$HWSKU" ]; then + echo "Error: HWSKU name cannot be empty" + exit 1 + fi + + # Validate in Supported list + valid_sku=0 + for sku in "$PLATFORM_DIR"/*/; do + if [ -d "$sku" ]; then + sku="${sku%/}" + sku="${sku##*/}" + + if [ -n "$HWSKU_STR_START" ] && [ "$HWSKU_STR_START" != "${sku:0:4}" ]; then + continue + fi + + if [ "$sku" = "$HWSKU" ]; then + valid_sku=1 + break + fi + fi + done + + if [ $valid_sku -eq 1 ]; then + if [ "$PRESENT_HWSKU" = "$HWSKU" ]; then + echo "Same as present HWSKU $HWSKU, no changes made" + else + echo -e "Warning: This deletes existing configurations and cause switch to reboot." + if [ "${EXECUTE}" = "no" ]; then + read -r -p "Are you sure you want to change? [y/N] " response + else + response='y' + fi + case $response in + [yY][eE][sS]|[yY]) + echo "Setting Default HWSKU to $HWSKU $DEFAULT_PRESET" + + # Write to default_sku + if [ -f "$PLATFORM_DIR/default_sku" ]; then + echo "$HWSKU $DEFAULT_PRESET" > "$PLATFORM_DIR/default_sku" + fi + + # Update sonic-environment + if [ -r /etc/sonic/sonic-environment ]; then + sed -i '/HWSKU.*/d' /etc/sonic/sonic-environment + echo "HWSKU=$HWSKU" >> /etc/sonic/sonic-environment + fi + + echo "Removing existing config_db.json" + if [ -r /etc/sonic/config_db.json ]; then + rm -rf /etc/sonic/config_db.json + fi + + # Remove and recreate hwsku directory + echo "Deleting hwsku directory..." + rm -rf /usr/share/sonic/hwsku + + echo "Please reboot manually to apply changes" + ;; + *) + exit 0 + ;; + esac + fi + else + echo "Invalid HWSKU - $HWSKU" + echo "Available SKUs:" + list_hwskus + exit 1 + fi +} + +# Main function +main() +{ + # Check permissions first + check_permissions + + # Get platform information + get_platform_info + + local cmd="$1" + + if [ "$cmd" = "-p" ]; then + echo "$PRESENT_HWSKU" + exit 0 + fi + + if [ "$cmd" = "help" ] || \ + [ "$cmd" = "-h" ] || [ "$cmd" = "--help" ]; then + usage + exit 0 + fi + + # Display supported HWSKU's for current platform + if [ "$cmd" = "-l" ]; then + list_hwskus + # Set user provided HWSKU as default_SKU + elif [ "$cmd" = "-s" ]; then + EXECUTE="no" + if [ "$3" = "-y" ]; then + EXECUTE="yes" + elif [ -n "$3" ] && [ "$3" != "-y" ]; then + usage + exit 1 + fi + + if [ -z "$2" ]; then + echo "Error: HWSKU name required" + usage + exit 1 + fi + + set_hwsku "$2" + # Validate supported commands + else + usage + exit 1 + fi + + exit 0 +} + +# Call main function with all arguments +main "$@" \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/config-ledswitch.sh b/platform/broadcom/sonic-platform-modules-micas/common/script/config-ledswitch.sh new file mode 100644 index 0000000000..0a71936f52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/config-ledswitch.sh @@ -0,0 +1,265 @@ +#!/bin/bash +########################################################################### +# Script Name: ledswitch.sh +# Description: Control LED switch monitoring and display current status +# Usage: ./ledswitch.sh -l # Show current LED status +# ./ledswitch.sh -s {sdk|cpld} # Set LED status (sdk or cpld) +# ./ledswitch.sh -h # Show help information +########################################################################### + +SCRIPT_DIR="/usr/share/sonic/platform" +SCRIPT_NAME="ledswitch_monitor.py" +SCRIPT_PATH="${SCRIPT_DIR}/${SCRIPT_NAME}" +PID_FILE="/var/run/ledswitch_monitor.pid" +LOG_FILE="/var/log/ledswitch_monitor.log" + +# Logging function +log_info() { + echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a ${LOG_FILE} +} + +log_error() { + echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a ${LOG_FILE} +} + +# Check if script exists +check_script() { + if [ ! -f "${SCRIPT_PATH}" ]; then + log_error "Script not found: ${SCRIPT_PATH}" + return 1 + fi + return 0 +} + +# Check if bcmcmd exists +check_bcmcmd() { + if ! command -v bcmcmd &> /dev/null; then + log_error "bcmcmd command not found" + return 1 + fi + return 0 +} + +# Start service (CPLD mode) +start_service() { + if check_script; then + # Check if already running + if [ -f "${PID_FILE}" ]; then + local pid=$(cat "${PID_FILE}") + if kill -0 "${pid}" 2>/dev/null; then + log_info "Service already running (PID: ${pid})" + return 0 + else + rm -f "${PID_FILE}" + fi + fi + + log_info "Starting LED switch monitoring service (CPLD mode)..." + nohup python3 "${SCRIPT_PATH}" start >> "${LOG_FILE}" 2>&1 & + local pid=$! + echo "${pid}" > "${PID_FILE}" + log_info "Service started (PID: ${pid})" + fi +} + +# Stop service (SDK mode) +stop_service() { + if [ -f "${PID_FILE}" ]; then + local pid=$(cat "${PID_FILE}") + if kill -0 "${pid}" 2>/dev/null; then + log_info "Stopping LED switch monitoring service (PID: ${pid})..." + kill -TERM "${pid}" + sleep 2 + if kill -0 "${pid}" 2>/dev/null; then + log_error "Service did not stop gracefully, force killing..." + kill -9 "${pid}" + fi + rm -f "${PID_FILE}" + log_info "Service stopped" + else + log_info "Service not running" + rm -f "${PID_FILE}" + fi + else + # Try to find by process name + local pid=$(pgrep -f "${SCRIPT_NAME}") + if [ -n "${pid}" ]; then + log_info "Found running service (PID: ${pid}), stopping..." + kill -TERM ${pid} + rm -f "${PID_FILE}" + log_info "Service stopped" + else + log_info "Service not running" + fi + fi +} + +# Check service status (returns 0 if running, 1 if not) +is_service_running() { + if [ -f "${PID_FILE}" ]; then + local pid=$(cat "${PID_FILE}") + if kill -0 "${pid}" 2>/dev/null; then + return 0 + else + rm -f "${PID_FILE}" + return 1 + fi + else + local pid=$(pgrep -f "${SCRIPT_NAME}") + if [ -n "${pid}" ]; then + echo "${pid}" > "${PID_FILE}" + return 0 + else + return 1 + fi + fi +} + +# Set CPLD mode (use Python monitoring service) +set_cpld_mode() { + log_info "Setting LED mode to CPLD..." + + # Stop SDK mode first (stop bcmcmd led) + if check_bcmcmd; then + log_info "Stopping bcmcmd led..." + bcmcmd "led stop" 2>/dev/null + if [ $? -eq 0 ]; then + log_info "bcmcmd led stop executed successfully" + else + log_error "Failed to execute bcmcmd led stop" + fi + fi + + # Start Python monitoring service + start_service + + log_info "LED mode switched to CPLD" +} + +# Set SDK mode (use bcmcmd led control) +set_sdk_mode() { + log_info "Setting LED mode to SDK..." + + # Stop Python monitoring service first + stop_service + + # Start bcmcmd led + if check_bcmcmd; then + log_info "Starting bcmcmd led..." + bcmcmd "led start" 2>/dev/null + if [ $? -eq 0 ]; then + log_info "bcmcmd led start executed successfully" + else + log_error "Failed to execute bcmcmd led start" + fi + fi + + log_info "LED mode switched to SDK" +} + +# Show current LED status +show_led_status() { + echo "" + echo "==========================================" + echo " LED Switch Status" + echo "==========================================" + + if is_service_running; then + echo " Current Mode: CPLD" + local pid=$(cat "${PID_FILE}" 2>/dev/null) + if [ -n "${pid}" ]; then + echo " PID: ${pid}" + fi + else + echo " Current Mode: SDK" + fi + + echo "==========================================" + echo "" +} + +# Show help information +show_help() { + cat << EOF +=========================================== + LED Switch Control Script +=========================================== + +USAGE: + ledswitch.sh -l Show current LED status + ledswitch.sh -s {sdk|cpld} Set LED mode (sdk or cpld) + ledswitch.sh -h Show this help message + +DESCRIPTION: + This script controls the LED switch monitoring service. + + - CPLD mode: Uses Python monitoring service to control LEDs based on + port status and breakout mode configuration. + + - SDK mode: Uses bcmcmd "led start/stop" commands to let the SDK + handle LED control directly. + +EXAMPLES: + ledswitch.sh -l # Display current mode (CPLD or SDK) + ledswitch.sh -s cpld # Switch to CPLD mode + ledswitch.sh -s sdk # Switch to SDK mode + ledswitch.sh -h # Display this help + +LOG FILE: + /var/log/ledswitch_monitor.log + +=========================================== +EOF +} + +# Main function +main() { + # Parse command line arguments + while getopts "ls:h" opt; do + case ${opt} in + l) + show_led_status + exit 0 + ;; + s) + MODE="$OPTARG" + case "${MODE}" in + sdk) + set_sdk_mode + ;; + cpld) + set_cpld_mode + ;; + *) + echo "Error: Invalid mode '$MODE'" + echo "Usage: ledswitch.sh -s {sdk|cpld}" + exit 1 + ;; + esac + exit 0 + ;; + h) + show_help + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + show_help + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac + done + + # If no arguments provided, show help + if [ $OPTIND -eq 1 ]; then + show_help + exit 0 + fi +} + +# Run main function +main "$@" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py index 23b39d3731..245f49c5f7 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py @@ -249,6 +249,23 @@ def slotsmonitor(self): val_t = getattr(DevMonitor, slotsattr, None) devdebuglog("slotsattr:value:%s" % (val_t)) return ret + + def binddevsmonitor(self): + binddevs_conf = DEV_MONITOR_PARAM.get('binddevs') + if binddevs_conf is None: + return 0 + binddevsattr = 'binddevsattr' + val_t = getattr(DevMonitor, binddevsattr, None) + if val_t == 'OK': + return 0 + ret = self.monitor(binddevs_conf) + if ret == 0: + setattr(DevMonitor, binddevsattr, 'OK') + else: + setattr(DevMonitor, binddevsattr, 'NOT OK') + val_t = getattr(DevMonitor, binddevsattr, None) + devdebuglog("binddevsattr:value:%s" % (val_t)) + return ret def othersmonitor(self): others_conf = DEV_MONITOR_PARAM.get('others') @@ -274,6 +291,7 @@ def doDevMonitor(devMonitor): ret_t += devMonitor.fansmonitor() ret_t += devMonitor.slotsmonitor() ret_t += devMonitor.othersmonitor() + ret_t += devMonitor.binddevsmonitor() return ret_t diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py index a7bfa03942..4c48c1cf2e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py @@ -199,6 +199,7 @@ def __init__(self): self.__config = baseutil.get_monitor_config() self.__pid_config = self.__config["pid"] self.__hyst_config = self.__config.get("hyst", {}) + self.__openloop_config = self.__config["openloop"] self.__temps_threshold_config = self.__config["temps_threshold"] for temp_threshold in self.__temps_threshold_config.values(): temp_threshold['temp'] = 0 @@ -256,6 +257,7 @@ def __init__(self): self.__temp_emergency_countdown = self.__fancontrol_para.get("temp_emergency_countdown", 60) self.__rotor_error_count = self.__fancontrol_para.get("rotor_error_count", 6) self.__inlet_mac_diff = self.__fancontrol_para.get("inlet_mac_diff", 50) + self.__inlet_mac_diff_flag = self.__fancontrol_para.get("check_inlet_mac_diff", 1) self.__check_crit_reboot_flag = self.__fancontrol_para.get("check_crit_reboot_flag", 1) self.__check_emerg_reboot_flag = self.__fancontrol_para.get("check_emerg_reboot_flag", 1) self.__check_crit_reboot_num = self.__fancontrol_para.get("check_crit_reboot_num", 3) @@ -840,9 +842,10 @@ def abnormal_check(self): pwm_list.append(psu_absent_pwm) fancontrol_debug("psu_absent_pwm = 0x%x" % psu_absent_pwm) - dev_err_pwm = self.checkDevError() - pwm_list.append(dev_err_pwm) - fancontrol_debug("dev_err_pwm = 0x%x" % dev_err_pwm) + if self.__inlet_mac_diff_flag == 1: + dev_err_pwm = self.checkDevError() + pwm_list.append(dev_err_pwm) + fancontrol_debug("dev_err_pwm = 0x%x" % dev_err_pwm) temp_fail_pwm = self.checktempfail() pwm_list.append(temp_fail_pwm) @@ -1018,19 +1021,30 @@ def do_fancontrol(self): # get_monitor_temp self.get_monitor_temp() fancontrol_debug("last_pwm = 0x%x" % self.__pwm) - # openloop - inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] - linear_value = self.openloop.linear_cacl(inlettemp) - if linear_value is None: - linear_value = self.__min_pwm - pwm_list.append(linear_value) - fancontrol_debug("linear_value = 0x%x" % linear_value) - - curve_value = self.openloop.curve_cacl(inlettemp) - if curve_value is None: - curve_value = self.__min_pwm - pwm_list.append(curve_value) - fancontrol_debug("curve_value = 0x%x" % curve_value) + # openloop linear + linear_flag = self.__openloop_config.get("linear", {}).get("flag", 0) + if linear_flag == 0: + fancontrol_debug("openloop linear flag is 0, do nothing") + else: + inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] + linear_value = self.openloop.linear_cacl(inlettemp) + if linear_value is None: + linear_value = self.__min_pwm + pwm_list.append(linear_value) + fancontrol_debug("linear_value = 0x%x" % linear_value) + + # openloop curve + curve_flag = self.__openloop_config.get("curve", {}).get("flag", 0) + if curve_flag == 0: + fancontrol_debug("openloop curve flag is 0, do nothing") + + else: + inlettemp = self.__temps_threshold_config.get(INLET_TEMP)['temp'] + curve_value = self.openloop.curve_cacl(inlettemp) + if curve_value is None: + curve_value = self.__min_pwm + pwm_list.append(curve_value) + fancontrol_debug("curve_value = 0x%x" % curve_value) # hyst for hyst_index in self.__hyst_config.values(): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/mgmt_ledctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/mgmt_ledctrl.py new file mode 100644 index 0000000000..26a8c6c4f6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/mgmt_ledctrl.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import os +import logging +import time + +from platform_util import get_value, set_value, setup_logger, BSP_COMMON_LOG_DIR +from platform_config import MGMT_LED_CONFIG + +DEBUG_FILE = "/etc/.mgmt_ledcontrol_debug_flag" +LOG_FILE = BSP_COMMON_LOG_DIR + "mgmt_ledctrl_debug.log" +logger = setup_logger(LOG_FILE) + + +class PortConfig(object): + def __init__(self, name, link_path, led_path): + self.name = name + self.link_path = link_path + self.led_path = led_path + + +def debug_init(): + if os.path.exists(DEBUG_FILE): + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.INFO) + + +def mgmt_led_debug(msg): + logger.debug(msg) + + +def mgmt_led_error(msg): + logger.error(msg) + + +def read_link_status(path): + config = { + "gettype": "sysfs", + "loc": path, + "int_decode": 16, + } + ret, value = get_value(config) + if ret is not True: + raise RuntimeError("read link status failed, path:{}, msg:{}".format(path, value)) + if value not in (0, 1): + raise ValueError("unsupported link_status value:{} path:{}".format(value, path)) + mgmt_led_debug("read link status path:{} value:{}".format(path, value)) + return value + + +def write_led_status(path, value): + config = { + "gettype": "sysfs", + "loc": path, + "value": int(value), + "mask": 0, + } + ret, msg = set_value(config) + mgmt_led_debug("write led status path:{} value:{} ret:{} msg:{}".format(path, value, ret, msg)) + return ret, msg + + +def load_runtime_config_from_product(): + if MGMT_LED_CONFIG is None or not isinstance(MGMT_LED_CONFIG, dict): + raise ValueError("MGMT_LED_CONFIG error: %s" % MGMT_LED_CONFIG) + + interval = float(MGMT_LED_CONFIG.get("interval", 3)) + if interval <= 0: + raise ValueError("MGMT_LED_CONFIG.interval must be > 0") + + led_list = MGMT_LED_CONFIG.get("mgmt_led_list", []) + if not isinstance(led_list, list) or len(led_list) == 0: + raise ValueError("MGMT_LED_CONFIG.mgmt_led_list must be non-empty list") + + ports = [] + for idx, item in enumerate(led_list): + if not isinstance(item, dict): + raise ValueError("MGMT_LED_CONFIG.mgmt_led_list[{}] must be dict".format(idx)) + + name = item.get("name", "mgmt_led_{}".format(idx)) + link_path = item.get("link_path") + led_path = item.get("led_path") + + if not link_path: + raise ValueError("MGMT_LED_CONFIG.mgmt_led_list[{}].link_path is required".format(idx)) + if not led_path: + raise ValueError("MGMT_LED_CONFIG.mgmt_led_list[{}].led_path is required".format(idx)) + + ports.append(PortConfig(name, link_path, led_path)) + + mgmt_led_debug("load MGMT_LED_CONFIG success interval:{} port_num:{}".format(interval, len(ports))) + return ports, interval + + +def monitor_once(port): + link_status = read_link_status(port.link_path) + if link_status == 1: + led_status = 1 + else: + led_status = 0 + ret, msg = write_led_status(port.led_path, led_status) + if ret is not True: + raise RuntimeError("set led failed, path={}, value={}, msg={}" + .format(port.led_path, led_status, msg)) + mgmt_led_debug("monitor {} done link:{} led:{}".format(port.name, link_status, led_status)) + + +def main(): + debug_init() + ports, interval = load_runtime_config_from_product() + + while True: + debug_init() + for port in ports: + try: + monitor_once(port) + except Exception as exc: + mgmt_led_error("[{}] monitor error: {}".format(port.name, str(exc))) + time.sleep(interval) + + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py index 025a22ce82..5e456fda83 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py @@ -42,6 +42,7 @@ "INIT_PARAM", "INIT_COMMAND", "SET_MAC_CONF", + "MGMT_LED_CONFIG", "DRVIER_UPDATE_CONF", "MONITOR_TEMP_MIN", "MONITOR_K", @@ -152,6 +153,9 @@ # Set eth mac address parameters SET_MAC_CONF = [] +# mgmt led config parameters +MGMT_LED_CONFIG = [] + # driver update config DRVIER_UPDATE_CONF = {} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py index 762f33dfbc..68a4645db5 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py @@ -47,6 +47,7 @@ "GLOBALINITPARAM_PRE", "GLOBALINITCOMMAND_PRE", "SET_MAC_CONF", + "MGMT_LED_CONFIG", "DRVIER_UPDATE_CONF", "MONITOR_CONST", "PSU_FAN_FOLLOW", @@ -156,6 +157,9 @@ def getdeviceplatform(): # Set eth mac address parameters SET_MAC_CONF = module_product.SET_MAC_CONF +# mgmt led config parameters +MGMT_LED_CONFIG = module_product.MGMT_LED_CONFIG + # driver update config DRVIER_UPDATE_CONF = module_product.DRVIER_UPDATE_CONF diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py index 290e3a93a3..203b2def3d 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py @@ -18,12 +18,23 @@ import os import subprocess import time +import sys import click from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG, FW_UPGRADE_STARTED_FLAG +from platform_util import set_value +from platform_util import setup_logger, BSP_COMMON_LOG_DIR +# Constants +LOG_WRITE_SIZE = 1 * 1024 * 1024 # 1 MB +LOG_FILE = BSP_COMMON_LOG_DIR + "platform_driver_debug.log" +logger = setup_logger(LOG_FILE, LOG_WRITE_SIZE) -CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} +def log_message(message): + logger.info(message) + +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} +PLATFORM_I2C_RETRY_TIME = 3 class AliasedGroup(click.Group): def get_command(self, ctx, cmd_name): @@ -142,12 +153,47 @@ def checksignaldriver(name): return False -def adddriver(name, delay): - cmd = "modprobe %s" % name - if delay != 0: +def process_init_commands(init): + if init is not None: + if isinstance(init, list): + for init_cmd in init: + ret, log = set_value(init_cmd) + if ret is True: + click.echo("%%PLATFORM_DRIVER: init success, cmd: %s" % init_cmd) + else: + click.echo("%%PLATFORM_DRIVER: init failed, cmd: %s, msg: %s" % (init_cmd, str(log))) + return + else: + click.echo("%%PLATFORM_DRIVER: init must be list (type is %s)" % type(init).__name__) + return + +def adddriver(name, delay, init=None): + realname = name.lstrip().split(" ")[0] + if delay > 0: time.sleep(delay) - if checksignaldriver(name) is not True: - log_os_system(cmd) + + ret = checksignaldriver(realname) + if ret is True: + log_message("%%PLATFORM_DRIVER: WARN: %s driver already loaded, skip to modprobe" % realname) + return + + cmd = "modprobe %s" % name + log_message("%%PLATFORM_DRIVER: adddriver cmd: %s, delay: %s" % (cmd, delay)) + retrytime = PLATFORM_I2C_RETRY_TIME + for i in range(retrytime): + process_init_commands(init) + status, log = log_os_system(cmd) + if status == 0: + ret = checksignaldriver(realname) + if ret is True: + log_message("%%PLATFORM_DRIVER: add driver %s success" % realname) + return + log_message("%%PLATFORM_DRIVER: run %s success, but driver %s not load, retry: %d" % (cmd, realname, i)) + else: + log_message("%%PLATFORM_DRIVER: run %s error, status: %s, msg: %s, retry: %d" % (cmd, status, log, i)) + time.sleep(0.1) + log_message("%%PLATFORM_DRIVER: load %s driver failed, exit!" % realname) + sys.exit(1) def removedriver(name, delay, removeable=1): @@ -181,21 +227,23 @@ def removedrivers(): def adddrivers(): if GLOBALCONFIG is None: - click.echo("%%WB_PLATFORM_DRIVER-INIT: load global config failed.") + click.echo("%%PLATFORM_DRIVER-INIT: load global config failed.") return drivers = GLOBALCONFIG.get("DRIVERLISTS", None) if drivers is None: - click.echo("%%WB_PLATFORM_DRIVER-INIT: load driver list failed.") + click.echo("%%PLATFORM_DRIVER-INIT: load driver list failed.") return for driver in drivers: delay = 0 name = "" + init = None if isinstance(driver, dict) and "delay" in driver: - name = driver.get("name") + name = driver.get("name", "") delay = driver["delay"] + init = driver.get("init", None) else: name = driver - adddriver(name, delay) + adddriver(name, delay, init) def blacklist_driver_remove(): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py index 3c76dd447a..d782b57b0f 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py @@ -175,6 +175,13 @@ def startSff_polling(): rets = getPid("sff_polling.py") if len(rets) == 0: log_os_system(cmd) + +def startMgmt_ledctrl(): + if STARTMODULE.get('mgmt_ledctrl', 0) == 1: + cmd = "nohup mgmt_ledctrl.py start > /dev/null 2>&1 &" + rets = getPid("mgmt_ledctrl.py") + if len(rets) == 0: + log_os_system(cmd) def generate_air_flow(): @@ -307,6 +314,12 @@ def stopSff_polling(): cmd = "kill " + ret log_os_system(cmd) +def stopMgmt_ledctrl(): + if STARTMODULE.get('mgmt_ledctrl', 0) == 1: + rets = getPid("mgmt_ledctrl.py") + for ret in rets: + cmd = "kill " + ret + log_os_system(cmd) def stopGenerate_air_flow(): if STARTMODULE.get('generate_airflow', 0) == 1: @@ -342,6 +355,7 @@ def otherinit_pre(): def unload_apps(): stopSff_polling() + stopMgmt_ledctrl() stopPMON_sys() stopSignalmonitor() stopIntelligentmonitor() @@ -396,6 +410,7 @@ def load_apps(): startSignalmonitor() startPMON_sys() startSff_polling() + startMgmt_ledctrl() otherinit() if STARTMODULE.get("macledreset", 0) == 1: MacLedSet("reset") diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py index 7e505b59ab..c41b7ecb0b 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py @@ -232,11 +232,11 @@ def print_boarddcdc(self): monitor_one_sensor_dict = OrderedDict() monitor_one_sensor_dict['id'] = sensor_key try: - monitor_one_sensor_dict['dcdc_input'] = float(sensor_info["Value"]) / 1000 + monitor_one_sensor_dict['dcdc_input'] = float(sensor_info["Value"]) monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] - monitor_one_sensor_dict['dcdc_min'] = float(sensor_info["Min"]) / 1000 + monitor_one_sensor_dict['dcdc_min'] = float(sensor_info["Min"]) monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] - monitor_one_sensor_dict['dcdc_max'] = float(sensor_info["Max"]) / 1000 + monitor_one_sensor_dict['dcdc_max'] = float(sensor_info["Max"]) monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] monitor_one_sensor_dict["status"] = sensor_info["Status"] except Exception: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py index 2187b391a2..9df7bf3270 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py @@ -27,10 +27,12 @@ import shutil import gzip import ast - +from typing import Tuple CONFIG_DB_PATH = "/etc/sonic/config_db.json" MAILBOX_DIR = "/sys/bus/i2c/devices/" +# bsp common log dir +BSP_COMMON_LOG_DIR = "/var/log/bsp_tech/" __all__ = [ @@ -62,7 +64,9 @@ "getSdkReg", "getMacTemp", "getMacTemp_sysfs", - "get_format_value" + "get_format_value", + "BSP_COMMON_LOG_DIR", + "setup_logger" ] class CodeVisitor(ast.NodeVisitor): @@ -258,6 +262,91 @@ def getplatform_name(): return getplatform_config_db() +def set_file_and_dir_permissions_if_root( + file_path: str, + dir_mode: int = 0o777, + file_mode: int = 0o666 +) -> Tuple[bool, str]: + """ + (Updated docstring) If the current user is root, atomically set permissions for the parent directory of the specified file (to `dir_mode`) + and the file itself (to `file_mode`). The operation is atomic: either both permissions are set successfully, or no changes are made. + + Parameters: + file_path (str): Absolute path to the file (e.g., /a/b/c.txt). + dir_mode (int): Permissions for the parent directory (default: 0o777, recommended for most directories). + file_mode (int): Permissions for the file (default: 0o666, recommended for most files). + + Returns: + Tuple[bool, str]: (True if successful, "Success") or (False if failed, detailed error message). + """ + # Check if the current user is root (only root can modify permissions of other users' files) + if os.geteuid() != 0: + return False, "Not running as root (requires root privileges)" + + # Check if the file path is absolute (relative paths may cause unexpected parent directory resolution) + if not os.path.isabs(file_path): + return False, "File path must be an absolute path (e.g., /a/b/c.txt)" + + # Check if the file exists (cannot set permissions for a non-existent file) + if not os.path.exists(file_path): + return False, f"File not found: {file_path} (verify the path is correct)" + + parent_dir = os.path.dirname(file_path) + + # Get the original permissions of the parent directory (to rollback if file permission setting fails) + try: + original_dir_stat = os.stat(parent_dir) + original_dir_mode = original_dir_stat.st_mode & 0o777 # Extract only the permission bits (ignore other flags) + except Exception as e: + return False, f"Failed to retrieve parent directory permissions: {str(e)}" + + # Attempt to set permissions for the parent directory + try: + os.chmod(parent_dir, dir_mode) + except Exception as e: + return False, f"Failed to set parent directory permissions: {str(e)}" + + # Attempt to set permissions for the file (rollback parent directory permissions if this fails) + try: + os.chmod(file_path, file_mode) + except Exception as e: + # Rollback: Restore the parent directory to its original permissions + try: + os.chmod(parent_dir, original_dir_mode) + except Exception as rollback_e: + return False, f"Failed to set file permissions (and rollback of parent directory permissions failed): {str(e)}; Rollback error: {str(rollback_e)}" + return False, f"Failed to set file permissions (parent directory permissions rolled back successfully): {str(e)}" + + return True, "Success" + +def setup_logger(log_file, max_bytes=1024*1024*5, backup_count=3, formatter_type="default"): + dir_path = os.path.dirname(log_file) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + # creat logger + logger = logging.getLogger(log_file) + if not logger.hasHandlers(): + logger.setLevel(logging.INFO) + + # creat RotatingFileHandler set log file size and backupCount + handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=max_bytes, backupCount=backup_count) + handler.setLevel(logging.DEBUG) + + # creat formatter and addd to handler + if formatter_type == "default": + formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s") + elif formatter_type == "simple": + formatter = logging.Formatter("%(message)s:%(asctime)s") + else: + formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s[%(funcName)s][%(lineno)s]: %(message)s") + handler.setFormatter(formatter) + + logger.addHandler(handler) + + set_file_and_dir_permissions_if_root(log_file) + + return logger + def wbi2cget(bus, devno, address, word=None): if word is None: command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address) @@ -893,3 +982,12 @@ def get_format_value(format_str): ret = visitor.get_value() return ret +def log_to_file(content, log_file_path, max_size=5*1024*1024): + try: + logger = setup_logger(log_file_path, max_size) + logger.info(content) + + except Exception as e: + return False, (str(e) + "log_file_path[%s]" % log_file_path) + return True, "log_to_file success" + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/saphy_script.sh b/platform/broadcom/sonic-platform-modules-micas/common/script/saphy_script.sh new file mode 100644 index 0000000000..1878655a68 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/saphy_script.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +start() { + BDIR="/usr/share/sonic/device" + CURDEV="$(cat /host/machine.conf | grep onie_platform)" + DB_CONF_FILE="/var/run/redis/sonic-db/database_config.json" + array=(${CURDEV//=/ }) + PLTF=${array[1]} + DEVDIR=${BDIR}"/"${PLTF} + def_sku=${DEVDIR}"/default_sku" + cur_sku=${DEVDIR}"/current_sku" + SKU="" + + if [ ! -e "/usr/local/bin/saphy" ]; then + echo "Error: /usr/local/bin/saphy not found" + exit 0 + fi + + echo "Waiting for $DB_CONF_FILE to be ready..." + WAIT_TIME=0 + MAX_WAIT=10 + while [ ! -f "$DB_CONF_FILE" ] && [ $WAIT_TIME -lt $MAX_WAIT ]; do + sleep 1 + WAIT_TIME=$((WAIT_TIME + 1)) + echo "Waiting... ${WAIT_TIME}s / ${MAX_WAIT}s" + done + + if [ -f "$DB_CONF_FILE" ]; then + echo "$DB_CONF_FILE found. Proceeding..." + else + echo "Warning: $DB_CONF_FILE not found after ${MAX_WAIT} seconds, continuing anyway..." + fi + + if type config-hwsku.sh >/dev/null 2>&1; then + SKU="" + RETRY_COUNT=0 + MAX_RETRIES=10 + + echo "Trying to get SKU via config-hwsku.sh -p..." + while [ -z "$SKU" ] && [ $RETRY_COUNT -lt $MAX_RETRIES ]; do + SKU="$(config-hwsku.sh -p 2>/dev/null | xargs)" + if [ -n "$SKU" ]; then + echo "config-hwsku.sh get sku: ${SKU}" + break + fi + RETRY_COUNT=$((RETRY_COUNT + 1)) + if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then + echo "Failed to get SKU (attempt ${RETRY_COUNT}/${MAX_RETRIES}), retrying in 1 second..." + sleep 1 + fi + done + + if [ -z "$SKU" ]; then + echo "Warning: Failed to get SKU via config-hwsku.sh after ${MAX_RETRIES} attempts" + fi + fi + + if [ -z "$SKU" ]; then + echo "Falling back to file-based SKU detection..." + if test -e "$cur_sku"; then + sku=${cur_sku} + echo "cur_sku: ${sku}" + elif test -e "$def_sku"; then + sku=${def_sku} + echo "def_sku: ${sku}" + else + echo "Error: sku file not found !!!" + exit 1 + fi + t="$(cat ${sku})" + array=(${t// / }) + SKU=${array[0]} + echo "Got SKU from file: ${SKU}" + fi + + if [ -z "$SKU" ]; then + echo "Error: Failed to get SKU from any source" + exit 1 + fi + + hwsku_dir="/usr/share/sonic/hwsku" + target_path="${BDIR}/${PLTF}/${SKU}" + + if [ ! -d "$target_path" ]; then + echo "Error: Target path not found: $target_path" + exit 1 + fi + + if [ -e "$hwsku_dir" ] || [ -L "$hwsku_dir" ]; then + echo "Removing existing $hwsku_dir" + rm -rf "$hwsku_dir" + fi + + echo "Creating symlink: $hwsku_dir -> $target_path" + ln -s "$target_path" "$hwsku_dir" + + if [ ! -L "$hwsku_dir" ]; then + echo "Error: Failed to create symlink" + exit 1 + fi + + platform_dir="/usr/share/sonic/platform" + target_platform_path="${BDIR}/${PLTF}" + + if [ -e "$platform_dir" ] || [ -L "$platform_dir" ]; then + echo "Removing existing $platform_dir" + rm -rf "$platform_dir" + fi + + ln -s "$target_platform_path" "$platform_dir" + + echo "Starting /usr/local/bin/saphy..." + sleep 1 + /usr/local/bin/saphy service +} + +wait() { + echo "wait /usr/local/bin/saphy..." +} + +stop() { + echo "Stopping /usr/local/bin/saphy..." + pkill -f "/usr/local/bin/saphy" 2>/dev/null + echo "Stopped /usr/local/bin/saphy..." + exit 0 +} + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py b/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py index 21e14b0488..24ef71002c 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py @@ -22,7 +22,7 @@ import subprocess import fcntl -sfp_temperature_file = "/tmp/highest_sff_temp" +sfp_temperature_file = "/etc/sonic/highest_sff_temp" SFP_TEMP_DEBUG_FILE = "/etc/.sfp_temp_debug_flag" SFP_TEMP_RECORD_DEBUG = 1 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/service/saphy.service b/platform/broadcom/sonic-platform-modules-micas/common/service/saphy.service new file mode 100644 index 0000000000..d80dd3d860 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/service/saphy.service @@ -0,0 +1,15 @@ +[Unit] +Description=saphy service +After=platform_driver.service +Requires=platform_driver.service + +[Service] +ExecStart=/usr/local/bin/saphy_script.sh start +ExecStop=/usr/local/bin/saphy_script.sh stop +KillMode=process +Restart=on-failure +RestartSec=60s +SuccessExitStatus=TERM + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py index 8f07567207..a98a1c6de7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py @@ -27,7 +27,7 @@ # from sonic_platform.watchdog import Watchdog from sonic_platform.component import Component from sonic_platform.eeprom import Eeprom - from sonic_platform.dcdc import Dcdc + from sonic_platform.dcdc import Dcdc, VoltageSensor, CurrentSensor from plat_hal.baseutil import baseutil from plat_hal.interface import interface @@ -71,9 +71,16 @@ def __init__(self): if self.port_start_index == 1: self._sfp_list.append(Sfp(1)) + sfp_config = baseutil.get_config().get("sfps", {}) + logical_to_physical_sfp_map = sfp_config.get("logical_to_physical_sfp_map", {}) + # sfp id always start at 1 for index in range(1, self.port_num + 1): - self._sfp_list.append(Sfp(index)) + physical_index = logical_to_physical_sfp_map.get(index, logical_to_physical_sfp_map.get(str(index), index)) + if physical_index != index: + self._sfp_list.append(self._sfp_list[physical_index - 1]) + else: + self._sfp_list.append(Sfp(index)) for i in range(self.port_start_index, self.port_start_index + self.port_num): self.sfp_present_dict[i] = self.STATUS_REMOVED @@ -110,9 +117,23 @@ def __init__(self): self._component_list.append(componentobj) dcdc_num = self.int_case.get_dcdc_total_number() + vol_index = 1 + curr_index = 1 for index in range(dcdc_num): dcdcobj = Dcdc(self.int_case, index + 1) self._dcdc_list.append(dcdcobj) + dcdc_id = "DCDC" + str(index + 1) + dcdc_unit = self.int_case.get_dcdc_unit_by_id(dcdc_id) + + if dcdc_unit == "V" or dcdc_unit == "mV": + volobj = VoltageSensor(self.int_case, index + 1, vol_index) + self._voltage_sensor_list.append(volobj) + vol_index += 1 + + if dcdc_unit == "A" or dcdc_unit == "mA": + currobj = CurrentSensor(self.int_case, index + 1, curr_index) + self._current_sensor_list.append(currobj) + curr_index += 1 def get_name(self): """ @@ -247,6 +268,30 @@ def get_status_led(self): return color return 'N/A' + def set_uid_led(self, color): + """ + Sets the state of the system UID LED + + Args: + color: A string representing the color with which to set the + system UID LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + return False + + def get_uid_led(self): + """ + Gets the state of the system UID LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + return 'N/A' + + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -431,11 +476,23 @@ def get_change_event(self, timeout=0): try: while timeout >= 0: # check for sfp - sfp_change_dict = self.get_transceiver_change_event() + try: + sfp_change_dict = self.get_transceiver_change_event() + except Exception as e: + sfp_change_dict = {} + print("get_transceiver_change_event exception: %s" % e) # check for fan - fan_change_dict = self.get_fan_change_event() + try: + fan_change_dict = self.get_fan_change_event() + except Exception as e: + fan_change_dict = {} + print("get_fan_change_event exception: %s" % e) # check for voltage - voltage_change_dict = self.get_voltage_change_event() + try: + voltage_change_dict = self.get_voltage_change_event() + except Exception as e: + voltage_change_dict = {} + print("get_voltage_change_event exception: %s" % e) if sfp_change_dict or fan_change_dict or voltage_change_dict: change_event_dict["sfp"] = sfp_change_dict @@ -453,7 +510,7 @@ def get_change_event(self, timeout=0): time.sleep(timeout) return True, change_event_dict except Exception as e: - print(e) + print("get_change_event exception: %s" % e) print("get_change_event: Should not reach here.") return False, change_event_dict @@ -517,7 +574,13 @@ def get_voltage_change_event(self): value = dcdc.get_value() high = dcdc.get_high_threshold() low = dcdc.get_low_threshold() - if (value is None) or (value > high) or (value < low): + + # Hot-plug may temporarily return non-numeric values (e.g. "N/A"). Transfer potentially non-numeric values to None or float, and let the following logic to determine the status. + value_num = None if value is None else float(value) + high_num = None if high is None else float(high) + low_num = None if low is None else float(low) + + if (value_num is None) or ((high_num is not None) and (value_num > high_num)) or ((low_num is not None) and (value_num < low_num)): current_voltage_status_dict[name] = self.STATUS_ABNORMAL else: current_voltage_status_dict[name] = self.STATUS_NORMAL @@ -535,5 +598,3 @@ def get_voltage_change_event(self): ret_dict[name] = status self.voltage_status_dict = current_voltage_status_dict return ret_dict - - diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py index 920f4c2d3f..c67940fcd1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py @@ -16,9 +16,9 @@ # along with this program. If not, see . import time +from sonic_platform_base.sensor_base import SensorBase - -class Dcdc(object): +class Dcdc(SensorBase): def __init__(self, interface_obj, index): self.dcdc_dict = {} @@ -26,6 +26,12 @@ def __init__(self, interface_obj, index): self.index = index self.update_time = 0 self.dcdc_id = "DCDC" + str(index) + self.minimum = None + self.maximum = None + + @classmethod + def get_type(cls): + return "SENSOR_TYPE" def dcdc_dict_update(self): local_time = time.time() @@ -33,6 +39,76 @@ def dcdc_dict_update(self): self.update_time = local_time self.dcdc_dict = self.int_case.get_dcdc_by_id(self.dcdc_id) + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + return "N/A" + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + return "N/A" + + def get_revision(self): + """ + Retrieves the hardware revision of the device + + Returns: + string: Revision value of device + """ + return "N/A" + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + self.dcdc_dict_update() + if self.dcdc_dict["Max"] is not None and self.dcdc_dict["Value"] > self.dcdc_dict["Max"]: + return False + + if self.dcdc_dict["Min"] is not None and self.dcdc_dict["Value"] < self.dcdc_dict["Min"]: + return False + + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + def get_name(self): """ Retrieves the name of the sensor @@ -43,15 +119,31 @@ def get_name(self): self.dcdc_dict_update() return self.dcdc_dict["Name"] + def get_unit(self): + """ + Retrieves unit of measurement reported by sensor + + Returns: + Sensor measurement unit + """ + return self.int_case.get_dcdc_unit_by_id(self.dcdc_id) + def get_value(self): """ Retrieves current value reading from sensor """ self.dcdc_dict_update() - value = self.dcdc_dict["Value"] - if value is None: - value = 0 - return round(float(value), 3) + tmp_value = self.dcdc_dict["Value"] + if tmp_value is None or tmp_value == self.int_case.error_ret: + return "N/A" + value = round(float(tmp_value), 3) + if self.minimum is None or value < self.minimum: + self.minimum = value + + if self.maximum is None or value > self.maximum: + self.maximum = value + + return value def get_high_threshold(self): """ @@ -59,8 +151,8 @@ def get_high_threshold(self): """ self.dcdc_dict_update() value = self.dcdc_dict["High"] - if value is None: - value = 0 + if value is None or value == self.int_case.error_ret: + return self.get_high_critical_threshold() return round(float(value), 3) def get_low_threshold(self): @@ -69,18 +161,43 @@ def get_low_threshold(self): """ self.dcdc_dict_update() value = self.dcdc_dict["Low"] - if value is None: - value = 0 + if value is None or value == self.int_case.error_ret: + return self.get_low_critical_threshold() return round(float(value), 3) + def set_high_threshold(self, value): + """ + Sets the high threshold value of sensor + + Args: + value: High threshold value to set + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def set_low_threshold(self, value): + """ + Sets the low threshold value of sensor + + Args: + value: Value + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def get_high_critical_threshold(self): """ Retrieves the high critical threshold temperature of sensor """ self.dcdc_dict_update() value = self.dcdc_dict["Max"] - if value is None: - value = 0 + if value is None or value == self.int_case.error_ret: + return "N/A" return round(float(value), 3) def get_low_critical_threshold(self): @@ -89,6 +206,92 @@ def get_low_critical_threshold(self): """ self.dcdc_dict_update() value = self.dcdc_dict["Min"] - if value is None: - value = 0 + if value is None or value == self.int_case.error_ret: + return "N/A" return round(float(value), 3) + + def set_high_critical_threshold(self, value): + """ + Sets the critical high threshold value of sensor + + Args: + value: Critical high threshold Value + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def set_low_critical_threshold(self, value): + """ + Sets the critical low threshold value of sensor + + Args: + value: Critial low threshold Value + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def get_minimum_recorded(self): + """ + Retrieves the minimum recorded value of sensor + + Returns: + The minimum recorded value of sensor + """ + if self.minimum is None: + self.get_value() + if self.minimum is None: + return "N/A" + return self.minimum + + def get_maximum_recorded(self): + """ + Retrieves the maximum recorded value of sensor + + Returns: + The maximum recorded value of sensor + """ + if self.maximum is None: + self.get_value() + if self.maximum is None: + return "N/A" + return self.maximum + +class VoltageSensor(Dcdc): + def __init__(self, interface_obj, dcdc_index, vol_index): + super(VoltageSensor, self).__init__(interface_obj, dcdc_index) + self.index = vol_index + + @classmethod + def get_type(cls): + return "SENSOR_TYPE_VOLTAGE" + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return self.index + +class CurrentSensor(Dcdc): + def __init__(self, interface_obj, dcdc_index, curr_index): + super(CurrentSensor, self).__init__(interface_obj, dcdc_index) + self.index = curr_index + + @classmethod + def get_type(cls): + return "SENSOR_TYPE_CURRENT" + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return self.index diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py index 847a921538..70cb92eb5b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py @@ -104,6 +104,9 @@ def get_eeprom_path(self): def read_eeprom(self, offset, num_bytes): return self._sfp_api.read_eeprom(offset, num_bytes) + def write_eeprom(self, offset, num_bytes, write_buffer): + return self._sfp_api.write_eeprom(offset, num_bytes, write_buffer) + def set_power_class(self): try: if self.sfp_type is None: @@ -122,9 +125,6 @@ def set_power_class(self): except Exception as e: print(traceback.format_exc()) - def write_eeprom(self, offset, num_bytes, write_buffer): - return self._sfp_api.write_eeprom(offset, num_bytes, write_buffer) - def get_presence(self): presence = self._sfp_api.get_presence() if (presence == True) and (self.presence != True): @@ -679,35 +679,44 @@ def _get_sfp_cpld_info(self, cpld_config): class SfpV2(SfpCust): def _init_config(self, index): super()._init_config(index) - # init eeprom path sfp_config = baseutil.get_config().get("sfps", None) - eeprom_path_config = sfp_config.get("eeprom_path", None) - eeprom_path_key = sfp_config.get("eeprom_path_key")[self._port_id - 1] - self.eeprom_path = None if eeprom_path_config is None else eeprom_path_config % ( - eeprom_path_key, eeprom_path_key) - self._sfplog(LOG_DEBUG_LEVEL, "Done init eeprom path: %s" % self.eeprom_path) + self.bp_port_list = self._convert_str_range_to_int_arr(sfp_config.get("bp_port_list", None)) + # init eeprom path + # "/sys/s3ip/transceiver/eth%d/eeprom" + path_config = sfp_config.get("eeprom_path", None) + if path_config is not None and self._port_id not in self.bp_port_list: + self.eeprom_path = path_config % (self._port_id) + else: + self.eeprom_path = None + self._sfplog(LOG_DEBUG_LEVEL, "Done init port %d eeprom path: %s" % (self._port_id, self.eeprom_path)) # init presence path - self.presence_path = None if sfp_config.get("presence_path", - None) is None else sfp_config.get("presence_path") % self._port_id + # /sys/s3ip/transceiver/eth%d/present + path_config = sfp_config.get("presence_path", None) + if path_config is not None and self._port_id not in self.bp_port_list: + self.presence_path = path_config % (self._port_id) + else: + self.presence_path = None self.presence_val_is_present = sfp_config.get("presence_val_is_present", 0) - self._sfplog(LOG_DEBUG_LEVEL, "Done init presence path: %s" % self.presence_path) + self._sfplog(LOG_DEBUG_LEVEL, "Done init port %d presence path: %s" % (self._port_id, self.presence_path)) # init optoe driver path optoe_driver_path = sfp_config.get("optoe_driver_path", None) - optoe_driver_key = sfp_config.get("optoe_driver_key")[self._port_id - 1] - self.dev_class_path = None if optoe_driver_path is None else optoe_driver_path % ( - optoe_driver_key, optoe_driver_key) - self._sfplog(LOG_DEBUG_LEVEL, "Done init optoe driver path: %s" % self.dev_class_path) + if optoe_driver_path is not None and self._port_id not in self.bp_port_list: + optoe_driver_key = sfp_config.get("optoe_driver_key")[self._port_id - 1] + self.dev_class_path = None if optoe_driver_path is None else optoe_driver_path % ( + optoe_driver_key, optoe_driver_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init port %d optoe driver path: %s" % (self._port_id, self.dev_class_path)) # init reset path - self.reset_path = None if sfp_config.get( - "reset_path", - None) is None else sfp_config.get( - "reset_path", - None) % self._port_id + # /sys/s3ip/transceiver/eth%d/present + path_config = sfp_config.get("reset_path", None) + if path_config is not None and self._port_id not in self.bp_port_list: + self.reset_path = path_config % (self._port_id) + else: + self.reset_path = None self.reset_val_is_reset = sfp_config.get("reset_val_is_reset", 0) - self._sfplog(LOG_DEBUG_LEVEL, "Done init reset path: %s" % self.reset_path) + self._sfplog(LOG_DEBUG_LEVEL, "Done init port %d reset path: %s" % (self._port_id, self.reset_path)) def get_presence(self): if self.presence_path is None: @@ -934,4 +943,4 @@ def _file_rw_unlock(self): return True except Exception as e: self._sfplog(LOG_ERROR_LEVEL, "file unlock err, msg:%s" % (str(e))) - return False + return False \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/control b/platform/broadcom/sonic-platform-modules-micas/debian/control index e272778df0..366df05c21 100644 --- a/platform/broadcom/sonic-platform-modules-micas/debian/control +++ b/platform/broadcom/sonic-platform-modules-micas/debian/control @@ -38,4 +38,12 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-micas-m2-w6520-48c8qc Architecture: amd64 -Description: kernel modules for platform devices such as fan, led, sfp \ No newline at end of file +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-micas-m2-w6950-128oc +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-micas-m2-w6951-64hc-cp +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.install b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.install new file mode 100644 index 0000000000..721c8ac7f3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.install @@ -0,0 +1 @@ +m2-w6950-128oc/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-micas_m2-w6950-128oc-r0 diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.postinst b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.postinst new file mode 100644 index 0000000000..a8132f4f65 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6950-128oc.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.install b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.install new file mode 100644 index 0000000000..0d6afaedf9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.install @@ -0,0 +1 @@ +m2-w6951-64hc-cp/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-micas_m2-w6951-64hc-cp-r0 diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.postinst b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.postinst new file mode 100644 index 0000000000..a8132f4f65 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6951-64hc-cp.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk b/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk index fbcd72290a..38ae2f88e3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk +++ b/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk @@ -9,6 +9,7 @@ MODULE_DIRS += m2-w6940-64oc MODULE_DIRS += m2-w6920-32qc2x MODULE_DIRS += m2-w6510-32c MODULE_DIRS += m2-w6520-48c8qc - +MODULE_DIRS += m2-w6950-128oc +MODULE_DIRS += m2-w6951-64hc-cp export MODULE_DIRS diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/Makefile index 8c39927af7..5bc3d1ef5f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/Makefile @@ -1,7 +1,9 @@ MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +BSP_PUBLIC_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/public/include) EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(BSP_PUBLIC_PATH) obj-m += wb_pcie_dev_device.o obj-m += wb_io_dev_device.o diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_indirect_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_indirect_dev_device.c index 82b692e414..3f0af72ba6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_indirect_dev_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6940-64oc/modules/driver/wb_indirect_dev_device.c @@ -50,13 +50,10 @@ static indirect_dev_device_t indirect_dev_device_data0 = { .dev_name = "cpld2", .logic_dev_name = "/dev/cpld1", .data_bus_width = 4, - .addr_bus_width = 1, .wr_data = 0x70, - .wr_data_width = 4, .addr_low = 0x74, .addr_high = 0x75, .rd_data = 0x76, - .rd_data_width = 4, .opt_ctl = 0x7a, .indirect_len = 0x230, }; @@ -67,13 +64,10 @@ static indirect_dev_device_t indirect_dev_device_data1 = { .dev_name = "cpld3", .logic_dev_name = "/dev/cpld1", .data_bus_width = 4, - .addr_bus_width = 1, .wr_data = 0x80, - .wr_data_width = 4, .addr_low = 0x84, .addr_high = 0x85, .rd_data = 0x86, - .rd_data_width = 4, .opt_ctl = 0x8a, .indirect_len = 0x230, }; @@ -84,13 +78,10 @@ static indirect_dev_device_t indirect_dev_device_data2 = { .dev_name = "cpld4", .logic_dev_name = "/dev/cpld1", .data_bus_width = 4, - .addr_bus_width = 1, .wr_data = 0x90, - .wr_data_width = 4, .addr_low = 0x94, .addr_high = 0x95, .rd_data = 0x96, - .rd_data_width = 4, .opt_ctl = 0x9a, .indirect_len = 0x230, }; @@ -101,13 +92,10 @@ static indirect_dev_device_t indirect_dev_device_data3 = { .dev_name = "cpld5", .logic_dev_name = "/dev/cpld1", .data_bus_width = 4, - .addr_bus_width = 1, .wr_data = 0xa0, - .wr_data_width = 4, .addr_low = 0xa4, .addr_high = 0xa5, .rd_data = 0xa6, - .rd_data_width = 4, .opt_ctl = 0xaa, .indirect_len = 0x230, }; diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/Makefile new file mode 100644 index 0000000000..6114c2aa22 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/Makefile @@ -0,0 +1,34 @@ +PWD = $(shell pwd) +DIR_KERNEL_SRC = $(PWD)/modules/driver +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +SUB_BUILD_DIR = $(PWD)/build +INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) +INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_UPGRADE_TEST_DIR = $(SUB_BUILD_DIR)/etc/.upgrade_test +INSTALL_CPLD_REFRESH_DIR = $(SUB_BUILD_DIR)/etc/.cpld_refresh +INSTALL_S3IP_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/s3ip_sysfs_cfg +INSTALL_S3IP_CONFIG_DIR = $(SUB_BUILD_DIR)/etc/s3ip + +all: + $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules + @if [ ! -d ${INSTALL_DIR} ]; then mkdir -p ${INSTALL_DIR} ;fi + cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) + @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi + cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_UPGRADE_TEST_DIR} ]; then mkdir -p ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ -d $(PWD)/.upgrade_test/ ]; then cp -r $(PWD)/.upgrade_test/* ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ ! -d ${INSTALL_CPLD_REFRESH_DIR} ]; then mkdir -p ${INSTALL_CPLD_REFRESH_DIR} ;fi + @if [ -d $(PWD)/.cpld_refresh/ ]; then cp -r $(PWD)/.cpld_refresh/* ${INSTALL_CPLD_REFRESH_DIR} ;fi + @if [ ! -d ${INSTALL_S3IP_CONFIG_DIR} ]; then mkdir -p ${INSTALL_S3IP_CONFIG_DIR} ;fi + @if [ -d $(PWD)/s3ip_config/ ]; then cp -r $(PWD)/s3ip_config/* ${INSTALL_S3IP_CONFIG_DIR} ;fi + @if [ ! -d ${INSTALL_S3IP_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_S3IP_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/s3ip_sysfs_cfg/ ]; then cp -r $(PWD)/s3ip_sysfs_cfg/* ${INSTALL_S3IP_SYSFS_CFG_DIR} ;fi +clean: + rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd ${DIR_KERNEL_SRC}/*.mod + rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order + rm -rf ${DIR_KERNEL_SRC}/.tmp_versions + rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_config.py new file mode 100644 index 0000000000..e749c1e224 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_config.py @@ -0,0 +1,2271 @@ +#!/usr/bin/env python_nos +# -*- coding: UTF-8 -*- +from platform_common import * + +STARTMODULE = { + "hal_fanctrl": 1, + "hal_ledctrl": 1, + "avscontrol": 0, + "tty_console": 0, + "dev_monitor": 1, + "pmon_syslog": 1, + "sff_temp_polling": 1, + "reboot_cause": 0, + "product_name": 1, + "dfx_xdpe_monitor": 0, + "mgmt_ledctrl": 1, +} + +DEV_MONITOR_PARAM = { + "polling_time": 10, + "psus": [ + { + "name": "psu1", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/psu/psu1/present", "okval": 1}, + "device": [ + {"id": "psu1pmbus", "name": "wb_fsp1200", "bus": 67, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "24c02", "bus": 67, "loc": 0x50, "attr": "eeprom"} + ], + }, + { + "name": "psu2", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/psu/psu2/present", "okval": 1}, + "device": [ + {"id": "psu2pmbus", "name": "wb_fsp1200", "bus": 68, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "24c02", "bus": 68, "loc": 0x50, "attr": "eeprom"} + ], + }, + { + "name": "psu3", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/psu/psu3/present", "okval": 1}, + "device": [ + {"id": "psu3pmbus", "name": "wb_fsp1200", "bus": 69, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu3frue2", "name": "24c02", "bus": 69, "loc": 0x50, "attr": "eeprom"} + ], + }, + { + "name": "psu4", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/psu/psu4/present", "okval": 1}, + "device": [ + {"id": "psu4pmbus", "name": "wb_fsp1200", "bus": 70, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu4frue2", "name": "24c02", "bus": 70, "loc": 0x50, "attr": "eeprom"} + ], + }, + ], + "fans": [ + { + "name": "fan1", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan1/present", "okval": 1}, + "device": [ + {"id": "fan1frue2", "name": "24c64", "bus": 77, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan2", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan2/present", "okval": 1}, + "device": [ + {"id": "fan2frue2", "name": "24c64", "bus": 85, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan3", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan3/present", "okval": 1}, + "device": [ + {"id": "fan3frue2", "name": "24c64", "bus": 78, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan4", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan4/present", "okval": 1}, + "device": [ + {"id": "fan4frue2", "name": "24c64", "bus": 86, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan5", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan5/present", "okval": 1}, + "device": [ + {"id": "fan5frue2", "name": "24c64", "bus": 79, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan6", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan6/present", "okval": 1}, + "device": [ + {"id": "fan6frue2", "name": "24c64", "bus": 87, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan7", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan7/present", "okval": 1}, + "device": [ + {"id": "fan7frue2", "name": "24c64", "bus": 80, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan7", + "present": {"gettype": "sysfs", "loc": "/sys/s3ip/fan/fan8/present", "okval": 1}, + "device": [ + {"id": "fan8frue2", "name": "24c64", "bus": 88, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "24c02", "bus": 1, "loc": 0x56, "attr": "eeprom"}, + {"id": "eeprom_2", "name": "24c02", "bus": 1, "loc": 0x57, "attr": "eeprom"}, + {"id": "eeprom_3", "name": "24c02", "bus": 51, "loc": 0x57, "attr": "eeprom"}, + {"id": "eeprom_4", "name": "24c02", "bus": 97, "loc": 0x57, "attr": "eeprom"}, + {"id": "eeprom_5", "name": "24c02", "bus": 99, "loc": 0x57, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "lm75", "bus": 54, "loc": 0x4a, "attr": "hwmon"}, + {"id": "lm75_2", "name": "lm75", "bus": 55, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_3", "name": "lm75", "bus": 56, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_4", "name": "lm75", "bus": 76, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_5", "name": "lm75", "bus": 84, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_6", "name": "lm75", "bus": 93, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_7", "name": "lm75", "bus": 101, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_8", "name": "lm75", "bus": 123, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_9", "name": "lm75", "bus": 124, "loc": 0x4f, "attr": "hwmon"}, + ], + }, + { + "name": "ucd90160", + "device": [ + {"id": "ucd90160_1", "name": "ucd90160", "bus": 53, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_2", "name": "ucd90160", "bus": 54, "loc": 0x5f, "attr": "hwmon"}, + {"id": "ucd90160_3", "name": "ucd90160", "bus": 92, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_4", "name": "ucd90160", "bus": 100, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_5", "name": "ucd90160", "bus": 128, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_6", "name": "ucd90160", "bus": 129, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_7", "name": "ucd90160", "bus": 130, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_8", "name": "ucd90160", "bus": 57, "loc": 0x68, "attr": "hwmon"}, + ], + }, + { + "name": "ads7828", + "device": [ + {"id": "ads7828_1", "name": "ads7828", "bus": 60, "loc": 0x48, "attr": "hwmon"}, + ], + }, + ], + "binddevs": [ + { + "name": "wb-vr-common", + "driver_type": "platform", + "device": [ + {"id": "vr_1", "name": "wb-vr-common.1", "bus": 54, "loc": 0x72, "attr": "hwmon"}, + {"id": "vr_2", "name": "wb-vr-common.2", "bus": 54, "loc": 0x74, "attr": "hwmon"}, + {"id": "vr_3", "name": "wb-vr-common.3", "bus": 94, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_4", "name": "wb-vr-common.4", "bus": 95, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_5", "name": "wb-vr-common.5", "bus": 96, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_6", "name": "wb-vr-common.6", "bus": 97, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_7", "name": "wb-vr-common.7", "bus": 102, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_8", "name": "wb-vr-common.8", "bus": 103, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_9", "name": "wb-vr-common.9", "bus": 104, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_10", "name": "wb-vr-common.10", "bus": 105, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_11", "name": "wb-vr-common.11", "bus": 107, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_12", "name": "wb-vr-common.12", "bus": 108, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_13", "name": "wb-vr-common.13", "bus": 109, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_14", "name": "wb-vr-common.14", "bus": 110, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_15", "name": "wb-vr-common.15", "bus": 111, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_16", "name": "wb-vr-common.16", "bus": 112, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_17", "name": "wb-vr-common.17", "bus": 113, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_18", "name": "wb-vr-common.18", "bus": 114, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_19", "name": "wb-vr-common.19", "bus": 115, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_20", "name": "wb-vr-common.20", "bus": 116, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_21", "name": "wb-vr-common.21", "bus": 117, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_22", "name": "wb-vr-common.22", "bus": 118, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_23", "name": "wb-vr-common.23", "bus": 119, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_24", "name": "wb-vr-common.24", "bus": 120, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_25", "name": "wb-vr-common.25", "bus": 121, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_26", "name": "wb-vr-common.26", "bus": 122, "loc": 0x60, "attr": "hwmon"}, + {"id": "vr_27", "name": "wb-vr-common.27", "bus": 136, "loc": 0x60, "attr": "hwmon"}, + ], + }, + ], +} + + +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, + + "cpu": { + "key": "CPU", + "next": "ssd" + }, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, + }, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, + }, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, + }, + "ssd": { + "key": "SSD", + "next": "cpld" + }, + "ssd_model": { + "parent": "ssd", + "key": "Model Number", + "cmd": "smartctl -i /dev/nvme0n1 |grep \"Model Number\"", + "pattern": r".*Model Number", + "separator": ":", + "arrt_index": 1, + }, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/nvme0n1 |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/nvme0n1 |grep \"Namespace 1 Size/Capacity\"", + "pattern": r".*Namespace 1 Size/Capacity", + "separator": ":", + "arrt_index": 3, + }, + + "cpld": { + "key": "CPLD", + "next": "psu" + }, + + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-6900C-5BG400C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/cpld0", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-6900C-5BG400C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "MGMT_CPLD", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/cpld1", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-6900C-5BG400C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "MAC_CPLD_A", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "reg": { + "loc": "/dev/cpld2", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO3LF-4300C-5BG324C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "MAC_CPLD_B", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "reg": { + "loc": "/dev/cpld3", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO3LF-6900C-5BG400C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "MAC_CPLD_C", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "reg": { + "loc": "/dev/cpld4", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld6": { + "key": "CPLD6", + "parent": "cpld", + "arrt_index": 6, + }, + "cpld6_model": { + "key": "Device Model", + "parent": "cpld6", + "config": "LCMXO3LF-6900C-5BG400C", + "arrt_index": 1, + }, + "cpld6_vender": { + "key": "Vendor", + "parent": "cpld6", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld6_desc": { + "key": "Description", + "parent": "cpld6", + "config": "UPORT_CPLD", + "arrt_index": 3, + }, + "cpld6_version": { + "key": "Firmware Version", + "parent": "cpld6", + "reg": { + "loc": "/dev/cpld5", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + "cpld7": { + "key": "CPLD7", + "parent": "cpld", + "arrt_index": 7, + }, + "cpld7_model": { + "key": "Device Model", + "parent": "cpld7", + "config": "LCMXO3LF-6900C-5BG400C", + "arrt_index": 1, + }, + "cpld7_vender": { + "key": "Vendor", + "parent": "cpld7", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld7_desc": { + "key": "Description", + "parent": "cpld7", + "config": "DPORT_CPLD", + "arrt_index": 3, + }, + "cpld7_version": { + "key": "Firmware Version", + "parent": "cpld7", + "reg": { + "loc": "/dev/cpld6", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld8": { + "key": "CPLD8", + "parent": "cpld", + "arrt_index": 8, + }, + "cpld8_model": { + "key": "Device Model", + "parent": "cpld8", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld8_vender": { + "key": "Vendor", + "parent": "cpld8", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld8_desc": { + "key": "Description", + "parent": "cpld8", + "config": "UFAN_CPLD", + "arrt_index": 3, + }, + "cpld8_version": { + "key": "Firmware Version", + "parent": "cpld8", + "reg": { + "loc": "/dev/cpld7", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld9": { + "key": "CPLD9", + "parent": "cpld", + "arrt_index": 9, + }, + "cpld9_model": { + "key": "Device Model", + "parent": "cpld9", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld9_vender": { + "key": "Vendor", + "parent": "cpld9", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld9_desc": { + "key": "Description", + "parent": "cpld9", + "config": "DFAN_CPLD", + "arrt_index": 3, + }, + "cpld9_version": { + "key": "Firmware Version", + "parent": "cpld9", + "reg": { + "loc": "/dev/cpld8", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld10": { + "key": "CPLD10", + "parent": "cpld", + "arrt_index": 10, + }, + "cpld10_model": { + "key": "Device Model", + "parent": "cpld10", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld10_vender": { + "key": "Vendor", + "parent": "cpld10", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld10_desc": { + "key": "Description", + "parent": "cpld10", + "config": "MAC_CPLD_D", + "arrt_index": 3, + }, + "cpld10_version": { + "key": "Firmware Version", + "parent": "cpld10", + "reg": { + "loc": "/dev/cpld9", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "psu3": { + "parent": "psu", + "key": "PSU3", + "arrt_index": 3, + }, + "psu3_hw_version": { + "key": "Hardware Version", + "parent": "psu3", + "extra": { + "funcname": "getPsu", + "id": "psu3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu3_fw_version": { + "key": "Firmware Version", + "parent": "psu3", + "config": "NA", + "arrt_index": 2, + }, + + "psu4": { + "parent": "psu", + "key": "PSU4", + "arrt_index": 4, + }, + "psu4_hw_version": { + "key": "Hardware Version", + "parent": "psu4", + "extra": { + "funcname": "getPsu", + "id": "psu4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu4_fw_version": { + "key": "Firmware Version", + "parent": "psu4", + "config": "NA", + "arrt_index": 2, + }, + "fan": { + "key": "FAN", + "next": "i210" + }, + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, + + "fan5": { + "key": "FAN5", + "parent": "fan", + "arrt_index": 5, + }, + "fan5_hw_version": { + "key": "Hardware Version", + "parent": "fan5", + "extra": { + "funcname": "checkFan", + "id": "fan5", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan5_fw_version": { + "key": "Firmware Version", + "parent": "fan5", + "config": "NA", + "arrt_index": 2, + }, + + "fan6": { + "key": "FAN6", + "parent": "fan", + "arrt_index": 6, + }, + "fan6_hw_version": { + "key": "Hardware Version", + "parent": "fan6", + "extra": { + "funcname": "checkFan", + "id": "fan6", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan6_fw_version": { + "key": "Firmware Version", + "parent": "fan6", + "config": "NA", + "arrt_index": 2, + }, + + "fan7": { + "key": "FAN7", + "parent": "fan", + "arrt_index": 7, + }, + "fan7_hw_version": { + "key": "Hardware Version", + "parent": "fan7", + "extra": { + "funcname": "checkFan", + "id": "fan7", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan7_fw_version": { + "key": "Firmware Version", + "parent": "fan7", + "config": "NA", + "arrt_index": 2, + }, + + "fan8": { + "key": "FAN8", + "parent": "fan", + "arrt_index": 8, + }, + "fan8_hw_version": { + "key": "Hardware Version", + "parent": "fan8", + "extra": { + "funcname": "checkFan", + "id": "fan8", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan8_fw_version": { + "key": "Firmware Version", + "parent": "fan8", + "config": "NA", + "arrt_index": 2, + }, + "i210": { + "key": "NIC", + "next": "fpga" + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, + "fpga": { + "key": "FPGA", + "next": "others" + }, + + "fpga1": { + "key": "FPGA1", + "parent": "fpga", + "arrt_index": 1, + }, + "fpga1_model": { + "parent": "fpga1", + "devfile": { + "loc": "/dev/fpga0", + "offset":0x10, + "len":4, + "bit_width":4 + }, + "decode": { + "00000050": "XC7A50T-2FGG484I", + "00000100": "XC7A100T-2FGG484I" + }, + "key": "Device Model", + "arrt_index": 1, + }, + "fpga1_vender": { + "parent": "fpga1", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga1_desc": { + "key": "Description", + "parent": "fpga1", + "config": "MAC_FPGA", + "arrt_index": 3, + }, + "fpga1_hw_version": { + "parent": "fpga1", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga1_fw_version": { + "parent": "fpga1", + "devfile": { + "loc": "/dev/fpga0", + "offset":0, + "len":4, + "bit_width":4 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga1_date": { + "parent": "fpga1", + "devfile": { + "loc": "/dev/fpga0", + "offset":4, + "len":4, + "bit_width":4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + + "fpga2": { + "key": "FPGA2", + "parent": "fpga", + "arrt_index": 2, + }, + "fpga2_model": { + "parent": "fpga2", + "devfile": { + "loc": "/dev/fpga1", + "offset":0x10, + "len":4, + "bit_width":4 + }, + "decode": { + "00000050": "XC7A50T-2FGG484I", + "00000100": "XC7A100T-2FGG484I" + }, + "key": "Device Model", + "arrt_index": 2, + }, + "fpga2_vender": { + "parent": "fpga2", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga2_desc": { + "key": "Description", + "parent": "fpga2", + "config": "UPORT_FPGA", + "arrt_index": 3, + }, + "fpga2_hw_version": { + "parent": "fpga2", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga2_fw_version": { + "parent": "fpga2", + "devfile": { + "loc": "/dev/fpga1", + "offset":0, + "len":4, + "bit_width":4 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga2_date": { + "parent": "fpga2", + "devfile": { + "loc": "/dev/fpga1", + "offset":4, + "len":4, + "bit_width":4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + + "fpga3": { + "key": "FPGA3", + "parent": "fpga", + "arrt_index": 3, + }, + "fpga3_model": { + "parent": "fpga3", + "devfile": { + "loc": "/dev/fpga2", + "offset":0x10, + "len":4, + "bit_width":4 + }, + "decode": { + "00000050": "XC7A50T-2FGG484I", + "00000100": "XC7A100T-2FGG484I" + }, + "key": "Device Model", + "arrt_index": 3, + }, + "fpga3_vender": { + "parent": "fpga3", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 3, + }, + "fpga3_desc": { + "key": "Description", + "parent": "fpga3", + "config": "DPORT_FPGA", + "arrt_index": 3, + }, + "fpga3_hw_version": { + "parent": "fpga3", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga3_fw_version": { + "parent": "fpga3", + "devfile": { + "loc": "/dev/fpga2", + "offset":0, + "len":4, + "bit_width":4 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga3_date": { + "parent": "fpga3", + "devfile": { + "loc": "/dev/fpga2", + "offset":4, + "len":4, + "bit_width":4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + "others": { + "key": "OTHERS", + }, + "53134": { + "parent": "others", + "key": "CPU-BMC-SWITCH", + "arrt_index": 1, + }, + "53134_model": { + "parent": "53134", + "config": "BCM53134O", + "key": "Device Model", + "arrt_index": 1, + }, + "53134_vendor": { + "parent": "53134", + "config": "Broadcom", + "key": "Vendor", + "arrt_index": 2, + }, + "53134_hw_version": { + "parent": "53134", + "key": "Hardware Version", + "func": { + "funcname": "get_bcm5387_version", + "params": { + "before": [ + # enable tocm_jtag_en + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + # OE high + {"gettype": "cmd", "cmd": "echo 596 > /sys/class/gpio/export"}, + {"gettype": "cmd", "cmd": "echo high > /sys/class/gpio/gpio596/direction"}, + # SEL1 high + {"gettype": "cmd", "cmd": "echo 597 > /sys/class/gpio/export"}, + {"gettype": "cmd", "cmd": "echo high > /sys/class/gpio/gpio597/direction"}, + # enable 53134 update + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x54, "value": 0x01}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x55, "value": 0x05}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x4c, "value": 0xb2}, + # {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio_device sck=7 mosi=5 miso=6 cs=8 bus=0 gpio_chip_name=AMDI0030:00"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_93xx46 eeprom_name=gt93c56a"}, + ], + "get_version": "md5sum /sys/bus/spi/devices/spi0.0/eeprom | awk '{print $1}'", + "after": [ + {"gettype": "cmd", "cmd": "echo 0 > /sys/class/gpio/gpio597/value"}, + {"gettype": "cmd", "cmd": "echo 597 > /sys/class/gpio/unexport"}, + {"gettype": "cmd", "cmd": "echo 0 > /sys/class/gpio/gpio596/value"}, + {"gettype": "cmd", "cmd": "echo 596 > /sys/class/gpio/unexport"}, + ], + "finally": [ + {"gettype": "cmd", "cmd": "rmmod wb_spi_93xx46"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio_device"}, + # {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio"}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x4c, "value": 0xb3}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x55, "value": 0x00}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x54, "value": 0x00}, + # disable tocm_jtag_en + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + }, + "arrt_index": 3, + }, + +} + +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/s3ip/transceiver/*/present"], "ABSENT": 0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "sff1": "Ethernet1", + "sff2": "Ethernet2", + "sff3": "Ethernet3", + "sff4": "Ethernet4", + "sff5": "Ethernet5", + "sff6": "Ethernet6", + "sff7": "Ethernet7", + "sff8": "Ethernet8", + "sff9": "Ethernet9", + "sff10": "Ethernet10", + "sff11": "Ethernet11", + "sff12": "Ethernet12", + "sff13": "Ethernet13", + "sff14": "Ethernet14", + "sff15": "Ethernet15", + "sff16": "Ethernet16", + "sff17": "Ethernet17", + "sff18": "Ethernet18", + "sff19": "Ethernet19", + "sff20": "Ethernet20", + "sff21": "Ethernet21", + "sff22": "Ethernet22", + "sff23": "Ethernet23", + "sff24": "Ethernet24", + "sff25": "Ethernet25", + "sff26": "Ethernet26", + "sff27": "Ethernet27", + "sff28": "Ethernet28", + "sff29": "Ethernet29", + "sff30": "Ethernet30", + "sff31": "Ethernet31", + "sff32": "Ethernet32", + "sff33": "Ethernet33", + "sff34": "Ethernet34", + "sff35": "Ethernet35", + "sff36": "Ethernet36", + "sff37": "Ethernet37", + "sff38": "Ethernet38", + "sff39": "Ethernet39", + "sff40": "Ethernet40", + "sff41": "Ethernet41", + "sff42": "Ethernet42", + "sff43": "Ethernet43", + "sff44": "Ethernet44", + "sff45": "Ethernet45", + "sff46": "Ethernet46", + "sff47": "Ethernet47", + "sff48": "Ethernet48", + "sff49": "Ethernet49", + "sff50": "Ethernet50", + "sff51": "Ethernet51", + "sff52": "Ethernet52", + "sff53": "Ethernet53", + "sff54": "Ethernet54", + "sff55": "Ethernet55", + "sff56": "Ethernet56", + "sff57": "Ethernet57", + "sff58": "Ethernet58", + "sff59": "Ethernet59", + "sff60": "Ethernet60", + "sff61": "Ethernet61", + "sff62": "Ethernet62", + "sff63": "Ethernet63", + "sff64": "Ethernet64", + "sff65": "Ethernet65", + "sff66": "Ethernet66", + "sff67": "Ethernet67", + "sff68": "Ethernet68", + "sff69": "Ethernet69", + "sff70": "Ethernet70", + "sff71": "Ethernet71", + "sff72": "Ethernet72", + "sff73": "Ethernet73", + "sff74": "Ethernet74", + "sff75": "Ethernet75", + "sff76": "Ethernet76", + "sff77": "Ethernet77", + "sff78": "Ethernet78", + "sff79": "Ethernet79", + "sff80": "Ethernet80", + "sff81": "Ethernet81", + "sff82": "Ethernet82", + "sff83": "Ethernet83", + "sff84": "Ethernet84", + "sff85": "Ethernet85", + "sff86": "Ethernet86", + "sff87": "Ethernet87", + "sff88": "Ethernet88", + "sff89": "Ethernet89", + "sff90": "Ethernet90", + "sff91": "Ethernet91", + "sff92": "Ethernet92", + "sff93": "Ethernet93", + "sff94": "Ethernet94", + "sff95": "Ethernet95", + "sff96": "Ethernet96", + "sff97": "Ethernet97", + "sff98": "Ethernet98", + "sff99": "Ethernet99", + "sff100": "Ethernet100", + "sff101": "Ethernet101", + "sff102": "Ethernet102", + "sff103": "Ethernet103", + "sff104": "Ethernet104", + "sff105": "Ethernet105", + "sff106": "Ethernet106", + "sff107": "Ethernet107", + "sff108": "Ethernet108", + "sff109": "Ethernet109", + "sff110": "Ethernet110", + "sff111": "Ethernet111", + "sff112": "Ethernet112", + "sff113": "Ethernet113", + "sff114": "Ethernet114", + "sff115": "Ethernet115", + "sff116": "Ethernet116", + "sff117": "Ethernet117", + "sff118": "Ethernet118", + "sff119": "Ethernet119", + "sff120": "Ethernet120", + "sff121": "Ethernet121", + "sff122": "Ethernet122", + "sff123": "Ethernet123", + "sff124": "Ethernet124", + "sff125": "Ethernet125", + "sff126": "Ethernet126", + "sff127": "Ethernet127", + "sff128": "Ethernet128", + "sff129": "Ethernet129" + } + }, + "fans": { + "present": {"path": ["/sys/s3ip/fan/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/s3ip/fan/%s/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4", + "fan5": "FAN5", + "fan6": "FAN6", + "fan7": "FAN7", + "fan8": "FAN8" + } + }, + "psus": { + "present": {"path": ["/sys/s3ip/psu/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/s3ip/psu/%s/out_status", "okval":1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2", + "psu3": "PSU3", + "psu4": "PSU4" + } + } +} + +REBOOT_CAUSE_PARA = { + "reboot_cause_list": [ + { + "name": "cold_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x1d, "read_len":1, "okval":0x09}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Power Loss, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Power Loss, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ] + }, + { + "name": "wdt_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x1d, "read_len":1, "okval":0x05}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Watchdog, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Watchdog, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "bmc_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x1d, "read_len":1, "okval":0x06}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC reboot, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC reboot, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "cpu_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x1d, "read_len":1, "okval":[0x03, 0x04]}, + "record": [ + {"record_type": "file", "mode":"cover", "log":"CPU reboot, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "CPU reboot, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "bmc_powerdown", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x1d, "read_len":1, "okval":[0x02, 0x07, 0x0a]}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC powerdown, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC powerdown, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "otp_switch_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_switch_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: ASIC, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: ASIC, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_switch_reboot_flag"}, + ] + }, + { + "name": "otp_other_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_other_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: Other, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: Other, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_other_reboot_flag"}, + ] + }, + ], + "other_reboot_cause_record": [ + {"record_type": "file", "mode": "cover", "log": "Other, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Other, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], +} + +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "MAC_CORE_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8a, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs1", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/136-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8c : 0.794245, + 0x8a : 0.851800, + 0x88 : 0.864700, + 0x86 : 0.877600, + 0x84 : 0.83898, + 0x82 : 0.851795, + 0x80 : 0.864745, + }, + }, + { + "name": "MAC_PT0_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs2", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/107-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT1_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs3", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/107-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT2_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs4", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/108-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT3_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs5", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/108-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT4_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs6", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/109-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT5_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs7", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/109-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT6_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs8", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/110-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, + { + "name": "MAC_PT7_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/131-0044/hwmon/hwmon*/avs9", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/110-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x92 : 0.7000, + 0x90 : 0.7125, + 0x8e : 0.7250, + 0x8c : 0.7375, + 0x8a : 0.7500, + 0x88 : 0.7625, + 0x86 : 0.7750, + 0x84 : 0.7875, + 0x82 : 0.8000, + 0x80 : 0.8125, + }, + }, +] + +DRIVERLISTS = [ + {"name": "wb_ixgbe", "delay": 0, "removable": 0}, + {"name": "ice", "delay": 0, "removable": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "wb_i2c_designware_core", "delay": 0}, + {"name": "wb_i2c_designware_platform sda_fall_ns=320 scl_fall_ns=1006 bus_freq_hz=100000", "delay": 0}, + # {"name": "i2c_algo_bit", "delay": 0}, + # {"name": "i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + # {"name": "wb_i2c_gpio_device gpio_sda=116 gpio_scl=115 gpio_chip_name=AMDI0030:00 bus_num=2", "delay": 0}, + {"name": "i2c_piix4", "delay": 0.1}, + {"name": "platform_common dfd_my_type=0x414e", "delay": 0}, + {"name": "wb_logic_dev_common", "delay":0}, + {"name": "wb_fpga_pcie", "delay": 0}, + {"name": "wb_pcie_dev", "delay": 0}, + {"name": "wb_pcie_dev_device", "delay": 0}, + {"name": "wb_spi_gpio", "delay": 0}, + {"name": "wb_spi_gpio_device_cpld", "delay": 0}, + #{"name": "wb_io_dev", "delay": 0}, + #{"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_spi_dev", "delay": 0}, + {"name": "wb_spi_dev_device", "delay": 0.1}, + # {"name": "wb_indirect_dev", "delay": 0}, + {"name": "wb_fpga_i2c_bus_drv", "delay": 0}, + {"name": "wb_fpga_i2c_bus_device", "delay": 0}, + {"name": "wb_i2c_mux_pca954x", "delay": 0}, + {"name": "wb_i2c_mux_pca954x_device", "delay": 0}, + {"name": "wb_fpga_pca954x_drv", "delay": 0}, + {"name": "wb_fpga_pca954x_device", "delay": 0}, + {"name": "wb_i2c_dev_device", "delay": 0}, + # {"name": "wb_indirect_dev_device", "delay": 0}, + {"name": "wb_cpld_i2c_bus_device", "delay": 0.1}, + {"name": "wb_cpld_pca954x_device", "delay": 0}, + { + "init": [ + # disable mdio to avoid 81349 mdio error + {"path":"/dev/cpld1", "offset":0x41, "value":0x0, "gettype":"devfile"}, + ], + "name": "mdio_bitbang", "delay": 0 + }, + {"name": "mdio_gpio", "delay": 0}, + {"name": "wb_mdio_gpio_device gpio_mdc=131 gpio_mdio=132 gpio_chip_name=AMDI0030:00","delay": 0.1}, + {"name": "wb_wdt", "delay": 0}, + {"name": "wb_wdt_device", "delay": 0}, + #{"name": "wb_eeprom_93xx46", "delay": 0}, + {"name": "lm75", "delay": 0}, + {"name": "tmp401", "delay": 0}, + {"name": "ads7828", "delay": 0}, + {"name": "wb_rc32312", "delay": 0}, + {"name": "optoe", "delay": 0}, + {"name": "at24", "delay": 0}, + {"name": "pmbus_core", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "ucd9000", "delay": 0}, + {"name": "wb_ucd9081", "delay": 0}, + {"name": "xdpe12284", "delay": 0}, + {"name": "wb_xdpe132g5c_pmbus", "delay":0}, + {"name": "isl68137", "delay": 0}, + {"name": "wb_xdpe132g5c", "delay": 0}, + {"name": "wb_vr_common", "delay": 0}, + {"name": "wb_vr_common_dev_device", "delay": 0}, + #{"name": "firmware_driver_cpld", "delay": 0}, + #{"name": "firmware_driver_ispvme", "delay": 0}, + #{"name": "firmware_driver_sysfs", "delay": 0}, + #{"name": "wb_firmware_upgrade_device", "delay": 0}, + {"name": "hw_test", "delay": 0}, + {"name": "s3ip_sysfs", "delay": 0}, + {"name": "wb_switch_driver", "delay": 0}, + {"name": "syseeprom_device_driver", "delay": 0}, + {"name": "fan_device_driver", "delay": 0}, + {"name": "cpld_device_driver", "delay": 0}, + {"name": "sysled_device_driver", "delay": 0}, + {"name": "psu_device_driver", "delay": 0}, + {"name": "transceiver_device_driver", "delay": 0}, + {"name": "temp_sensor_device_driver", "delay": 0}, + {"name": "vol_sensor_device_driver", "delay": 0}, + #{"name": "curr_sensor_device_driver", "delay": 0}, + {"name": "fpga_device_driver", "delay": 0}, + {"name": "wb_mdio_dev", "delay": 0}, + {"name": "wb_switch_dev", "delay": 0}, + {"name": "wb_switch_dev_device", "delay": 0}, + +] + +DEVICE = [ + # CPU & MGMT board + {"name": "24c02", "bus": 1, "loc": 0x56}, + {"name": "24c02", "bus": 1, "loc": 0x57}, + {"name": "24c02", "bus": 51, "loc": 0x57}, + {"name": "ucd90160", "bus": 53, "loc": 0x5b}, + {"name": "lm75", "bus": 54, "loc": 0x4a}, # TMP1075DR + {"name": "ucd90160", "bus": 54, "loc": 0x5f}, + {"name": "lm75", "bus": 55, "loc": 0x4b}, # CT75 + {"name": "lm75", "bus": 56, "loc": 0x4b}, # CT75 + {"name": "ucd90160", "bus": 57, "loc": 0x68}, + {"name": "ads7828", "bus": 60, "loc": 0x48}, + # psu + {"name": "24c02", "bus": 67, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 67, "loc": 0x58}, + {"name": "24c02", "bus": 68, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 68, "loc": 0x58}, + {"name": "24c02", "bus": 69, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 69, "loc": 0x58}, + {"name": "24c02", "bus": 70, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 70, "loc": 0x58}, + # fcb + {"name": "lm75", "bus": 76, "loc": 0x4b}, # CT75 + {"name": "24c64", "bus": 77, "loc": 0x50}, + {"name": "24c64", "bus": 78, "loc": 0x50}, + {"name": "24c64", "bus": 79, "loc": 0x50}, + {"name": "24c64", "bus": 80, "loc": 0x50}, + {"name": "lm75", "bus": 84, "loc": 0x4b}, # CT75 + {"name": "24c64", "bus": 85, "loc": 0x50}, + {"name": "24c64", "bus": 86, "loc": 0x50}, + {"name": "24c64", "bus": 87, "loc": 0x50}, + {"name": "24c64", "bus": 88, "loc": 0x50}, + # uport + {"name": "24c02", "bus": 91, "loc": 0x57}, + {"name": "ucd90160", "bus": 92, "loc": 0x5b}, + {"name": "lm75", "bus": 93, "loc": 0x4b}, # CT75 + # dport + {"name": "24c02", "bus": 99, "loc": 0x57}, + {"name": "ucd90160", "bus": 100, "loc": 0x5b}, + {"name": "lm75", "bus": 101, "loc": 0x4b}, # CT75 + # mac board + {"name": "lm75", "bus": 123, "loc": 0x4b}, # CT75 + {"name": "lm75", "bus": 124, "loc": 0x4f}, # CT75 + {"name": "ucd90160", "bus": 128, "loc": 0x5b}, + {"name": "ucd90160", "bus": 129, "loc": 0x5b}, + {"name": "ucd90160", "bus": 130, "loc": 0x5b}, + {"name": "wb_mac_bsc_th6", "bus": 131, "loc": 0x44}, + {"name": "wb_rc32312", "bus": 134, "loc": 0x09}, + {"name": "wb_rc32312", "bus": 135, "loc": 0x09}, +] + +OPTOE = [ + {"name": "optoe3", "startbus": 201, "endbus": 328}, + {"name": "optoe1", "startbus": 329, "endbus": 329}, + {"name": "optoe2", "startbus": 330, "endbus": 330}, +] + +INIT_PARAM_PRE = [ + # MAC_CORE min and max value + # {"loc": "136-0060/hwmon/hwmon*/avs0_vout_min", "value": "747100", "gettype": "sysfs"}, + # {"loc": "136-0060/hwmon/hwmon*/avs0_vout_max", "value": "828900", "gettype": "sysfs"}, + # {"loc": "136-0060/hwmon/hwmon*/avs0_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "136-0060/hwmon/hwmon*/avs0_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "107-0060/hwmon/hwmon*/avs0_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "107-0060/hwmon/hwmon*/avs0_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "108-0060/hwmon/hwmon*/avs0_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "108-0060/hwmon/hwmon*/avs0_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "109-0060/hwmon/hwmon*/avs0_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "109-0060/hwmon/hwmon*/avs0_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "110-0060/hwmon/hwmon*/avs0_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "110-0060/hwmon/hwmon*/avs0_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "107-0060/hwmon/hwmon*/avs1_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "107-0060/hwmon/hwmon*/avs1_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "108-0060/hwmon/hwmon*/avs1_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "108-0060/hwmon/hwmon*/avs1_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "109-0060/hwmon/hwmon*/avs1_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "109-0060/hwmon/hwmon*/avs1_vout_max", "value": "900000", "gettype": "sysfs"}, + # {"loc": "110-0060/hwmon/hwmon*/avs1_vout_min", "value": "600000", "gettype": "sysfs"}, + # {"loc": "110-0060/hwmon/hwmon*/avs1_vout_max", "value": "900000", "gettype": "sysfs"}, +] + +INIT_COMMAND = [ + # UPORT OSFP_VDD3V3 EN + "dfd_debug sysfs_data_wr /dev/cpld5 0x23 0xdd", + "dfd_debug sysfs_data_wr /dev/cpld5 0x24 0xdb", + "dfd_debug sysfs_data_wr /dev/cpld5 0x25 0xdb", + "dfd_debug sysfs_data_wr /dev/cpld5 0x26 0xd9", + "dfd_debug sysfs_data_wr /dev/cpld5 0x27 0xd9", + "dfd_debug sysfs_data_wr /dev/cpld5 0x28 0xd7", + "dfd_debug sysfs_data_wr /dev/cpld5 0x29 0xd7", + "dfd_debug sysfs_data_wr /dev/cpld5 0x2a 0xd5", + + # MAC OSFP_VDD3V3 EN + "dfd_debug sysfs_data_wr /dev/cpld4 0x30 0xcf", + "dfd_debug sysfs_data_wr /dev/cpld4 0x31 0xcf", + "dfd_debug sysfs_data_wr /dev/cpld4 0x32 0xcd", + "dfd_debug sysfs_data_wr /dev/cpld4 0x33 0xcd", + "dfd_debug sysfs_data_wr /dev/cpld4 0x34 0xcb", + "dfd_debug sysfs_data_wr /dev/cpld4 0x35 0xcb", + "dfd_debug sysfs_data_wr /dev/cpld4 0x36 0xc9", + "dfd_debug sysfs_data_wr /dev/cpld4 0x37 0xc9", + "dfd_debug sysfs_data_wr /dev/cpld4 0x38 0xc7", + "dfd_debug sysfs_data_wr /dev/cpld4 0x39 0xc7", + "dfd_debug sysfs_data_wr /dev/cpld4 0x3a 0xc5", + "dfd_debug sysfs_data_wr /dev/cpld4 0x3b 0xc5", + "dfd_debug sysfs_data_wr /dev/cpld4 0x3c 0xc3", + "dfd_debug sysfs_data_wr /dev/cpld4 0x3d 0xc3", + "dfd_debug sysfs_data_wr /dev/cpld4 0x3e 0xc1", + "dfd_debug sysfs_data_wr /dev/cpld4 0x3f 0xc1", + # DPORT OSFP_VDD3V3 EN + "dfd_debug sysfs_data_wr /dev/cpld6 0x23 0xdd", + "dfd_debug sysfs_data_wr /dev/cpld6 0x24 0xdb", + "dfd_debug sysfs_data_wr /dev/cpld6 0x25 0xdb", + "dfd_debug sysfs_data_wr /dev/cpld6 0x26 0xd9", + "dfd_debug sysfs_data_wr /dev/cpld6 0x27 0xd9", + "dfd_debug sysfs_data_wr /dev/cpld6 0x28 0xd7", + "dfd_debug sysfs_data_wr /dev/cpld6 0x29 0xd7", + "dfd_debug sysfs_data_wr /dev/cpld6 0x2a 0xd5", + # UPORT efuse en + "dfd_debug sysfs_data_wr /dev/fpga1 0x58 0xff 0xff 0xff 0xff", + # MAC efuse EN + "dfd_debug sysfs_data_wr /dev/cpld9 0x20 0xDF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x21 0xDF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x22 0xDD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x23 0xDD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x24 0xDB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x25 0xDB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x26 0xD9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x27 0xD9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x28 0xD7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x29 0xD7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x2A 0xD5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x2B 0xD5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x2C 0xD3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x2D 0xD3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x2E 0xD1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x2F 0xD1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x30 0xCF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x31 0xCF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x32 0xCD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x33 0xCD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x34 0xCB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x35 0xCB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x36 0xC9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x37 0xC9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x38 0xC7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x39 0xC7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x3A 0xC5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x3B 0xC5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x3C 0xC3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x3D 0xC3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x3E 0xC1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x3F 0xC1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x40 0xBF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x41 0xBF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x42 0xBD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x43 0xBD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x44 0xBB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x45 0xBB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x46 0xB9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x47 0xB9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x48 0xB7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x49 0xB7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x4A 0xB5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x4B 0xB5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x4C 0xB3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x4D 0xB3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x4E 0xB1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x4F 0xB1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x50 0xAF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x51 0xAF", + "dfd_debug sysfs_data_wr /dev/cpld9 0x52 0xAD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x53 0xAD", + "dfd_debug sysfs_data_wr /dev/cpld9 0x54 0xAB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x55 0xAB", + "dfd_debug sysfs_data_wr /dev/cpld9 0x56 0xA9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x57 0xA9", + "dfd_debug sysfs_data_wr /dev/cpld9 0x58 0xA7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x59 0xA7", + "dfd_debug sysfs_data_wr /dev/cpld9 0x5A 0xA5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x5B 0xA5", + "dfd_debug sysfs_data_wr /dev/cpld9 0x5C 0xA3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x5D 0xA3", + "dfd_debug sysfs_data_wr /dev/cpld9 0x5E 0xA1", + "dfd_debug sysfs_data_wr /dev/cpld9 0x5F 0xA1", + # DOORT efuse en + "dfd_debug sysfs_data_wr /dev/fpga2 0x58 0xff 0xff 0xff 0xff", + # Enable port129 power + "dfd_debug sysfs_data_wr /dev/cpld1 0x5d 0xa3", + # saphy bcm81394 mdio access enable + "dfd_debug sysfs_data_wr /dev/cpld1 0x41 0x03", + # write CPU_READY to release sys led control + "dfd_debug sysfs_data_wr /dev/cpld1 0x8f 0x01", +] + +UPGRADE_SUMMARY = { + "devtype": 0x414e, + + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "CPU_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain2": { + "name": "MGMT_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain3": { + "name": "MAC_CPLD_AB", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain4": { + "name": "MAC_CPLD_C", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain5": { + "name": "UPORT_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain6": { + "name": "DPORT_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain7": { + "name": "UFAN_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain8": { + "name": "DFAN_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain9": { + "name": "MAC_CPLD_D", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + }, + + "SPI-LOGIC-DEV": { + "chain1": { + "name": "MAC_FPGA", + "is_support_warm_upg": 0, + }, + "chain2": { + "name": "MAC_FPGA_SHAOPIAN", + "is_support_warm_upg": 0, + }, + "chain3": { + "name": "UPORT_FPGA", + "is_support_warm_upg": 0, + }, + "chain4": { + "name": "UPORT_FPGA_SHAOPIAN", + "is_support_warm_upg": 0, + }, + "chain5": { + "name": "DPORT_FPGA", + "is_support_warm_upg": 0, + }, + "chain6": { + "name": "DPORT_FPGA_SHAOPIAN", + "is_support_warm_upg": 0, + }, + }, + + "SYSFS": { + "chain8": { + "name": "BCM53134", + "is_support_warm_upg": 0, + "init_cmd": [ + # {"cmd": "modprobe wb_spi_gpio", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_gpio_device sck=7 mosi=5 miso=6 cs=8 bus=0 gpio_chip_name=AMDI0030:00", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_93xx46 eeprom_name=gt93c56a", "gettype": "cmd", "delay": 0.1}, + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + {"cmd": "rmmod wb_spi_93xx46", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio_device", "gettype": "cmd"}, + # {"cmd": "rmmod wb_spi_gpio", "gettype": "cmd", "delay": 0.1}, + ], + }, + }, + + #"BASH": { + # "chain1": { + # "name": "SATA", + # "upgrade_way": UPGRADE_BY_HDPARM, + # "dev_name": "sda", + # }, + #}, + + "TEST": { + "fpga": [ + {"chain": 1, "file": "/etc/.upgrade_test/mac_fpga_test_header.bin", "display_name": "MAC_FPGA"}, + {"chain": 3, "file": "/etc/.upgrade_test/uport_fpga_test_header.bin", "display_name": "UPORT_FPGA"}, + {"chain": 5, "file": "/etc/.upgrade_test/dport_fpga_test_header.bin", "display_name": "DPORT_FPGA"}, + ], + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/cpu_cpld_test_header.vme", "display_name": "CPU_CPLD"}, + {"chain": 2, "file": "/etc/.upgrade_test/mgmt_cpld_test_header.vme", "display_name": "MGMT_CPLD"}, + {"chain": 3, "file": "/etc/.upgrade_test/mac_cpldab_test_header.vme", "display_name": "MAC_CPLD_AB"}, + {"chain": 4, "file": "/etc/.upgrade_test/mac_cpldc_test_header.vme", "display_name": "MAC_CPLD_C"}, + {"chain": 5, "file": "/etc/.upgrade_test/uport_cpld_test_header.vme", "display_name": "UPORT_CPLD"}, + {"chain": 6, "file": "/etc/.upgrade_test/dport_cpld_test_header.vme", "display_name": "DPORT_CPLD"}, + {"chain": 7, "file": "/etc/.upgrade_test/ufan_cpld_test_header.vme", "display_name": "UFAN_CPLD"}, + {"chain": 8, "file": "/etc/.upgrade_test/dfan_cpld_test_header.vme", "display_name": "DFAN_CPLD"}, + {"chain": 9, "file": "/etc/.upgrade_test/mac_cpldd_test_header.vme", "display_name": "MAC_CPLD_D"}, + ], + }, + }, +} + +PLATFORM_E2_CONF = { + "fan": [ + {"name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/77-0050/eeprom"}, + {"name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/85-0050/eeprom"}, + {"name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/78-0050/eeprom"}, + {"name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/86-0050/eeprom"}, + {"name": "fan5", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/79-0050/eeprom"}, + {"name": "fan6", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/87-0050/eeprom"}, + {"name": "fan7", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/80-0050/eeprom"}, + {"name": "fan8", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/88-0050/eeprom"}, + ], + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/67-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/68-0050/eeprom"}, + {"name": "psu3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/69-0050/eeprom"}, + {"name": "psu4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/70-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, + ], + "mgmt": [ + {"name": "MGMT card", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/51-0057/eeprom"}, + ], + "uport": [ + {"name": "Uport board", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/91-0057/eeprom"}, + ], + "dport": [ + {"name": "Dport board", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/99-0057/eeprom"}, + ], + "mac": [ + {"name": "MAC board", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/1-0057/eeprom"}, + ], +} + +AIR_FLOW_CONF = { +} + +# DFX_XDPE_MONITOR_INFO = { +# "device_list": [ +# { +# "name": "wb_isl69260", +# "loc": "70-0070", +# "page": [0, 1], +# }, +# { +# "name": "wb_isl69260", +# "loc": "70-006e", +# "page": [0, 1], +# }, +# { +# "name": "wb_isl69260", +# "loc": "70-005e", +# "page": [0, 1], +# }, +# { +# "name": "wb_isl69260", +# "loc": "70-0068", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe1a2g5b", +# "loc": "85-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "86-0062", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "87-0062", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "88-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "89-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "90-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "91-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "92-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "93-0062", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "94-0062", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "95-0060", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "96-0074", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "97-0074", +# "page": [0, 1], +# }, +# { +# "name": "wb_xdpe12284c", +# "loc": "98-0074", +# "page": [0, 1], +# }, +# ] +# } + +MGMT_LED_CONFIG = { + "interval": 3, + "mgmt_led_list": [ + { + "name": "sfp_phy", + "link_path": "/sys/logic_dev/sfp_phy/link_status", + "led_path": "/sys/s3ip/sysled/lan_led_status", + }, + ] +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_port_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_port_config.py new file mode 100644 index 0000000000..4f727afc8a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/config/x86_64_micas_m2_w6950_128oc_r0_port_config.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python_nos +# -*- coding: UTF-8 -*- +PLATFORM_INTF_OPTOE = { + "port_num": 129, + "optoe_start_bus": 201, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_device.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_device.py new file mode 100644 index 0000000000..1a31793f43 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_device.py @@ -0,0 +1,1079 @@ +#!/usr/bin/env python_nos + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + +psu_fan_airflow = { + "intake": ['CRPS2700D2','AP-CA3200F12DT'], + "exhaust": [] +} + +fanairflow = { + "intake": ['FAN80-04H-F'], + "exhaust": [], +} + + +s3ip_led_decode = { + "red flash": 0x07, "red": 0x03, "green flash": 0x05, "green": 0x01, + "amber flash": 0x06, "amber": 0x02, "off": 0, "mask": 0x0ff +} + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +class threshold: + PSU_TEMP_MIN = -20 * 1000 + PSU_TEMP_MAX = 65 * 1000 + + PSU_FAN_SPEED_MIN = 1000 + PSU_FAN_SPEED_MAX = 37000 + PSU_A_FAN_SPEED_MAX = 39000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 13 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 90 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 264 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 180 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 320 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 0* 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 3000 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 0 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 3100* 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 0 * 1000 + PSU_OUTPUT_CURRENT_MAX = 246 * 1000 + + PSU_INPUT_CURRENT_MIN = 0 * 1000 + PSU_INPUT_CURRENT_MAX = 20 * 1000 + + FRONT_FAN_SPEED_MAX = 18000 + REAR_FAN_SPEED_MAX = 16000 + FAN_SPEED_MIN = 3200 + + +devices = { + "sensor_print_src": "s3ip", + + "dcdc_data_source": [ + { + "path": "/sys/s3ip/vol_sensor", + "type": "vol", + "Unit": Unit.Voltage, + "read_times": 3, + }, + { + "path": "/sys/s3ip/curr_sensor", + "type": "curr", + "Unit": Unit.Current, + "read_times": 3, + }, + ], + "temp_data_source": [ + { + "path": "/sys/s3ip/temp_sensor", + "type": "temp", + "Unit": Unit.Temperature, + }, + ], + + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/1-0056/eeprom", "way": "sysfs"}, + "airflow": "intake" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/67-0050/eeprom", "way": "sysfs"}, + "psu_sn": {"loc": "/sys/s3ip/psu/psu1/serial_number", "way": "sysfs"}, + "psu_hw": {"loc": "/sys/s3ip/psu/psu1/hardware_version", "way": "sysfs"}, + "psu_pn": {"loc": "/sys/s3ip/psu/psu1/part_number", "way": "sysfs"}, + "psu_vendor": {"loc": "/sys/s3ip/psu/psu1/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 67, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 67, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu1/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 67, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu1/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 67, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 67, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu1/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu1/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu1/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu1/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 67, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu1/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu1/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu1/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/68-0050/eeprom", "way": "sysfs"}, + "psu_sn": {"loc": "/sys/s3ip/psu/psu2/serial_number", "way": "sysfs"}, + "psu_hw": {"loc": "/sys/s3ip/psu/psu2/hardware_version", "way": "sysfs"}, + "psu_pn": {"loc": "/sys/s3ip/psu/psu2/part_number", "way": "sysfs"}, + "psu_vendor": {"loc": "/sys/s3ip/psu/psu2/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 68, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 68, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu2/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 68, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu2/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 68, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 68, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu2/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu2/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu2/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu2/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 68, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu2/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu2/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu2/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/69-0050/eeprom", "way": "sysfs"}, + "psu_sn": {"loc": "/sys/s3ip/psu/psu3/serial_number", "way": "sysfs"}, + "psu_hw": {"loc": "/sys/s3ip/psu/psu3/hardware_version", "way": "sysfs"}, + "psu_pn": {"loc": "/sys/s3ip/psu/psu3/part_number", "way": "sysfs"}, + "psu_vendor": {"loc": "/sys/s3ip/psu/psu3/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 69, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU3", + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 69, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu3/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 69, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu3/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 69, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 69, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu3/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu3/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu3/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu3/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 69, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu3/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu3/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu3/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/70-0050/eeprom", "way": "sysfs"}, + "psu_sn": {"loc": "/sys/s3ip/psu/psu4/serial_number", "way": "sysfs"}, + "psu_hw": {"loc": "/sys/s3ip/psu/psu4/hardware_version", "way": "sysfs"}, + "psu_pn": {"loc": "/sys/s3ip/psu/psu4/part_number", "way": "sysfs"}, + "psu_vendor": {"loc": "/sys/s3ip/psu/psu4/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 70, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU4", + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 70, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu4/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 70, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu4/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 70, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 70, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu4/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu4/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu4/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu4/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 70, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu4/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu4/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu4/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + } + ], + "temps": [ + { + "name": "CPU_TEMP", + "temp_id": "TEMP1", + "api_name": "CPU", + "Temperature": { + "value": {"loc": "/sys/s3ip/temp_sensor/temp11/value", "way": "sysfs"}, + "Min": -30000, + "Low": -20000, + "High": 90000, + "Max": 95000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP2", + "api_name": "Inlet", + "Temperature": { + "value": {"loc": "/sys/s3ip/temp_sensor/temp2/value", "way": "sysfs"}, + "Min": -30000, + "Low": -20000, + "High": 60000, + "Max": 70000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP3", + "api_name": "Outlet", + "Temperature": { + "value": [ + {"loc": "/sys/s3ip/temp_sensor/temp3/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp4/value", "way": "sysfs"}, + ], + "Min": -30000, + "Low": -20000, + "High": 70000, + "Max": 75000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP4", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/s3ip/temp_sensor/temp13/value", "way": "sysfs"}, + "Min": -30000, + "Low": -20000, + "High": 100000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -100000, + "error": -99999, + }, + { + "name": "MOS_TEMP", + "temp_id": "TEMP5", + "Temperature": { + "value": [ + {"loc": "/sys/s3ip/temp_sensor/temp14/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp15/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp16/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp17/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp18/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp19/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp20/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp21/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp22/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp23/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp24/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp25/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp26/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp27/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp28/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp29/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp30/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp31/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp32/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp33/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp34/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp35/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp36/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp37/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp38/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp39/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp40/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp41/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp42/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp43/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp44/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp45/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp46/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp47/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp48/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp49/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp50/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp51/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp52/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp53/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp54/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp55/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp56/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp57/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp58/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp59/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp60/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp61/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp62/value", "way": "sysfs"}, + ], + "Min": -30000, + "Low": -20000, + "High": 110000, + "Max": 125000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "BOARD_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/s3ip/temp_sensor/temp6/value", "way": "sysfs"}, + "Min": -30000, + "Low": -20000, + "High": 95000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/etc/sonic/highest_sff_temp", "way": "sysfs", "flock_path": "/etc/sonic/highest_sff_temp"}, + "Min": -30000, + "Low": -20000, + "High": 80000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"loc": "/sys/s3ip/sysled/sys_led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + }, + { + "name": "FRONT_BMC_LED", + "led_type": "BMC_LED", + "led": {"loc": "/sys/s3ip/sysled/bmc_led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"loc": "/sys/s3ip/sysled/psu_led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"loc": "/sys/s3ip/sysled/fan_led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/77-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan1/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x90, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x90, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan1/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan1/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan1/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/85-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan2/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x90, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x90, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan2/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan2/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan2/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/78-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan3/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x91, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x91, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan3/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan3/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan3/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/86-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan4/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x91, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x91, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN5", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/79-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan5/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan5/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x92, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan5/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x92, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan5/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan5/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan5/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN6", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/87-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan6/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan6/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x92, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan6/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x92, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan6/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan6/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan6/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN7", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/80-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan7/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan7/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x93, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan7/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan7/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan7/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld7", "offset": 0x93, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan7/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan7/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan7/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN8", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/88-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan8/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/sys/s3ip/fan/fan8/led_status", "way": "sysfs"}, + "led_attrs": s3ip_led_decode, + "PowerMax": 168, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x93, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan8/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan8/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan8/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld8", "offset": 0x93, "len": 1, "way": "devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan8/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan8/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan8/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + } + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + "warm": 1, + }, + { + "name": "MGMT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDA", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDB", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld3", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDC", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "UPORT_CPLD", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/cpld5", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "DPORT_CPLD", + "cpld_id": "CPLD7", + "VersionFile": {"loc": "/dev/cpld6", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "UFAN_CPLD", + "cpld_id": "CPLD8", + "VersionFile": {"loc": "/dev/cpld7", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + "warm": 1, + }, + { + "name": "DFAN_CPLD", + "cpld_id": "CPLD9", + "VersionFile": {"loc": "/dev/cpld8", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDD", + "cpld_id": "CPLD10", + "VersionFile": {"loc": "/dev/cpld9", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_FPGA", + "cpld_id": "CPLD11", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "UPORT_FPGA", + "cpld_id": "CPLD12", + "VersionFile": {"loc": "/dev/fpga1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "DPORT_FPGA", + "cpld_id": "CPLD13", + "VersionFile": {"loc": "/dev/fpga2", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "BIOS", + "cpld_id": "CPLD14", + "VersionFile": {"cmd": "dmidecode -s bios-version", "way": "cmd"}, + "desc": "Performs initialization of hardware components during booting", + "slot": 0, + "type": "str", + "warm": 0, + }, + ], + "cpu": [ + { + "name": "cpu", + "CpuResetCntReg": {"loc": "/dev/cpld1", "offset": 0x10, "len": 1, "way": "devfile_ascii"}, + "reboot_cause_path": "/etc/sonic/.reboot/.previous-reboot-cause.txt" + } + ], + "sfps": { + "ver": '2.0', + "port_index_start": 1, + "port_num": 129, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_path": "/sys/s3ip/transceiver/eth%d/present", + "presence_val_is_present": 1, + "eeprom_path": "/sys/s3ip/transceiver/eth%d/eeprom", + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(201, 330)), + "lpmode_path": "/sys/s3ip/transceiver/eth%d/low_power_mode", + "reset_path": "/sys/s3ip/transceiver/eth%d/reset", + "reset_val_is_reset": 0, + "tx_dis_path": "/sys/s3ip/transceiver/eth%d/tx_disable", + "rx_los_path": "/sys/s3ip/transceiver/eth%d/rx_los", + "tx_fault_path": "/sys/s3ip/transceiver/eth%d/tx_fault", + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_monitor.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_monitor.py new file mode 100644 index 0000000000..250f76906e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/hal-config/x86_64_micas_m2_w6950_128oc_r0_monitor.py @@ -0,0 +1,186 @@ +# coding:utf-8 + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 0, + "pwm_min": 0x66, + "pwm_max": 0xff, + "K": 11, + "tin_min": 38, + }, + "curve": { + "name": "curve", + "flag": 1, + "pwm_min": 0x66, + "pwm_max": 0xff, + "a": 0.4, + "b": -15.7, + "c": 245.3, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x66, + "pwm_max": 0xff, + "Kp": 0.5, + "Ki": 0.3, + "Kd": 0.3, + "target": 80, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x66, + "pwm_max": 0xff, + "Kp": 0.5, + "Ki": 0.3, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "OUTLET_TEMP": { + "name": "OUTLET_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x66, + "pwm_max": 0xff, + "Kp": 0, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x66, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.3, + "Kd": 0, + "target": 63, + "value": [None, None, None], + }, + "BOARD_TEMP": { + "name": "BOARD_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x66, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 80, + "value": [None, None, None], + }, + "MOS_TEMP": { + "name": "MOS_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x66, + "pwm_max": 0xff, + "Kp": 1, + "Ki": 0.1, + "Kd": 0.3, + "target": 95, + "value": [None, None, None], + }, + }, + + "temps_threshold": { + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 90, "critical": 95}, + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105, "alert": 110, "invalid": -100000, "error": -99999}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 60, "critical": 70}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 75}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 95, "critical": 105}, + "MOS_TEMP": {"name": "MOS_TEMP", "warning": 110, "critical": 125}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "max_pwm": 0xff, + "min_pwm": 0x66, + "abnormal_pwm": 0xff, + "warning_pwm": 0xff, + "temp_invalid_pid_pwm": 0x66, + "temp_error_pid_pwm": 0x66, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + {"temp_name": "SWITCH_TEMP"}, + {"temp_name": "CPU_TEMP"}, + {"temp_name": "OUTLET_TEMP"}, + {"temp_name": "BOARD_TEMP"}, + {"temp_name": "MOS_TEMP"}, + ], + "temp_warning_num": 3, # temp over warning 3 times continuously + "temp_critical_num": 3, # temp over critical 3 times continuously + "temp_alert_num": 1, # temp over alert 1 times continuously + "temp_warning_countdown": 60, # 5 min warning speed after not warning + "temp_critical_countdown": 60, # 5 min full speed after not critical + "rotor_error_count": 3, # fan rotor error 3 times continuously + "inlet_mac_diff": 999, + "check_crit_reboot_flag": 1, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 5, + "check_temp_critical_reboot": [ + ["SWITCH_TEMP"], + ["INLET_TEMP", "OUTLET_TEMP", "BOARD_TEMP", "CPU_TEMP", "MOS_TEMP"], + ], + "check_alert_reboot_flag": 1, + "check_alert_reboot_num": 3, + "check_alert_sleep_time": 0.05, + "check_temp_alert_reboot": [ + ["SWITCH_TEMP"], + ], + "psu_fan_control": 1, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 3, + "rotor_error_fullspeed_num": 6, + "deal_over_temp_reboot_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0x86, "value": 0x06}, + ] + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 1: sys led follow psu led + "checkfan": 0, # 1: sys led follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "bios_boot_source_check": 0, + "bmcled_ctrl": 0, + "board_sys_led": [ + {"led_name": "FRONT_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "FRONT_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "FRONT_FAN_LED"}, + ], + "board_bmc_led": [ + {"led_name": "FRONT_BMC_LED"}, + ], + "psu_air_flow_monitor": 0, + "fan_air_flow_monitor": 0, + "psu_air_flow_amber_num": 0, + "fan_air_flow_amber_num": 0, + }, + + "otp_reboot_judge_file": { + "otp_switch_reboot_judge_file": "/etc/.otp_switch_reboot_flag", + "otp_other_reboot_judge_file": "/etc/.otp_other_reboot_flag", + }, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/Makefile new file mode 100644 index 0000000000..26bc7caa79 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/Makefile @@ -0,0 +1,29 @@ +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +KERNEL_MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/app/firmware_upgrade/firmware_driver/include) +BSP_PUBLIC_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/public/include) +COMMON_MODULE_SYMVERS = $(KERNEL_MODULES_DIR)/Module.symvers + +ifneq ($(wildcard $(COMMON_MODULE_SYMVERS)),) +KBUILD_EXTRA_SYMBOLS += $(COMMON_MODULE_SYMVERS) +endif + +EXTRA_CFLAGS+= -I$(BSP_PUBLIC_PATH) +EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) + +obj-m += wb_pcie_dev_device.o +obj-m += wb_fpga_i2c_bus_device.o +obj-m += wb_i2c_mux_pca954x_device.o +obj-m += wb_fpga_pca954x_device.o +obj-m += wb_i2c_dev_device.o +#obj-m += wb_firmware_upgrade_device.o +obj-m += wb_wdt_device.o +obj-m += wb_vr_common_dev_device.o +obj-m += wb_cpld_i2c_bus_device.o +obj-m += wb_cpld_pca954x_device.o +obj-m += wb_spi_gpio_device_cpld.o +obj-m += wb_spi_dev_device.o +obj-m += wb_switch_dev_device.o +obj-m += wb_spi_gpio.o diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/spi-bitbang-txrx.h b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/spi-bitbang-txrx.h new file mode 100644 index 0000000000..0cab48b787 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/spi-bitbang-txrx.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Mix this utility code with some glue code to get one of several types of + * simple SPI master driver. Two do polled word-at-a-time I/O: + * + * - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), + * expanding the per-word routines from the inline templates below. + * + * - Drivers for controllers resembling bare shift registers. Provide + * chipselect() and txrx_word[](), with custom setup()/cleanup() methods + * that use your controller's clock and chipselect registers. + * + * Some hardware works well with requests at spi_transfer scope: + * + * - Drivers leveraging smarter hardware, with fifos or DMA; or for half + * duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), + * and custom setup()/cleanup() methods. + */ + +/* + * The code that knows what GPIO pins do what should have declared four + * functions, ideally as inlines, before including this header: + * + * void setsck(struct spi_device *, int is_on); + * void setmosi(struct spi_device *, int is_on); + * int getmiso(struct spi_device *); + * void spidelay(unsigned); + * + * setsck()'s is_on parameter is a zero/nonzero boolean. + * + * setmosi()'s is_on parameter is a zero/nonzero boolean. + * + * getmiso() is required to return 0 or 1 only. Any other value is invalid + * and will result in improper operation. + * + * A non-inlined routine would call bitbang_txrx_*() routines. The + * main loop could easily compile down to a handful of instructions, + * especially if the delay is a NOP (to run at peak speed). + * + * Since this is software, the timings may not be exactly what your board's + * chips need ... there may be several reasons you'd need to tweak timings + * in these routines, not just to make it faster or slower to match a + * particular CPU clock rate. + * + * ToDo: Maybe the bitrev macros can be used to improve the code? + */ + +static inline u32 +bitbang_txrx_be_cpha0(struct spi_device *spi, + unsigned nsecs, unsigned cpol, unsigned flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + u32 oldbit = (!(word & (1<<(bits-1)))) << 31; + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on trailing edge */ + if ((flags & SPI_CONTROLLER_NO_TX) == 0) { + if ((word & (1 << 31)) != oldbit) { + setmosi(spi, word & (1 << 31)); + oldbit = word & (1 << 31); + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on leading edge */ + word <<= 1; + if ((flags & SPI_CONTROLLER_NO_RX) == 0) + word |= getmiso(spi); + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_be_cpha1(struct spi_device *spi, + unsigned nsecs, unsigned cpol, unsigned flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + u32 oldbit = (!(word & (1<<(bits-1)))) << 31; + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on leading edge */ + setsck(spi, !cpol); + if ((flags & SPI_CONTROLLER_NO_TX) == 0) { + if ((word & (1 << 31)) != oldbit) { + setmosi(spi, word & (1 << 31)); + oldbit = word & (1 << 31); + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on trailing edge */ + word <<= 1; + if ((flags & SPI_CONTROLLER_NO_RX) == 0) + word |= getmiso(spi); + } + return word; +} + +static inline u32 +bitbang_txrx_le_cpha0(struct spi_device *spi, + unsigned int nsecs, unsigned int cpol, unsigned int flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + u8 rxbit = bits - 1; + u32 oldbit = !(word & 1); + /* clock starts at inactive polarity */ + for (; likely(bits); bits--) { + + /* setup LSB (to slave) on trailing edge */ + if ((flags & SPI_CONTROLLER_NO_TX) == 0) { + if ((word & 1) != oldbit) { + setmosi(spi, word & 1); + oldbit = word & 1; + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample LSB (from slave) on leading edge */ + word >>= 1; + if ((flags & SPI_CONTROLLER_NO_RX) == 0) + word |= getmiso(spi) << rxbit; + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_le_cpha1(struct spi_device *spi, + unsigned int nsecs, unsigned int cpol, unsigned int flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + u8 rxbit = bits - 1; + u32 oldbit = !(word & 1); + /* clock starts at inactive polarity */ + for (; likely(bits); bits--) { + + /* setup LSB (to slave) on leading edge */ + setsck(spi, !cpol); + if ((flags & SPI_CONTROLLER_NO_TX) == 0) { + if ((word & 1) != oldbit) { + setmosi(spi, word & 1); + oldbit = word & 1; + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample LSB (from slave) on trailing edge */ + word >>= 1; + if ((flags & SPI_CONTROLLER_NO_RX) == 0) + word |= getmiso(spi) << rxbit; + } + return word; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_i2c_bus_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_i2c_bus_device.c new file mode 100644 index 0000000000..bf99e5478f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_i2c_bus_device.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +/* CPLD-I2C-MASTER-1 */ +static fpga_i2c_bus_device_t cpld_i2c_bus_device_data0 = { + .adap_nr = 445, + .i2c_timeout = 3000, + .i2c_scale = 0x00, + .i2c_filter = 0x04, + .i2c_stretch = 0x08, + .i2c_ext_9548_exits_flag = 0x0c, + .i2c_ext_9548_addr = 0x10, + .i2c_ext_9548_chan = 0x14, + .i2c_in_9548_chan = 0x18, + .i2c_slave = 0x1c, + .i2c_reg = 0x20, + .i2c_reg_len = 0x30, + .i2c_data_len = 0x34, + .i2c_ctrl = 0x38, + .i2c_status = 0x3c, + .i2c_err_vec = 0x48, + .i2c_data_buf = 0x100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/cpld10", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 5, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static void wb_fpga_i2c_bus_device_release(struct device *dev) +{ + return; +} + +static struct platform_device fpga_i2c_bus_device[] = { + { + .name = "wb-fpga-i2c", + .id = 45, + .dev = { + .platform_data = &cpld_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, +}; + +static int __init wb_fpga_i2c_bus_device_init(void) +{ + int i; + int ret = 0; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_i2c_bus_device); i++) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + ret = platform_device_register(&fpga_i2c_bus_device[i]); + if (ret < 0) { + fpga_i2c_bus_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-fpga-i2c.%d register failed!\n", i + 1); + } else { + fpga_i2c_bus_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_fpga_i2c_bus_device_exit(void) +{ + int i; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_i2c_bus_device) - 1; i >= 0; i--) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + if (fpga_i2c_bus_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&fpga_i2c_bus_device[i]); + } + } +} + +module_init(wb_fpga_i2c_bus_device_init); +module_exit(wb_fpga_i2c_bus_device_exit); +MODULE_DESCRIPTION("FPGA I2C Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_pca954x_device.c new file mode 100644 index 0000000000..534d3ebd01 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_cpld_pca954x_device.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define FPGA_INTERNAL_PCA9548 (1) +#define FPGA_EXTERNAL_PCA9548 (2) + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static fpga_pca954x_device_t fpga_pca954x_device_data0 = { + .i2c_bus = 445, + .i2c_addr = 0x70, + .pca9548_base_nr = 329, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +struct i2c_board_info fpga_pca954x_device_info[] = { + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data0,}, +}; + +static int __init wb_fpga_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_pca954x_device_info); i++) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + fpga_pca954x_device_info[i].addr = fpga_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(fpga_pca954x_device_data->i2c_bus); + if (adap == NULL) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", fpga_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); + if (IS_ERR(client)) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", + fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); + } else { + fpga_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_fpga_pca954x_device_exit(void) +{ + int i; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_pca954x_device_info) - 1; i >= 0; i--) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + if (fpga_pca954x_device_data->client) { + i2c_unregister_device(fpga_pca954x_device_data->client); + fpga_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_fpga_pca954x_device_init); +module_exit(wb_fpga_pca954x_device_exit); +MODULE_DESCRIPTION("FPGA PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 0000000000..1841453619 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,816 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_NUM (256) /* GPIO number */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) +#define GPIO_OFFSET (GPIO_DYNAMIC_BASE) /* Formula of gpio base number in Kernel */ +#else +#define GPIO_OFFSET (ARCH_NR_GPIOS - GPIO_NUM) /* Formula of gpio base number in Kernel */ +#endif + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +/* cpu cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 1, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x1, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 2, +}; + +/* mgmt cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 2, + .chip_index = 1, + .en_gpio[0] = 91 + GPIO_OFFSET, + .en_level[0] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_gpio_num = 1, + .en_logic_num = 0, +}; + +/* mac cpld a/b */ +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 3, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x44, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xba, + .en_logic_dis_val[2] = 0xbb, + .en_logic_width[2] = 0x1, + + .en_logic_dev[3] = "/dev/cpld1", + .en_logic_addr[3] = 0x4d, + .en_logic_mask[3] = 0, + .en_logic_en_val[3] = 0xb2, + .en_logic_dis_val[3] = 0xb3, + .en_logic_width[3] = 0x1, + + .en_logic_dev[4] = "/dev/cpld4", + .en_logic_addr[4] = 0x53, + .en_logic_mask[4] = 0, + .en_logic_en_val[4] = 0xad, + .en_logic_dis_val[4] = 0xac, + .en_logic_width[4] = 0x1, + + .en_logic_dev[5] = "/dev/cpld4", + .en_logic_addr[5] = 0x54, + .en_logic_mask[5] = 0, + .en_logic_en_val[5] = 0x1, + .en_logic_dis_val[5] = 0x0, + .en_logic_width[5] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 6, +}; + +/* mac cpld c */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 4, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x43, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xbc, + .en_logic_dis_val[2] = 0xbd, + .en_logic_width[2] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 3, +}; + +/* uport cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data4 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 5, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x47, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xb8, + .en_logic_dis_val[2] = 0xb9, + .en_logic_width[2] = 0x1, + + .en_logic_dev[3] = "/dev/cpld1", + .en_logic_addr[3] = 0x4d, + .en_logic_mask[3] = 0, + .en_logic_en_val[3] = 0xb2, + .en_logic_dis_val[3] = 0xb3, + .en_logic_width[3] = 0x1, + + .en_logic_dev[4] = "/dev/cpld4", + .en_logic_addr[4] = 0x53, + .en_logic_mask[4] = 0, + .en_logic_en_val[4] = 0xad, + .en_logic_dis_val[4] = 0xac, + .en_logic_width[4] = 0x1, + + .en_logic_dev[5] = "/dev/cpld4", + .en_logic_addr[5] = 0x54, + .en_logic_mask[5] = 0, + .en_logic_en_val[5] = 0x6, + .en_logic_dis_val[5] = 0x0, + .en_logic_width[5] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 6, +}; + +/* dport cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data5 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 6, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x49, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xb6, + .en_logic_dis_val[2] = 0xb7, + .en_logic_width[2] = 0x1, + + .en_logic_dev[3] = "/dev/cpld1", + .en_logic_addr[3] = 0x4d, + .en_logic_mask[3] = 0, + .en_logic_en_val[3] = 0xb2, + .en_logic_dis_val[3] = 0xb3, + .en_logic_width[3] = 0x1, + + .en_logic_dev[4] = "/dev/cpld4", + .en_logic_addr[4] = 0x53, + .en_logic_mask[4] = 0, + .en_logic_en_val[4] = 0xad, + .en_logic_dis_val[4] = 0xac, + .en_logic_width[4] = 0x1, + + .en_logic_dev[5] = "/dev/cpld4", + .en_logic_addr[5] = 0x54, + .en_logic_mask[5] = 0, + .en_logic_en_val[5] = 0x8, + .en_logic_dis_val[5] = 0x0, + .en_logic_width[5] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 6, +}; + +/* ufan cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data6 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 7, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x4a, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xb4, + .en_logic_dis_val[2] = 0xb5, + .en_logic_width[2] = 0x1, + + .en_logic_dev[3] = "/dev/cpld1", + .en_logic_addr[3] = 0x4d, + .en_logic_mask[3] = 0, + .en_logic_en_val[3] = 0xb2, + .en_logic_dis_val[3] = 0xb3, + .en_logic_width[3] = 0x1, + + .en_logic_dev[4] = "/dev/cpld4", + .en_logic_addr[4] = 0x53, + .en_logic_mask[4] = 0, + .en_logic_en_val[4] = 0xad, + .en_logic_dis_val[4] = 0xac, + .en_logic_width[4] = 0x1, + + .en_logic_dev[5] = "/dev/cpld4", + .en_logic_addr[5] = 0x54, + .en_logic_mask[5] = 0, + .en_logic_en_val[5] = 0x4, + .en_logic_dis_val[5] = 0x0, + .en_logic_width[5] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 6, +}; + +/* dfan cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data7 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 8, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x4b, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xb4, + .en_logic_dis_val[2] = 0xb5, + .en_logic_width[2] = 0x1, + + .en_logic_dev[3] = "/dev/cpld1", + .en_logic_addr[3] = 0x4d, + .en_logic_mask[3] = 0, + .en_logic_en_val[3] = 0xb2, + .en_logic_dis_val[3] = 0xb3, + .en_logic_width[3] = 0x1, + + .en_logic_dev[4] = "/dev/cpld4", + .en_logic_addr[4] = 0x53, + .en_logic_mask[4] = 0, + .en_logic_en_val[4] = 0xad, + .en_logic_dis_val[4] = 0xac, + .en_logic_width[4] = 0x1, + + .en_logic_dev[5] = "/dev/cpld4", + .en_logic_addr[5] = 0x54, + .en_logic_mask[5] = 0, + .en_logic_en_val[5] = 0x5, + .en_logic_dis_val[5] = 0x0, + .en_logic_width[5] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 6, +}; + +/* mac cpldd */ +static firmware_upgrade_device_t firmware_upgrade_device_data8 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 9, + .chip_index = 1, + .en_gpio[0] = 84 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 85 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x2, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x4d, + .en_logic_mask[2] = 0, + .en_logic_en_val[2] = 0xb2, + .en_logic_dis_val[2] = 0xb3, + .en_logic_width[2] = 0x1, + + .en_logic_dev[3] = "/dev/cpld4", + .en_logic_addr[3] = 0x53, + .en_logic_mask[3] = 0, + .en_logic_en_val[3] = 0xad, + .en_logic_dis_val[3] = 0xac, + .en_logic_width[3] = 0x1, + + .en_logic_dev[4] = "/dev/cpld4", + .en_logic_addr[4] = 0x54, + .en_logic_mask[4] = 0, + .en_logic_en_val[4] = 0xa, + .en_logic_dis_val[4] = 0x0, + .en_logic_width[4] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 5, +}; + +/* mac fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data9 = { + .type = "SPI_LOGIC", + .chain = 1, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x2f0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* mac fpga shaopian */ +static firmware_upgrade_device_t firmware_upgrade_device_data10 = { + .type = "SPI_LOGIC", + .chain = 2, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* uport fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data11 = { + .type = "SPI_LOGIC", + .chain = 3, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga1", + .ctrl_base = 0xa00, + .flash_base = 0x2f0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* uport fpga shaopian */ +static firmware_upgrade_device_t firmware_upgrade_device_data12 = { + .type = "SPI_LOGIC", + .chain = 4, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga1", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* dport fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data13 = { + .type = "SPI_LOGIC", + .chain = 5, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga2", + .ctrl_base = 0xa00, + .flash_base = 0x2f0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* dport fpga shaopian */ +static firmware_upgrade_device_t firmware_upgrade_device_data14 = { + .type = "SPI_LOGIC", + .chain = 6, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga2", + .ctrl_base = 0xa00, + .flash_base = 0x0, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* bcm53134 */ +static firmware_upgrade_device_t firmware_upgrade_device_data15 = { + .type = "SYSFS", + .chain = 8, + .chip_index = 1, + .upg_type.sysfs = { + .sysfs_name = "/sys/bus/spi/devices/spi0.0/eeprom", + }, + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0x54, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x1, + .en_logic_dis_val[0] = 0x0, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0x55, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x5, + .en_logic_dis_val[1] = 0x0, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0x4c, + .en_logic_mask[2] = 0x00, + .en_logic_en_val[2] = 0xb2, + .en_logic_dis_val[2] = 0xb3, + .en_logic_width[2] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 3, +}; + +/* MAC-PCIE */ +static firmware_upgrade_device_t firmware_upgrade_device_data16 = { + .type = "MTD_DEV", + .chain = 9, + .chip_index = 1, + .upg_type.sysfs = { + .mtd_name = "spi0.0", + .flash_base = 0, + }, + + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 5, + .dev = { + .platform_data = &firmware_upgrade_device_data4, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 6, + .dev = { + .platform_data = &firmware_upgrade_device_data5, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 7, + .dev = { + .platform_data = &firmware_upgrade_device_data6, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 8, + .dev = { + .platform_data = &firmware_upgrade_device_data7, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 9, + .dev = { + .platform_data = &firmware_upgrade_device_data8, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 10, + .dev = { + .platform_data = &firmware_upgrade_device_data9, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 11, + .dev = { + .platform_data = &firmware_upgrade_device_data10, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 12, + .dev = { + .platform_data = &firmware_upgrade_device_data11, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 13, + .dev = { + .platform_data = &firmware_upgrade_device_data12, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 14, + .dev = { + .platform_data = &firmware_upgrade_device_data13, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 15, + .dev = { + .platform_data = &firmware_upgrade_device_data14, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 16, + .dev = { + .platform_data = &firmware_upgrade_device_data15, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 17, + .dev = { + .platform_data = &firmware_upgrade_device_data16, + .release = firmware_device_release, + }, + }, +}; + +static int __init firmware_upgrade_device_init(void) +{ + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit firmware_upgrade_device_exit(void) +{ + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&firmware_upgrade_device[i]); + } + } +} + +module_init(firmware_upgrade_device_init); +module_exit(firmware_upgrade_device_exit); +MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_i2c_bus_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_i2c_bus_device.c new file mode 100644 index 0000000000..d036db8abc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_i2c_bus_device.c @@ -0,0 +1,1840 @@ +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +/* mac fpga i2c master */ +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data0 = { + .adap_nr = 401, + .i2c_timeout = 3000, + .i2c_scale = 0x2000, + .i2c_filter = 0x2004, + .i2c_stretch = 0x2008, + .i2c_ext_9548_exits_flag = 0x200c, + .i2c_ext_9548_addr = 0x2010, + .i2c_ext_9548_chan = 0x2014, + .i2c_in_9548_chan = 0x2018, + .i2c_slave = 0x201c, + .i2c_reg = 0x2020, + .i2c_reg_len = 0x2030, + .i2c_data_len = 0x2034, + .i2c_ctrl = 0x2038, + .i2c_status = 0x203c, + .i2c_err_vec = 0x2048, + .i2c_data_buf = 0x2100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x207c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data1 = { + .adap_nr = 402, + .i2c_timeout = 3000, + .i2c_scale = 0x2200, + .i2c_filter = 0x2204, + .i2c_stretch = 0x2208, + .i2c_ext_9548_exits_flag = 0x220c, + .i2c_ext_9548_addr = 0x2210, + .i2c_ext_9548_chan = 0x2214, + .i2c_in_9548_chan = 0x2218, + .i2c_slave = 0x221c, + .i2c_reg = 0x2220, + .i2c_reg_len = 0x2230, + .i2c_data_len = 0x2234, + .i2c_ctrl = 0x2238, + .i2c_status = 0x223c, + .i2c_err_vec = 0x2248, + .i2c_data_buf = 0x2300, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x227c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data2 = { + .adap_nr = 403, + .i2c_timeout = 3000, + .i2c_scale = 0x2400, + .i2c_filter = 0x2404, + .i2c_stretch = 0x2408, + .i2c_ext_9548_exits_flag = 0x240c, + .i2c_ext_9548_addr = 0x2410, + .i2c_ext_9548_chan = 0x2414, + .i2c_in_9548_chan = 0x2418, + .i2c_slave = 0x241c, + .i2c_reg = 0x2420, + .i2c_reg_len = 0x2430, + .i2c_data_len = 0x2434, + .i2c_ctrl = 0x2438, + .i2c_status = 0x243c, + .i2c_err_vec = 0x2448, + .i2c_data_buf = 0x2500, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x247c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data3 = { + .adap_nr = 404, + .i2c_timeout = 3000, + .i2c_scale = 0x2600, + .i2c_filter = 0x2604, + .i2c_stretch = 0x2608, + .i2c_ext_9548_exits_flag = 0x260c, + .i2c_ext_9548_addr = 0x2610, + .i2c_ext_9548_chan = 0x2614, + .i2c_in_9548_chan = 0x2618, + .i2c_slave = 0x261c, + .i2c_reg = 0x2620, + .i2c_reg_len = 0x2630, + .i2c_data_len = 0x2634, + .i2c_ctrl = 0x2638, + .i2c_status = 0x263c, + .i2c_err_vec = 0x2648, + .i2c_data_buf = 0x2700, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x267c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data4 = { + .adap_nr = 405, + .i2c_timeout = 3000, + .i2c_scale = 0x2800, + .i2c_filter = 0x2804, + .i2c_stretch = 0x2808, + .i2c_ext_9548_exits_flag = 0x280c, + .i2c_ext_9548_addr = 0x2810, + .i2c_ext_9548_chan = 0x2814, + .i2c_in_9548_chan = 0x2818, + .i2c_slave = 0x281c, + .i2c_reg = 0x2820, + .i2c_reg_len = 0x2830, + .i2c_data_len = 0x2834, + .i2c_ctrl = 0x2838, + .i2c_status = 0x283c, + .i2c_err_vec = 0x2848, + .i2c_data_buf = 0x2900, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x287c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data5 = { + .adap_nr = 406, + .i2c_timeout = 3000, + .i2c_scale = 0x2a00, + .i2c_filter = 0x2a04, + .i2c_stretch = 0x2a08, + .i2c_ext_9548_exits_flag = 0x2a0c, + .i2c_ext_9548_addr = 0x2a10, + .i2c_ext_9548_chan = 0x2a14, + .i2c_in_9548_chan = 0x2a18, + .i2c_slave = 0x2a1c, + .i2c_reg = 0x2a20, + .i2c_reg_len = 0x2a30, + .i2c_data_len = 0x2a34, + .i2c_ctrl = 0x2a38, + .i2c_status = 0x2a3c, + .i2c_err_vec = 0x2a48, + .i2c_data_buf = 0x2b00, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x2a7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data6 = { + .adap_nr = 407, + .i2c_timeout = 3000, + .i2c_scale = 0x2c00, + .i2c_filter = 0x2c04, + .i2c_stretch = 0x2c08, + .i2c_ext_9548_exits_flag = 0x2c0c, + .i2c_ext_9548_addr = 0x2c10, + .i2c_ext_9548_chan = 0x2c14, + .i2c_in_9548_chan = 0x2c18, + .i2c_slave = 0x2c1c, + .i2c_reg = 0x2c20, + .i2c_reg_len = 0x2c30, + .i2c_data_len = 0x2c34, + .i2c_ctrl = 0x2c38, + .i2c_status = 0x2c3c, + .i2c_err_vec = 0x2c48, + .i2c_data_buf = 0x2d00, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x2c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data7 = { + .adap_nr = 408, + .i2c_timeout = 3000, + .i2c_scale = 0x2e00, + .i2c_filter = 0x2e04, + .i2c_stretch = 0x2e08, + .i2c_ext_9548_exits_flag = 0x2e0c, + .i2c_ext_9548_addr = 0x2e10, + .i2c_ext_9548_chan = 0x2e14, + .i2c_in_9548_chan = 0x2e18, + .i2c_slave = 0x2e1c, + .i2c_reg = 0x2e20, + .i2c_reg_len = 0x2e30, + .i2c_data_len = 0x2e34, + .i2c_ctrl = 0x2e38, + .i2c_status = 0x2e3c, + .i2c_err_vec = 0x2e48, + .i2c_data_buf = 0x2f00, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x2e7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data8= { + .adap_nr = 409, + .i2c_timeout = 3000, + .i2c_scale = 0x3000, + .i2c_filter = 0x3004, + .i2c_stretch = 0x3008, + .i2c_ext_9548_exits_flag = 0x300c, + .i2c_ext_9548_addr = 0x3010, + .i2c_ext_9548_chan = 0x3014, + .i2c_in_9548_chan = 0x3018, + .i2c_slave = 0x301c, + .i2c_reg = 0x3020, + .i2c_reg_len = 0x3030, + .i2c_data_len = 0x3034, + .i2c_ctrl = 0x3038, + .i2c_status = 0x303c, + .i2c_err_vec = 0x3048, + .i2c_data_buf = 0x3100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x307c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data9 = { + .adap_nr = 410, + .i2c_timeout = 3000, + .i2c_scale = 0x3200, + .i2c_filter = 0x3204, + .i2c_stretch = 0x3208, + .i2c_ext_9548_exits_flag = 0x320c, + .i2c_ext_9548_addr = 0x3210, + .i2c_ext_9548_chan = 0x3214, + .i2c_in_9548_chan = 0x3218, + .i2c_slave = 0x321c, + .i2c_reg = 0x3220, + .i2c_reg_len = 0x3230, + .i2c_data_len = 0x3234, + .i2c_ctrl = 0x3238, + .i2c_status = 0x323c, + .i2c_err_vec = 0x3248, + .i2c_data_buf = 0x3300, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x327c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data0 = { + .adap_nr = 411, + .i2c_timeout = 3000, + .i2c_scale = 0x4000, + .i2c_filter = 0x4004, + .i2c_stretch = 0x4008, + .i2c_ext_9548_exits_flag = 0x400c, + .i2c_ext_9548_addr = 0x4010, + .i2c_ext_9548_chan = 0x4014, + .i2c_in_9548_chan = 0x4018, + .i2c_slave = 0x401c, + .i2c_reg = 0x4020, + .i2c_reg_len = 0x4030, + .i2c_data_len = 0x4034, + .i2c_ctrl = 0x4038, + .i2c_status = 0x403c, + .i2c_err_vec = 0x4048, + .i2c_data_buf = 0x4100, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x407c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data1 = { + .adap_nr = 412, + .i2c_timeout = 3000, + .i2c_scale = 0x4200, + .i2c_filter = 0x4204, + .i2c_stretch = 0x4208, + .i2c_ext_9548_exits_flag = 0x420c, + .i2c_ext_9548_addr = 0x4210, + .i2c_ext_9548_chan = 0x4214, + .i2c_in_9548_chan = 0x4218, + .i2c_slave = 0x421c, + .i2c_reg = 0x4220, + .i2c_reg_len = 0x4230, + .i2c_data_len = 0x4234, + .i2c_ctrl = 0x4238, + .i2c_status = 0x423c, + .i2c_err_vec = 0x4248, + .i2c_data_buf = 0x4300, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x427c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data2 = { + .adap_nr = 413, + .i2c_timeout = 3000, + .i2c_scale = 0x4400, + .i2c_filter = 0x4404, + .i2c_stretch = 0x4408, + .i2c_ext_9548_exits_flag = 0x440c, + .i2c_ext_9548_addr = 0x4410, + .i2c_ext_9548_chan = 0x4414, + .i2c_in_9548_chan = 0x4418, + .i2c_slave = 0x441c, + .i2c_reg = 0x4420, + .i2c_reg_len = 0x4430, + .i2c_data_len = 0x4434, + .i2c_ctrl = 0x4438, + .i2c_status = 0x443c, + .i2c_err_vec = 0x4448, + .i2c_data_buf = 0x4500, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x447c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data3 = { + .adap_nr = 414, + .i2c_timeout = 3000, + .i2c_scale = 0x4600, + .i2c_filter = 0x4604, + .i2c_stretch = 0x4608, + .i2c_ext_9548_exits_flag = 0x460c, + .i2c_ext_9548_addr = 0x4610, + .i2c_ext_9548_chan = 0x4614, + .i2c_in_9548_chan = 0x4618, + .i2c_slave = 0x461c, + .i2c_reg = 0x4620, + .i2c_reg_len = 0x4630, + .i2c_data_len = 0x4634, + .i2c_ctrl = 0x4638, + .i2c_status = 0x463c, + .i2c_err_vec = 0x4648, + .i2c_data_buf = 0x4700, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x467c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data4 = { + .adap_nr = 415, + .i2c_timeout = 3000, + .i2c_scale = 0x4800, + .i2c_filter = 0x4804, + .i2c_stretch = 0x4808, + .i2c_ext_9548_exits_flag = 0x480c, + .i2c_ext_9548_addr = 0x4810, + .i2c_ext_9548_chan = 0x4814, + .i2c_in_9548_chan = 0x4818, + .i2c_slave = 0x481c, + .i2c_reg = 0x4820, + .i2c_reg_len = 0x4830, + .i2c_data_len = 0x4834, + .i2c_ctrl = 0x4838, + .i2c_status = 0x483c, + .i2c_err_vec = 0x4848, + .i2c_data_buf = 0x4900, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x487c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data5 = { + .adap_nr = 416, + .i2c_timeout = 3000, + .i2c_scale = 0x4a00, + .i2c_filter = 0x4a04, + .i2c_stretch = 0x4a08, + .i2c_ext_9548_exits_flag = 0x4a0c, + .i2c_ext_9548_addr = 0x4a10, + .i2c_ext_9548_chan = 0x4a14, + .i2c_in_9548_chan = 0x4a18, + .i2c_slave = 0x4a1c, + .i2c_reg = 0x4a20, + .i2c_reg_len = 0x4a30, + .i2c_data_len = 0x4a34, + .i2c_ctrl = 0x4a38, + .i2c_status = 0x4a3c, + .i2c_err_vec = 0x4a48, + .i2c_data_buf = 0x4b00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4a7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data6 = { + .adap_nr = 417, + .i2c_timeout = 3000, + .i2c_scale = 0x4c00, + .i2c_filter = 0x4c04, + .i2c_stretch = 0x4c08, + .i2c_ext_9548_exits_flag = 0x4c0c, + .i2c_ext_9548_addr = 0x4c10, + .i2c_ext_9548_chan = 0x4c14, + .i2c_in_9548_chan = 0x4c18, + .i2c_slave = 0x4c1c, + .i2c_reg = 0x4c20, + .i2c_reg_len = 0x4c30, + .i2c_data_len = 0x4c34, + .i2c_ctrl = 0x4c38, + .i2c_status = 0x4c3c, + .i2c_err_vec = 0x4c48, + .i2c_data_buf = 0x4d00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data7 = { + .adap_nr = 418, + .i2c_timeout = 3000, + .i2c_scale = 0x4e00, + .i2c_filter = 0x4e04, + .i2c_stretch = 0x4e08, + .i2c_ext_9548_exits_flag = 0x4e0c, + .i2c_ext_9548_addr = 0x4e10, + .i2c_ext_9548_chan = 0x4e14, + .i2c_in_9548_chan = 0x4e18, + .i2c_slave = 0x4e1c, + .i2c_reg = 0x4e20, + .i2c_reg_len = 0x4e30, + .i2c_data_len = 0x4e34, + .i2c_ctrl = 0x4e38, + .i2c_status = 0x4e3c, + .i2c_err_vec = 0x4e48, + .i2c_data_buf = 0x4f00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4e7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data8 = { + .adap_nr = 419, + .i2c_timeout = 3000, + .i2c_scale = 0x5000, + .i2c_filter = 0x5004, + .i2c_stretch = 0x5008, + .i2c_ext_9548_exits_flag = 0x500c, + .i2c_ext_9548_addr = 0x5010, + .i2c_ext_9548_chan = 0x5014, + .i2c_in_9548_chan = 0x5018, + .i2c_slave = 0x501c, + .i2c_reg = 0x5020, + .i2c_reg_len = 0x5030, + .i2c_data_len = 0x5034, + .i2c_ctrl = 0x5038, + .i2c_status = 0x503c, + .i2c_err_vec = 0x5048, + .i2c_data_buf = 0x5100, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x507c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data9 = { + .adap_nr = 420, + .i2c_timeout = 3000, + .i2c_scale = 0x5200, + .i2c_filter = 0x5204, + .i2c_stretch = 0x5208, + .i2c_ext_9548_exits_flag = 0x520c, + .i2c_ext_9548_addr = 0x5210, + .i2c_ext_9548_chan = 0x5214, + .i2c_in_9548_chan = 0x5218, + .i2c_slave = 0x521c, + .i2c_reg = 0x5220, + .i2c_reg_len = 0x5230, + .i2c_data_len = 0x5234, + .i2c_ctrl = 0x5238, + .i2c_status = 0x523c, + .i2c_err_vec = 0x5248, + .i2c_data_buf = 0x5300, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x527c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data10 = { + .adap_nr = 421, + .i2c_timeout = 3000, + .i2c_scale = 0x5400, + .i2c_filter = 0x5404, + .i2c_stretch = 0x5408, + .i2c_ext_9548_exits_flag = 0x540c, + .i2c_ext_9548_addr = 0x5410, + .i2c_ext_9548_chan = 0x5414, + .i2c_in_9548_chan = 0x5418, + .i2c_slave = 0x541c, + .i2c_reg = 0x5420, + .i2c_reg_len = 0x5430, + .i2c_data_len = 0x5434, + .i2c_ctrl = 0x5438, + .i2c_status = 0x543c, + .i2c_err_vec = 0x5448, + .i2c_data_buf = 0x5500, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x547c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data11 = { + .adap_nr = 422, + .i2c_timeout = 3000, + .i2c_scale = 0x5600, + .i2c_filter = 0x5604, + .i2c_stretch = 0x5608, + .i2c_ext_9548_exits_flag = 0x560c, + .i2c_ext_9548_addr = 0x5610, + .i2c_ext_9548_chan = 0x5614, + .i2c_in_9548_chan = 0x5618, + .i2c_slave = 0x561c, + .i2c_reg = 0x5620, + .i2c_reg_len = 0x5630, + .i2c_data_len = 0x5634, + .i2c_ctrl = 0x5638, + .i2c_status = 0x563c, + .i2c_err_vec = 0x5648, + .i2c_data_buf = 0x5700, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x567c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data12 = { + .adap_nr = 423, + .i2c_timeout = 3000, + .i2c_scale = 0x5800, + .i2c_filter = 0x5804, + .i2c_stretch = 0x5808, + .i2c_ext_9548_exits_flag = 0x580c, + .i2c_ext_9548_addr = 0x5810, + .i2c_ext_9548_chan = 0x5814, + .i2c_in_9548_chan = 0x5818, + .i2c_slave = 0x581c, + .i2c_reg = 0x5820, + .i2c_reg_len = 0x5830, + .i2c_data_len = 0x5834, + .i2c_ctrl = 0x5838, + .i2c_status = 0x583c, + .i2c_err_vec = 0x5848, + .i2c_data_buf = 0x5900, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x587c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data13 = { + .adap_nr = 424, + .i2c_timeout = 3000, + .i2c_scale = 0x5a00, + .i2c_filter = 0x5a04, + .i2c_stretch = 0x5a08, + .i2c_ext_9548_exits_flag = 0x5a0c, + .i2c_ext_9548_addr = 0x5a10, + .i2c_ext_9548_chan = 0x5a14, + .i2c_in_9548_chan = 0x5a18, + .i2c_slave = 0x5a1c, + .i2c_reg = 0x5a20, + .i2c_reg_len = 0x5a30, + .i2c_data_len = 0x5a34, + .i2c_ctrl = 0x5a38, + .i2c_status = 0x5a3c, + .i2c_err_vec = 0x5a48, + .i2c_data_buf = 0x5b00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x5a7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data14 = { + .adap_nr = 425, + .i2c_timeout = 3000, + .i2c_scale = 0x5c00, + .i2c_filter = 0x5c04, + .i2c_stretch = 0x5c08, + .i2c_ext_9548_exits_flag = 0x5c0c, + .i2c_ext_9548_addr = 0x5c10, + .i2c_ext_9548_chan = 0x5c14, + .i2c_in_9548_chan = 0x5c18, + .i2c_slave = 0x5c1c, + .i2c_reg = 0x5c20, + .i2c_reg_len = 0x5c30, + .i2c_data_len = 0x5c34, + .i2c_ctrl = 0x5c38, + .i2c_status = 0x5c3c, + .i2c_err_vec = 0x5c48, + .i2c_data_buf = 0x5d00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x5c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data15 = { + .adap_nr = 426, + .i2c_timeout = 3000, + .i2c_scale = 0x5e00, + .i2c_filter = 0x5e04, + .i2c_stretch = 0x5e08, + .i2c_ext_9548_exits_flag = 0x5e0c, + .i2c_ext_9548_addr = 0x5e10, + .i2c_ext_9548_chan = 0x5e14, + .i2c_in_9548_chan = 0x5e18, + .i2c_slave = 0x5e1c, + .i2c_reg = 0x5e20, + .i2c_reg_len = 0x5e30, + .i2c_data_len = 0x5e34, + .i2c_ctrl = 0x5e38, + .i2c_status = 0x5e3c, + .i2c_err_vec = 0x5e48, + .i2c_data_buf = 0x5f00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x5e7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +/* uport fpga i2c master */ +static fpga_i2c_bus_device_t fpga1_i2c_bus_device_data0 = { + .adap_nr = 427, + .i2c_timeout = 3000, + .i2c_scale = 0x2000, + .i2c_filter = 0x2004, + .i2c_stretch = 0x2008, + .i2c_ext_9548_exits_flag = 0x200c, + .i2c_ext_9548_addr = 0x2010, + .i2c_ext_9548_chan = 0x2014, + .i2c_in_9548_chan = 0x2018, + .i2c_slave = 0x201c, + .i2c_reg = 0x2020, + .i2c_reg_len = 0x2030, + .i2c_data_len = 0x2034, + .i2c_ctrl = 0x2038, + .i2c_status = 0x203c, + .i2c_err_vec = 0x2048, + .i2c_data_buf = 0x2100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x207c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data0 = { + .adap_nr = 428, + .i2c_timeout = 3000, + .i2c_scale = 0x4000, + .i2c_filter = 0x4004, + .i2c_stretch = 0x4008, + .i2c_ext_9548_exits_flag = 0x400c, + .i2c_ext_9548_addr = 0x4010, + .i2c_ext_9548_chan = 0x4014, + .i2c_in_9548_chan = 0x4018, + .i2c_slave = 0x401c, + .i2c_reg = 0x4020, + .i2c_reg_len = 0x4030, + .i2c_data_len = 0x4034, + .i2c_ctrl = 0x4038, + .i2c_status = 0x403c, + .i2c_err_vec = 0x4048, + .i2c_data_buf = 0x4100, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x407c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data1 = { + .adap_nr = 429, + .i2c_timeout = 3000, + .i2c_scale = 0x4200, + .i2c_filter = 0x4204, + .i2c_stretch = 0x4208, + .i2c_ext_9548_exits_flag = 0x420c, + .i2c_ext_9548_addr = 0x4210, + .i2c_ext_9548_chan = 0x4214, + .i2c_in_9548_chan = 0x4218, + .i2c_slave = 0x421c, + .i2c_reg = 0x4220, + .i2c_reg_len = 0x4230, + .i2c_data_len = 0x4234, + .i2c_ctrl = 0x4238, + .i2c_status = 0x423c, + .i2c_err_vec = 0x4248, + .i2c_data_buf = 0x4300, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x427c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data2 = { + .adap_nr = 430, + .i2c_timeout = 3000, + .i2c_scale = 0x4400, + .i2c_filter = 0x4404, + .i2c_stretch = 0x4408, + .i2c_ext_9548_exits_flag = 0x440c, + .i2c_ext_9548_addr = 0x4410, + .i2c_ext_9548_chan = 0x4414, + .i2c_in_9548_chan = 0x4418, + .i2c_slave = 0x441c, + .i2c_reg = 0x4420, + .i2c_reg_len = 0x4430, + .i2c_data_len = 0x4434, + .i2c_ctrl = 0x4438, + .i2c_status = 0x443c, + .i2c_err_vec = 0x4448, + .i2c_data_buf = 0x4500, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x447c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data3 = { + .adap_nr = 431, + .i2c_timeout = 3000, + .i2c_scale = 0x4600, + .i2c_filter = 0x4604, + .i2c_stretch = 0x4608, + .i2c_ext_9548_exits_flag = 0x460c, + .i2c_ext_9548_addr = 0x4610, + .i2c_ext_9548_chan = 0x4614, + .i2c_in_9548_chan = 0x4618, + .i2c_slave = 0x461c, + .i2c_reg = 0x4620, + .i2c_reg_len = 0x4630, + .i2c_data_len = 0x4634, + .i2c_ctrl = 0x4638, + .i2c_status = 0x463c, + .i2c_err_vec = 0x4648, + .i2c_data_buf = 0x4700, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x467c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data4 = { + .adap_nr = 432, + .i2c_timeout = 3000, + .i2c_scale = 0x4800, + .i2c_filter = 0x4804, + .i2c_stretch = 0x4808, + .i2c_ext_9548_exits_flag = 0x480c, + .i2c_ext_9548_addr = 0x4810, + .i2c_ext_9548_chan = 0x4814, + .i2c_in_9548_chan = 0x4818, + .i2c_slave = 0x481c, + .i2c_reg = 0x4820, + .i2c_reg_len = 0x4830, + .i2c_data_len = 0x4834, + .i2c_ctrl = 0x4838, + .i2c_status = 0x483c, + .i2c_err_vec = 0x4848, + .i2c_data_buf = 0x4900, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x487c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data5 = { + .adap_nr = 433, + .i2c_timeout = 3000, + .i2c_scale = 0x4a00, + .i2c_filter = 0x4a04, + .i2c_stretch = 0x4a08, + .i2c_ext_9548_exits_flag = 0x4a0c, + .i2c_ext_9548_addr = 0x4a10, + .i2c_ext_9548_chan = 0x4a14, + .i2c_in_9548_chan = 0x4a18, + .i2c_slave = 0x4a1c, + .i2c_reg = 0x4a20, + .i2c_reg_len = 0x4a30, + .i2c_data_len = 0x4a34, + .i2c_ctrl = 0x4a38, + .i2c_status = 0x4a3c, + .i2c_err_vec = 0x4a48, + .i2c_data_buf = 0x4b00, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4a7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data6 = { + .adap_nr = 434, + .i2c_timeout = 3000, + .i2c_scale = 0x4c00, + .i2c_filter = 0x4c04, + .i2c_stretch = 0x4c08, + .i2c_ext_9548_exits_flag = 0x4c0c, + .i2c_ext_9548_addr = 0x4c10, + .i2c_ext_9548_chan = 0x4c14, + .i2c_in_9548_chan = 0x4c18, + .i2c_slave = 0x4c1c, + .i2c_reg = 0x4c20, + .i2c_reg_len = 0x4c30, + .i2c_data_len = 0x4c34, + .i2c_ctrl = 0x4c38, + .i2c_status = 0x4c3c, + .i2c_err_vec = 0x4c48, + .i2c_data_buf = 0x4d00, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data7 = { + .adap_nr = 435, + .i2c_timeout = 3000, + .i2c_scale = 0x4e00, + .i2c_filter = 0x4e04, + .i2c_stretch = 0x4e08, + .i2c_ext_9548_exits_flag = 0x4e0c, + .i2c_ext_9548_addr = 0x4e10, + .i2c_ext_9548_chan = 0x4e14, + .i2c_in_9548_chan = 0x4e18, + .i2c_slave = 0x4e1c, + .i2c_reg = 0x4e20, + .i2c_reg_len = 0x4e30, + .i2c_data_len = 0x4e34, + .i2c_ctrl = 0x4e38, + .i2c_status = 0x4e3c, + .i2c_err_vec = 0x4e48, + .i2c_data_buf = 0x4f00, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4e7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +/* dport fpga i2c master */ +static fpga_i2c_bus_device_t fpga2_i2c_bus_device_data0 = { + .adap_nr = 436, + .i2c_timeout = 3000, + .i2c_scale = 0x2000, + .i2c_filter = 0x2004, + .i2c_stretch = 0x2008, + .i2c_ext_9548_exits_flag = 0x200c, + .i2c_ext_9548_addr = 0x2010, + .i2c_ext_9548_chan = 0x2014, + .i2c_in_9548_chan = 0x2018, + .i2c_slave = 0x201c, + .i2c_reg = 0x2020, + .i2c_reg_len = 0x2030, + .i2c_data_len = 0x2034, + .i2c_ctrl = 0x2038, + .i2c_status = 0x203c, + .i2c_err_vec = 0x2048, + .i2c_data_buf = 0x2100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x207c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data0 = { + .adap_nr = 437, + .i2c_timeout = 3000, + .i2c_scale = 0x4000, + .i2c_filter = 0x4004, + .i2c_stretch = 0x4008, + .i2c_ext_9548_exits_flag = 0x400c, + .i2c_ext_9548_addr = 0x4010, + .i2c_ext_9548_chan = 0x4014, + .i2c_in_9548_chan = 0x4018, + .i2c_slave = 0x401c, + .i2c_reg = 0x4020, + .i2c_reg_len = 0x4030, + .i2c_data_len = 0x4034, + .i2c_ctrl = 0x4038, + .i2c_status = 0x403c, + .i2c_err_vec = 0x4048, + .i2c_data_buf = 0x4100, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x407c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data1 = { + .adap_nr = 438, + .i2c_timeout = 3000, + .i2c_scale = 0x4200, + .i2c_filter = 0x4204, + .i2c_stretch = 0x4208, + .i2c_ext_9548_exits_flag = 0x420c, + .i2c_ext_9548_addr = 0x4210, + .i2c_ext_9548_chan = 0x4214, + .i2c_in_9548_chan = 0x4218, + .i2c_slave = 0x421c, + .i2c_reg = 0x4220, + .i2c_reg_len = 0x4230, + .i2c_data_len = 0x4234, + .i2c_ctrl = 0x4238, + .i2c_status = 0x423c, + .i2c_err_vec = 0x4248, + .i2c_data_buf = 0x4300, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x427c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data2 = { + .adap_nr = 439, + .i2c_timeout = 3000, + .i2c_scale = 0x4400, + .i2c_filter = 0x4404, + .i2c_stretch = 0x4408, + .i2c_ext_9548_exits_flag = 0x440c, + .i2c_ext_9548_addr = 0x4410, + .i2c_ext_9548_chan = 0x4414, + .i2c_in_9548_chan = 0x4418, + .i2c_slave = 0x441c, + .i2c_reg = 0x4420, + .i2c_reg_len = 0x4430, + .i2c_data_len = 0x4434, + .i2c_ctrl = 0x4438, + .i2c_status = 0x443c, + .i2c_err_vec = 0x4448, + .i2c_data_buf = 0x4500, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x447c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data3 = { + .adap_nr = 440, + .i2c_timeout = 3000, + .i2c_scale = 0x4600, + .i2c_filter = 0x4604, + .i2c_stretch = 0x4608, + .i2c_ext_9548_exits_flag = 0x460c, + .i2c_ext_9548_addr = 0x4610, + .i2c_ext_9548_chan = 0x4614, + .i2c_in_9548_chan = 0x4618, + .i2c_slave = 0x461c, + .i2c_reg = 0x4620, + .i2c_reg_len = 0x4630, + .i2c_data_len = 0x4634, + .i2c_ctrl = 0x4638, + .i2c_status = 0x463c, + .i2c_err_vec = 0x4648, + .i2c_data_buf = 0x4700, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x467c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data4 = { + .adap_nr = 441, + .i2c_timeout = 3000, + .i2c_scale = 0x4800, + .i2c_filter = 0x4804, + .i2c_stretch = 0x4808, + .i2c_ext_9548_exits_flag = 0x480c, + .i2c_ext_9548_addr = 0x4810, + .i2c_ext_9548_chan = 0x4814, + .i2c_in_9548_chan = 0x4818, + .i2c_slave = 0x481c, + .i2c_reg = 0x4820, + .i2c_reg_len = 0x4830, + .i2c_data_len = 0x4834, + .i2c_ctrl = 0x4838, + .i2c_status = 0x483c, + .i2c_err_vec = 0x4848, + .i2c_data_buf = 0x4900, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x487c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data5 = { + .adap_nr = 442, + .i2c_timeout = 3000, + .i2c_scale = 0x4a00, + .i2c_filter = 0x4a04, + .i2c_stretch = 0x4a08, + .i2c_ext_9548_exits_flag = 0x4a0c, + .i2c_ext_9548_addr = 0x4a10, + .i2c_ext_9548_chan = 0x4a14, + .i2c_in_9548_chan = 0x4a18, + .i2c_slave = 0x4a1c, + .i2c_reg = 0x4a20, + .i2c_reg_len = 0x4a30, + .i2c_data_len = 0x4a34, + .i2c_ctrl = 0x4a38, + .i2c_status = 0x4a3c, + .i2c_err_vec = 0x4a48, + .i2c_data_buf = 0x4b00, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4a7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data6 = { + .adap_nr = 443, + .i2c_timeout = 3000, + .i2c_scale = 0x4c00, + .i2c_filter = 0x4c04, + .i2c_stretch = 0x4c08, + .i2c_ext_9548_exits_flag = 0x4c0c, + .i2c_ext_9548_addr = 0x4c10, + .i2c_ext_9548_chan = 0x4c14, + .i2c_in_9548_chan = 0x4c18, + .i2c_slave = 0x4c1c, + .i2c_reg = 0x4c20, + .i2c_reg_len = 0x4c30, + .i2c_data_len = 0x4c34, + .i2c_ctrl = 0x4c38, + .i2c_status = 0x4c3c, + .i2c_err_vec = 0x4c48, + .i2c_data_buf = 0x4d00, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga2_dom_i2c_bus_device_data7 = { + .adap_nr = 444, + .i2c_timeout = 3000, + .i2c_scale = 0x4e00, + .i2c_filter = 0x4e04, + .i2c_stretch = 0x4e08, + .i2c_ext_9548_exits_flag = 0x4e0c, + .i2c_ext_9548_addr = 0x4e10, + .i2c_ext_9548_chan = 0x4e14, + .i2c_in_9548_chan = 0x4e18, + .i2c_slave = 0x4e1c, + .i2c_reg = 0x4e20, + .i2c_reg_len = 0x4e30, + .i2c_data_len = 0x4e34, + .i2c_ctrl = 0x4e38, + .i2c_status = 0x4e3c, + .i2c_err_vec = 0x4e48, + .i2c_data_buf = 0x4f00, + .dev_name = "/dev/fpga2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 2, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4e7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static void wb_fpga_i2c_bus_device_release(struct device *dev) +{ + return; +} + +static struct platform_device fpga_i2c_bus_device[] = { + /* fpga0 i2c master */ + { + .name = "wb-fpga-i2c", + .id = 1, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 2, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 3, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 4, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 5, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 6, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 7, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 8, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 9, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data8, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 10, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data9, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + /* fpga0 dom i2c master */ + { + .name = "wb-fpga-i2c", + .id = 11, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 12, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 13, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 14, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 15, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 16, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 17, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 18, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 19, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data8, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 20, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data9, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 21, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data10, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 22, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data11, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 23, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data12, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 24, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data13, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 25, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data14, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 26, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data15, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + /* fpga1 i2c master */ + { + .name = "wb-fpga-i2c", + .id = 27, + .dev = { + .platform_data = &fpga1_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + /* fpga1 dom i2c master */ + { + .name = "wb-fpga-i2c", + .id = 28, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 29, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 30, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 31, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 32, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 33, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 34, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 35, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + /* fpga2 i2c master */ + { + .name = "wb-fpga-i2c", + .id = 36, + .dev = { + .platform_data = &fpga2_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + /* fpga2 dom i2c master */ + { + .name = "wb-fpga-i2c", + .id = 37, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 38, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 39, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 40, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 41, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 42, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 43, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 44, + .dev = { + .platform_data = &fpga2_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, +}; + +static int __init wb_fpga_i2c_bus_device_init(void) +{ + int i; + int ret = 0; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_i2c_bus_device); i++) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + ret = platform_device_register(&fpga_i2c_bus_device[i]); + if (ret < 0) { + fpga_i2c_bus_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-fpga-i2c.%d register failed!\n", i + 1); + } else { + fpga_i2c_bus_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_fpga_i2c_bus_device_exit(void) +{ + int i; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_i2c_bus_device) - 1; i >= 0; i--) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + if (fpga_i2c_bus_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&fpga_i2c_bus_device[i]); + } + } +} + +module_init(wb_fpga_i2c_bus_device_init); +module_exit(wb_fpga_i2c_bus_device_exit); +MODULE_DESCRIPTION("FPGA I2C Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_pca954x_device.c new file mode 100644 index 0000000000..d465cdf9bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_fpga_pca954x_device.c @@ -0,0 +1,564 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define FPGA_INTERNAL_PCA9548 (1) +#define FPGA_EXTERNAL_PCA9548 (2) + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static fpga_pca954x_device_t fpga_pca954x_device_data0 = { + .i2c_bus = 401, + .i2c_addr = 0x70, + .pca9548_base_nr = 451, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data1 = { + .i2c_bus = 451, + .i2c_addr = 0x77, + .pca9548_base_nr = 51, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data2 = { + .i2c_bus = 451, + .i2c_addr = 0x75, + .pca9548_base_nr = 59, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data3 = { + .i2c_bus = 402, + .i2c_addr = 0x70, + .pca9548_base_nr = 452, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data4 = { + .i2c_bus = 452, + .i2c_addr = 0x76, + .pca9548_base_nr = 67, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data5 = { + .i2c_bus = 403, + .i2c_addr = 0x70, + .pca9548_base_nr = 453, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data6 = { + .i2c_bus = 453, + .i2c_addr = 0x77, + .pca9548_base_nr = 75, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data7 = { + .i2c_bus = 404, + .i2c_addr = 0x70, + .pca9548_base_nr = 454, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data8 = { + .i2c_bus = 454, + .i2c_addr = 0x77, + .pca9548_base_nr = 83, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data9 = { + .i2c_bus = 405, + .i2c_addr = 0x70, + .pca9548_base_nr = 455, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data10 = { + .i2c_bus = 455, + .i2c_addr = 0x71, + .pca9548_base_nr = 91, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data11 = { + .i2c_bus = 455, + .i2c_addr = 0x72, + .pca9548_base_nr = 99, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data12 = { + .i2c_bus = 406, + .i2c_addr = 0x70, + .pca9548_base_nr = 456, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data13 = { + .i2c_bus = 456, + .i2c_addr = 0x71, + .pca9548_base_nr = 107, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data14 = { + .i2c_bus = 407, + .i2c_addr = 0x70, + .pca9548_base_nr = 457, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data15 = { + .i2c_bus = 457, + .i2c_addr = 0x72, + .pca9548_base_nr = 115, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data16 = { + .i2c_bus = 408, + .i2c_addr = 0x70, + .pca9548_base_nr = 458, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data17 = { + .i2c_bus = 458, + .i2c_addr = 0x73, + .pca9548_base_nr = 123, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data18 = { + .i2c_bus = 409, + .i2c_addr = 0x70, + .pca9548_base_nr = 459, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data19 = { + .i2c_bus = 459, + .i2c_addr = 0x74, + .pca9548_base_nr = 131, + .fpga_9548_flag = FPGA_EXTERNAL_PCA9548, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data20 = { + .i2c_bus = 410, + .i2c_addr = 0x70, + .pca9548_base_nr = 139, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data21 = { + .i2c_bus = 411, + .i2c_addr = 0x70, + .pca9548_base_nr = 233, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data22 = { + .i2c_bus = 412, + .i2c_addr = 0x70, + .pca9548_base_nr = 237, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data23 = { + .i2c_bus = 413, + .i2c_addr = 0x70, + .pca9548_base_nr = 241, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data24 = { + .i2c_bus = 414, + .i2c_addr = 0x70, + .pca9548_base_nr = 245, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data25 = { + .i2c_bus = 415, + .i2c_addr = 0x70, + .pca9548_base_nr = 249, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data26 = { + .i2c_bus = 416, + .i2c_addr = 0x70, + .pca9548_base_nr = 253, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data27 = { + .i2c_bus = 417, + .i2c_addr = 0x70, + .pca9548_base_nr = 257, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data28 = { + .i2c_bus = 418, + .i2c_addr = 0x70, + .pca9548_base_nr = 261, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data29 = { + .i2c_bus = 419, + .i2c_addr = 0x70, + .pca9548_base_nr = 265, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data30 = { + .i2c_bus = 420, + .i2c_addr = 0x70, + .pca9548_base_nr = 269, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data31 = { + .i2c_bus = 421, + .i2c_addr = 0x70, + .pca9548_base_nr = 273, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data32 = { + .i2c_bus = 422, + .i2c_addr = 0x70, + .pca9548_base_nr = 277, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data33 = { + .i2c_bus = 423, + .i2c_addr = 0x70, + .pca9548_base_nr = 281, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data34 = { + .i2c_bus = 424, + .i2c_addr = 0x70, + .pca9548_base_nr = 285, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data35 = { + .i2c_bus = 425, + .i2c_addr = 0x70, + .pca9548_base_nr = 289, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data36 = { + .i2c_bus = 426, + .i2c_addr = 0x70, + .pca9548_base_nr = 293, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data37 = { + .i2c_bus = 427, + .i2c_addr = 0x70, + .pca9548_base_nr = 147, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data38 = { + .i2c_bus = 428, + .i2c_addr = 0x70, + .pca9548_base_nr = 201, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data39 = { + .i2c_bus = 429, + .i2c_addr = 0x70, + .pca9548_base_nr = 205, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data40 = { + .i2c_bus = 430, + .i2c_addr = 0x70, + .pca9548_base_nr = 209, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data41 = { + .i2c_bus = 431, + .i2c_addr = 0x70, + .pca9548_base_nr = 213, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data42 = { + .i2c_bus = 432, + .i2c_addr = 0x70, + .pca9548_base_nr = 217, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data43 = { + .i2c_bus = 433, + .i2c_addr = 0x70, + .pca9548_base_nr = 221, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data44 = { + .i2c_bus = 434, + .i2c_addr = 0x70, + .pca9548_base_nr = 225, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data45 = { + .i2c_bus = 435, + .i2c_addr = 0x70, + .pca9548_base_nr = 229, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data46 = { + .i2c_bus = 436, + .i2c_addr = 0x70, + .pca9548_base_nr = 155, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data47 = { + .i2c_bus = 437, + .i2c_addr = 0x70, + .pca9548_base_nr = 297, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data48 = { + .i2c_bus = 438, + .i2c_addr = 0x70, + .pca9548_base_nr = 301, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data49 = { + .i2c_bus = 439, + .i2c_addr = 0x70, + .pca9548_base_nr = 305, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data50 = { + .i2c_bus = 440, + .i2c_addr = 0x70, + .pca9548_base_nr = 309, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data51 = { + .i2c_bus = 441, + .i2c_addr = 0x70, + .pca9548_base_nr = 313, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data52 = { + .i2c_bus = 442, + .i2c_addr = 0x70, + .pca9548_base_nr = 317, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data53 = { + .i2c_bus = 443, + .i2c_addr = 0x70, + .pca9548_base_nr = 321, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data54 = { + .i2c_bus = 444, + .i2c_addr = 0x70, + .pca9548_base_nr = 325, + .fpga_9548_flag = FPGA_INTERNAL_PCA9548, + .fpga_9548_reset_flag = 0, +}; + +struct i2c_board_info fpga_pca954x_device_info[] = { + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data0,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data1,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data2,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data3,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data4,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data5,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data6,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data7,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data8,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data9,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data10,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data11,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data12,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data13,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data14,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data15,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data16,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data17,}, + { .type = "wb_fpga_pca9541", .platform_data = &fpga_pca954x_device_data18,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data19,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data20,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data21,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data22,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data23,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data24,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data25,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data26,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data27,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data28,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data29,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data30,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data31,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data32,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data33,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data34,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data35,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data36,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data37,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data38,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data39,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data40,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data41,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data42,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data43,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data44,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data45,}, + { .type = "wb_fpga_pca9548", .platform_data = &fpga_pca954x_device_data46,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data47,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data48,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data49,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data50,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data51,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data52,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data53,}, + { .type = "wb_fpga_pca9544", .platform_data = &fpga_pca954x_device_data54,}, +}; + +static int __init wb_fpga_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_pca954x_device_info); i++) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + fpga_pca954x_device_info[i].addr = fpga_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(fpga_pca954x_device_data->i2c_bus); + if (adap == NULL) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", fpga_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); + if (IS_ERR(client)) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", + fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); + } else { + fpga_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_fpga_pca954x_device_exit(void) +{ + int i; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_pca954x_device_info) - 1; i >= 0; i--) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + if (fpga_pca954x_device_data->client) { + i2c_unregister_device(fpga_pca954x_device_data->client); + fpga_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_fpga_pca954x_device_init); +module_exit(wb_fpga_pca954x_device_exit); +MODULE_DESCRIPTION("FPGA PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 0000000000..785e59477a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,340 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +/* CPU CPLD */ +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 0, + .i2c_addr = 0x0d, + .i2c_name = "cpld0", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MGMT CPLD */ +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 52, + .i2c_addr = 0x3d, + .i2c_name = "cpld1", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD A */ +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 139, + .i2c_addr = 0x1d, + .i2c_name = "cpld2", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD B */ +static i2c_dev_device_t i2c_dev_device_data3 = { + .i2c_bus = 140, + .i2c_addr = 0x2D, + .i2c_name = "cpld3", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD C */ +static i2c_dev_device_t i2c_dev_device_data4 = { + .i2c_bus = 141, + .i2c_addr = 0x3D, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* UPORT CPLD */ +static i2c_dev_device_t i2c_dev_device_data5 = { + .i2c_bus = 147, + .i2c_addr = 0x3d, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* DPORT CPLD */ +static i2c_dev_device_t i2c_dev_device_data6 = { + .i2c_bus = 155, + .i2c_addr = 0x3d, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* UFAN CPLD */ +static i2c_dev_device_t i2c_dev_device_data7 = { + .i2c_bus = 75, + .i2c_addr = 0x0d, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* DFAN CPLD */ +static i2c_dev_device_t i2c_dev_device_data8 = { + .i2c_bus = 83, + .i2c_addr = 0x0d, + .i2c_name = "cpld8", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD D */ +static i2c_dev_device_t i2c_dev_device_data9 = { + .i2c_bus = 142, + .i2c_addr = 0x4D, + .i2c_name = "cpld9", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; +#if 0 +/* MGMT CPLD */ +static i2c_dev_device_t i2c_dev_device_data10 = { + .i2c_bus = 2, + .i2c_addr = 0x3a, + .i2c_name = "cpld10", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; +#endif +/* MAC CPLD A */ +static i2c_dev_device_t i2c_dev_device_data11 = { + .i2c_bus = 12, + .i2c_addr = 0x1c, + .i2c_name = "cpld11", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD B */ +static i2c_dev_device_t i2c_dev_device_data12 = { + .i2c_bus = 13, + .i2c_addr = 0x2c, + .i2c_name = "cpld12", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD C */ +static i2c_dev_device_t i2c_dev_device_data13 = { + .i2c_bus = 11, + .i2c_addr = 0x3c, + .i2c_name = "cpld13", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* MAC CPLD D */ +static i2c_dev_device_t i2c_dev_device_data14 = { + .i2c_bus = 1, + .i2c_addr = 0x4a, + .i2c_name = "cpld14", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* UPORT CPLD */ +static i2c_dev_device_t i2c_dev_device_data15 = { + .i2c_bus = 15, + .i2c_addr = 0x3c, + .i2c_name = "cpld15", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* DPORT CPLD */ +static i2c_dev_device_t i2c_dev_device_data16 = { + .i2c_bus = 17, + .i2c_addr = 0x3c, + .i2c_name = "cpld16", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data3, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data4, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data5, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data6, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data7, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data8, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data9, + }, +#if 0 + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data10, + }, +#endif + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data11, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data12, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data13, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data14, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data15, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data16, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (IS_ERR(client)) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 0000000000..36879f03f8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 1, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 0, + .close_chan_force_reset = 0, + .pca9548_base_nr = 11, + .pca9548_reset_type = PCA9548_RESET_FILE, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .file_attr.dev_name = "/dev/cpld1", + .file_attr.offset = 0x2b, + .file_attr.mask = 0xff, + .file_attr.reset_on = 0xd4, + .file_attr.reset_off = 0xd5, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (IS_ERR(client)) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("WB I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 0000000000..328119227c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x0a, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .search_mode = 1, + .bridge_bus = 0, + .bridge_slot = 0x03, + .bridge_fn = 3, +}; + +static pci_dev_device_t pcie_dev_device_data1 = { + .pci_dev_name = "fpga1", + .pci_domain = 0x0000, + .pci_bus = 8, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .search_mode = 1, + .bridge_bus = 0, + .bridge_slot = 0x03, + .bridge_fn = 1, +}; + +static pci_dev_device_t pcie_dev_device_data2 = { + .pci_dev_name = "fpga2", + .pci_domain = 0x0000, + .pci_bus = 9, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .search_mode = 1, + .bridge_bus = 0, + .bridge_slot = 0x03, + .bridge_fn = 2, +}; + + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, + { + .name = "wb-pci-dev", + .id = 2, + .dev = { + .platform_data = &pcie_dev_device_data1, + .release = wb_pcie_dev_device_release, + }, + }, + { + .name = "wb-pci-dev", + .id = 3, + .dev = { + .platform_data = &pcie_dev_device_data2, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_dev_device.c new file mode 100644 index 0000000000..0486278e9f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_dev_device.c @@ -0,0 +1,126 @@ +/* + * An wb_spi_dev_device driver for spi device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include "wb_spi_master.h" + +#define SPI_DEVICE_MAX_NUM (64) + +static int g_wb_spi_dev_device_debug = 0; +static int g_wb_spi_dev_device_error = 0; + +module_param(g_wb_spi_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_SPI_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_dev_device_debug) { \ + printk(KERN_INFO "[WB_SPI_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_SPI_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_dev_device_error) { \ + printk(KERN_ERR "[WB_SPI_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static spi_dev_device_t spi_dev_device_data0 = { + .spi_dev_name = "cpld10", + .data_bus_width = 4, + .addr_bus_width = 2, + .per_rd_len = 4, + .per_wr_len = 4, + .spi_len = 0x200, +}; + +static struct spi_device *g_spi_device[SPI_DEVICE_MAX_NUM]; + +struct spi_board_info spi_dev_device_info[] = { + { + .modalias = "wb-spi-dev", + .max_speed_hz = 6250000, + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_3, + .platform_data = &spi_dev_device_data0, + }, +}; + +static int __init wb_spi_dev_device_init(void) +{ + int i; + struct spi_controller *ctlr; + struct spi_device *spi; + int spi_dev_num; + + WB_SPI_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + + spi_dev_num = ARRAY_SIZE(spi_dev_device_info); + if (spi_dev_num > SPI_DEVICE_MAX_NUM) { + printk(KERN_ERR "spi_dev_num[%d] is bigger than max_num[%d].\n", + spi_dev_num, SPI_DEVICE_MAX_NUM); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(spi_dev_device_info); i++) { + ctlr = wb_spi_master_busnum_to_master(spi_dev_device_info[i].bus_num); + if (!ctlr) { + printk(KERN_ERR "get bus_num %u spi master failed.\n", + spi_dev_device_info[i].bus_num); + continue; + } + spi = spi_new_device(ctlr, &spi_dev_device_info[i]); + spi_controller_put(ctlr); + if (spi) { + g_spi_device[i] = spi; + } else { + g_spi_device[i] = NULL; + printk(KERN_ERR "Failed to register spi dev device %s at bus %d!\n", + spi_dev_device_info[i].modalias, spi_dev_device_info[i].bus_num); + continue; + } + } + return 0; +} + +static void __exit wb_spi_dev_device_exit(void) +{ + int i; + + WB_SPI_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(spi_dev_device_info) - 1; i >= 0; i--) { + if (g_spi_device[i]) { + spi_unregister_device(g_spi_device[i]); + g_spi_device[i] = NULL; + } + } +} + +module_init(wb_spi_dev_device_init); +module_exit(wb_spi_dev_device_exit); +MODULE_DESCRIPTION("SPI DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio.c new file mode 100644 index 0000000000..971c7abff2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * SPI host driver using generic bitbanged GPIO + * + * Copyright (C) 2006,2008 David Brownell + * Copyright (C) 2017 Linus Walleij + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static int nsecs_debug_time = 0; +module_param(nsecs_debug_time, int, S_IRUGO | S_IWUSR); + +/* + * This bitbanging SPI host driver should help make systems usable + * when a native hardware SPI engine is not available, perhaps because + * its driver isn't yet working or because the I/O pins it requires + * are used for other purposes. + * + * platform_device->driver_data ... points to spi_gpio + * + * spi->controller_state ... reserved for bitbang framework code + * + * spi->controller->dev.driver_data ... points to spi_gpio->bitbang + */ + +struct spi_gpio { + struct spi_bitbang bitbang; + struct gpio_desc *sck; + struct gpio_desc *miso; + struct gpio_desc *mosi; + struct gpio_desc **cs_gpios; +}; + +/*----------------------------------------------------------------------*/ + +/* + * Because the overhead of going through four GPIO procedure calls + * per transferred bit can make performance a problem, this code + * is set up so that you can use it in either of two ways: + * + * - The slow generic way: set up platform_data to hold the GPIO + * numbers used for MISO/MOSI/SCK, and issue procedure calls for + * each of them. This driver can handle several such busses. + * + * - The quicker inlined way: only helps with platform GPIO code + * that inlines operations for constant GPIOs. This can give + * you tight (fast!) inner loops, but each such bus needs a + * new driver. You'll define a new C file, with Makefile and + * Kconfig support; the C code can be a total of six lines: + * + * #define DRIVER_NAME "myboard_spi2" + * #define SPI_MISO_GPIO 119 + * #define SPI_MOSI_GPIO 120 + * #define SPI_SCK_GPIO 121 + * #define SPI_N_CHIPSEL 4 + * #include "spi-gpio.c" + */ + +#ifndef DRIVER_NAME +#define DRIVER_NAME "wb_spi_gpio" + +#define GENERIC_BITBANG /* vs tight inlines */ + +#endif + +/*----------------------------------------------------------------------*/ + +static inline struct spi_gpio *__pure +spi_to_spi_gpio(const struct spi_device *spi) +{ + const struct spi_bitbang *bang; + struct spi_gpio *spi_gpio; + + bang = spi_controller_get_devdata(spi->controller); + spi_gpio = container_of(bang, struct spi_gpio, bitbang); + return spi_gpio; +} + +/* These helpers are in turn called by the bitbang inlines */ +static inline void setsck(const struct spi_device *spi, int is_on) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->sck, is_on); +} + +static inline void setmosi(const struct spi_device *spi, int is_on) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->mosi, is_on); +} + +static inline int getmiso(const struct spi_device *spi) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + if (spi->mode & SPI_3WIRE) + return !!gpiod_get_value_cansleep(spi_gpio->mosi); + else + return !!gpiod_get_value_cansleep(spi_gpio->miso); +} + +/* + * NOTE: this clocks "as fast as we can". It "should" be a function of the + * requested device clock. Software overhead means we usually have trouble + * reaching even one Mbit/sec (except when we can inline bitops), so for now + * we'll just assume we never need additional per-bit slowdowns. + */ + #if 0 +#define spidelay(nsecs) do {} while (0) +#endif +static int spi_gpio_get_delay_time(unsigned nsecs) +{ + int delay_time_us; + + /* Frequency greater than 1M, return 0 as fast as we can */ + if (nsecs < 1000) { + return 0; + } + + /* Convert ns to us and round up */ + delay_time_us = (nsecs + 1000 - 1) / 1000; + + return delay_time_us; +} + +static void spidelay(unsigned nsecs) +{ + u32 delay_time_us; + /* Convert ns to us and round up */ + delay_time_us = spi_gpio_get_delay_time(nsecs); + if (delay_time_us >= 1) { + udelay(delay_time_us); + } + return; +} + +static void print_spi_debug_info(const char *mode, unsigned nsecs) +{ + if (nsecs_debug_time > 0) { + nsecs_debug_time--; + printk("%s, nsecs = %d, delay = %d\n", mode, nsecs, spi_gpio_get_delay_time(nsecs)); + } +} +#include "spi-bitbang-txrx.h" + +/* + * These functions can leverage inline expansion of GPIO calls to shrink + * costs for a txrx bit, often by factors of around ten (by instruction + * count). That is particularly visible for larger word sizes, but helps + * even with default 8-bit words. + * + * REVISIT overheads calling these functions for each word also have + * significant performance costs. Having txrx_bufs() calls that inline + * the txrx_word() logic would help performance, e.g. on larger blocks + * used with flash storage or MMC/SD. There should also be ways to make + * GCC be less stupid about reloading registers inside the I/O loops, + * even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3? + */ + +static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); +} + +static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); +} + +/* + * These functions do not call setmosi or getmiso if respective flag + * (SPI_CONTROLLER_NO_RX or SPI_CONTROLLER_NO_TX) is set, so they are safe to + * call when such pin is not present or defined in the controller. + * A separate set of callbacks is defined to get highest possible + * speed in the generic case (when both MISO and MOSI lines are + * available), as optimiser will remove the checks when argument is + * constant. + */ + +static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + flags = spi->controller->flags; + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + flags = spi->controller->flags; + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + flags = spi->controller->flags; + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); +} + +static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits, unsigned flags) +{ + print_spi_debug_info(__func__, nsecs); + + flags = spi->controller->flags; + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); +} + +/*----------------------------------------------------------------------*/ + +static void spi_gpio_chipselect(struct spi_device *spi, int is_active) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + /* set initial clock line level */ + if (is_active) + gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL); + + /* Drive chip select line, if we have one */ + if (spi_gpio->cs_gpios) { + struct gpio_desc *cs = spi_gpio->cs_gpios[spi_get_chipselect(spi, 0)]; + + /* SPI chip selects are normally active-low */ + gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); + } +} + +static void spi_gpio_set_mosi_idle(struct spi_device *spi) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + + gpiod_set_value_cansleep(spi_gpio->mosi, + !!(spi->mode & SPI_MOSI_IDLE_HIGH)); +} + +static int spi_gpio_setup(struct spi_device *spi) +{ + struct gpio_desc *cs; + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + int ret; + + /* + * The CS GPIOs have already been + * initialized from the descriptor lookup. + */ + if (spi_gpio->cs_gpios) { + cs = spi_gpio->cs_gpios[spi_get_chipselect(spi, 0)]; + if (!spi->controller_state && cs) { + ret = gpiod_direction_output(cs, !(spi->mode & SPI_CS_HIGH)); + if (ret) + return ret; + } + } + + return spi_bitbang_setup(spi); +} + +static int spi_gpio_set_direction(struct spi_device *spi, bool output) +{ + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); + int ret; + + if (output) + return gpiod_direction_output(spi_gpio->mosi, 1); + + /* + * Only change MOSI to an input if using 3WIRE mode. + * Otherwise, MOSI could be left floating if there is + * no pull resistor connected to the I/O pin, or could + * be left logic high if there is a pull-up. Transmitting + * logic high when only clocking MISO data in can put some + * SPI devices in to a bad state. + */ + if (spi->mode & SPI_3WIRE) { + ret = gpiod_direction_input(spi_gpio->mosi); + if (ret) + return ret; + } + /* + * Send a turnaround high impedance cycle when switching + * from output to input. Theoretically there should be + * a clock delay here, but as has been noted above, the + * nsec delay function for bit-banged GPIO is simply + * {} because bit-banging just doesn't get fast enough + * anyway. + */ + if (spi->mode & SPI_3WIRE_HIZ) { + gpiod_set_value_cansleep(spi_gpio->sck, + !(spi->mode & SPI_CPOL)); + gpiod_set_value_cansleep(spi_gpio->sck, + !!(spi->mode & SPI_CPOL)); + } + return 0; +} + +static void spi_gpio_cleanup(struct spi_device *spi) +{ + spi_bitbang_cleanup(spi); +} + +/* + * It can be convenient to use this driver with pins that have alternate + * functions associated with a "native" SPI controller if a driver for that + * controller is not available, or is missing important functionality. + * + * On platforms which can do so, configure MISO with a weak pullup unless + * there's an external pullup on that signal. That saves power by avoiding + * floating signals. (A weak pulldown would save power too, but many + * drivers expect to see all-ones data as the no target "response".) + */ +static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio) +{ + spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW); + if (IS_ERR(spi_gpio->mosi)) + return PTR_ERR(spi_gpio->mosi); + + spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN); + if (IS_ERR(spi_gpio->miso)) + return PTR_ERR(spi_gpio->miso); + + spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); + return PTR_ERR_OR_ZERO(spi_gpio->sck); +} + +static int spi_gpio_probe_pdata(struct platform_device *pdev, + struct spi_controller *host) +{ + struct device *dev = &pdev->dev; + struct spi_gpio_platform_data *pdata = dev_get_platdata(dev); + struct spi_gpio *spi_gpio = spi_controller_get_devdata(host); + int i; + +#ifdef GENERIC_BITBANG + if (!pdata || !pdata->num_chipselect) + return -ENODEV; +#endif + /* + * The host needs to think there is a chipselect even if not + * connected + */ + host->num_chipselect = pdata->num_chipselect ?: 1; + + spi_gpio->cs_gpios = devm_kcalloc(dev, host->num_chipselect, + sizeof(*spi_gpio->cs_gpios), + GFP_KERNEL); + if (!spi_gpio->cs_gpios) + return -ENOMEM; + + for (i = 0; i < host->num_chipselect; i++) { + spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", i, + GPIOD_OUT_HIGH); + if (IS_ERR(spi_gpio->cs_gpios[i])) + return PTR_ERR(spi_gpio->cs_gpios[i]); + } + + return 0; +} + +static int spi_gpio_probe(struct platform_device *pdev) +{ + int status; + struct spi_controller *host; + struct spi_gpio *spi_gpio; + struct device *dev = &pdev->dev; + struct fwnode_handle *fwnode = dev_fwnode(dev); + struct spi_bitbang *bb; + + host = devm_spi_alloc_host(dev, sizeof(*spi_gpio)); + if (!host) + return -ENOMEM; + + if (fwnode) { + device_set_node(&host->dev, fwnode); + host->use_gpio_descriptors = true; + } else { + status = spi_gpio_probe_pdata(pdev, host); + if (status) + return status; + } + + spi_gpio = spi_controller_get_devdata(host); + + status = spi_gpio_request(dev, spi_gpio); + if (status) + return status; + + host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); + host->mode_bits = SPI_3WIRE | SPI_3WIRE_HIZ | SPI_CPHA | SPI_CPOL | + SPI_CS_HIGH | SPI_LSB_FIRST | SPI_MOSI_IDLE_LOW | + SPI_MOSI_IDLE_HIGH; + if (!spi_gpio->mosi) { + /* HW configuration without MOSI pin + * + * No setting SPI_CONTROLLER_NO_RX here - if there is only + * a MOSI pin connected the host can still do RX by + * changing the direction of the line. + */ + host->flags = SPI_CONTROLLER_NO_TX; + } + + host->bus_num = pdev->id; + host->setup = spi_gpio_setup; + host->cleanup = spi_gpio_cleanup; + + bb = &spi_gpio->bitbang; + bb->ctlr = host; + /* + * There is some additional business, apart from driving the CS GPIO + * line, that we need to do on selection. This makes the local + * callback for chipselect always get called. + */ + host->flags |= SPI_CONTROLLER_GPIO_SS; + bb->chipselect = spi_gpio_chipselect; + bb->set_line_direction = spi_gpio_set_direction; + bb->set_mosi_idle = spi_gpio_set_mosi_idle; + + if (host->flags & SPI_CONTROLLER_NO_TX) { + bb->txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0; + bb->txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1; + bb->txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2; + bb->txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3; + } else { + bb->txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; + bb->txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; + bb->txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; + bb->txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; + } + bb->setup_transfer = spi_bitbang_setup_transfer; + + status = spi_bitbang_init(&spi_gpio->bitbang); + if (status) + return status; + + return devm_spi_register_controller(&pdev->dev, host); +} + +MODULE_ALIAS("platform:" DRIVER_NAME); + +static const struct of_device_id spi_gpio_dt_ids[] = { + { .compatible = "wb-spi-gpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids); + +static struct platform_driver spi_gpio_driver = { + .driver = { + .name = DRIVER_NAME, + .of_match_table = spi_gpio_dt_ids, + }, + .probe = spi_gpio_probe, +}; +module_platform_driver(spi_gpio_driver); + +MODULE_DESCRIPTION("SPI host driver using generic bitbanged GPIO "); +MODULE_AUTHOR("support"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio_device_cpld.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio_device_cpld.c new file mode 100644 index 0000000000..46bd398d28 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_spi_gpio_device_cpld.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#define DEFAULT_GPIO_SCK (115) +#define DEFAULT_GPIO_MISO (92) +#define DEFAULT_GPIO_MOSI (116) +#define DEFAULT_GPIO_CS (38) +#define DEFAULT_SPI_BUS (1) + +static int sck = DEFAULT_GPIO_SCK; +module_param(sck, int, S_IRUGO | S_IWUSR); + +static int miso = DEFAULT_GPIO_MISO; +module_param(miso, int, S_IRUGO | S_IWUSR); + +static int mosi = DEFAULT_GPIO_MOSI; +module_param(mosi, int, S_IRUGO | S_IWUSR); + +static int cs = DEFAULT_GPIO_CS; +module_param(cs, int, S_IRUGO | S_IWUSR); + +static int bus = DEFAULT_SPI_BUS; +module_param(bus, int, S_IRUGO | S_IWUSR); + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static char gpiod_lookup_table_devid[64]; + +static char *gpio_chip_name = NULL; +module_param(gpio_chip_name, charp, 0644); +MODULE_PARM_DESC(str_var, "A string variable for GPIO controller"); + +static struct gpiod_lookup_table wb_spi_gpio_table = { + .table = { + GPIO_LOOKUP("AMDI0030:00", DEFAULT_GPIO_SCK, + "sck", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("AMDI0030:00", DEFAULT_GPIO_MOSI, + "mosi", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("AMDI0030:00", DEFAULT_GPIO_MISO, + "miso", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("AMDI0030:00", DEFAULT_GPIO_CS, + "cs", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct spi_gpio_platform_data spi_pdata = { + .num_chipselect = 1, +}; + +static void spi_gpio_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_spi_gpio_device = { + .name = "wb_spi_gpio", + .num_resources = 0, + .id = -1, + + .dev = { + .platform_data = &spi_pdata, + .release = spi_gpio_release, + } +}; + +static void wb_spi_gpio_table_devid_name_set(void) { + int size; + + size = sizeof(gpiod_lookup_table_devid); + wb_spi_gpio_device.id = bus; + + mem_clear(gpiod_lookup_table_devid, size); + switch (bus) { + case PLATFORM_DEVID_NONE: + snprintf(gpiod_lookup_table_devid, size, "%s", wb_spi_gpio_device.name); + break; + case PLATFORM_DEVID_AUTO: + snprintf(gpiod_lookup_table_devid, size, "%s.%d.auto", wb_spi_gpio_device.name, bus); + break; + default: + snprintf(gpiod_lookup_table_devid, size, "%s.%d", wb_spi_gpio_device.name, bus); + break; + } + + wb_spi_gpio_table.dev_id = gpiod_lookup_table_devid; + return ; +} +static int __init wb_spi_gpio_device_init(void) +{ + int err; + struct gpiod_lookup *p; + + DEBUG_VERBOSE("enter!\n"); + wb_spi_gpio_table.table[0].chip_hwnum = sck; + wb_spi_gpio_table.table[1].chip_hwnum = mosi; + wb_spi_gpio_table.table[2].chip_hwnum = miso; + wb_spi_gpio_table.table[3].chip_hwnum = cs; + if (gpio_chip_name) { + wb_spi_gpio_table.table[0].key = gpio_chip_name; + wb_spi_gpio_table.table[1].key = gpio_chip_name; + wb_spi_gpio_table.table[2].key = gpio_chip_name; + wb_spi_gpio_table.table[3].key = gpio_chip_name; + } + wb_spi_gpio_table_devid_name_set(); + DEBUG_VERBOSE("spi gpi device table bus[%d] dev id[%s]\n", bus, wb_spi_gpio_table.dev_id); + for (p = &wb_spi_gpio_table.table[0]; p->key; p++) { + DEBUG_VERBOSE("con_id:%s gpio:%d\n", p->con_id, p->chip_hwnum); + } + + gpiod_add_lookup_table(&wb_spi_gpio_table); + err = platform_device_register(&wb_spi_gpio_device); + if (err < 0) { + printk(KERN_ERR "register spi gpio device fail(%d). \n", err); + gpiod_remove_lookup_table(&wb_spi_gpio_table); + return -1; + } + + return 0; +} + +static void __exit wb_spi_gpio_device_exit(void) +{ + DEBUG_VERBOSE("enter!\n"); + platform_device_unregister(&wb_spi_gpio_device); + gpiod_remove_lookup_table(&wb_spi_gpio_table); +} + +module_init(wb_spi_gpio_device_init); +module_exit(wb_spi_gpio_device_exit); +MODULE_DESCRIPTION("SPI GPIO Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_switch_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_switch_dev_device.c new file mode 100644 index 0000000000..979683c6c7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_switch_dev_device.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static void wb_switch_dev_device_release(struct device *dev) +{ + return; +} + +static switch_dev_info_t switch_dev_info_array[] = { + { + .mdio_bus_name = "gpio", + .mdio_dev_device = { + { .dev_name = "cpu_phy" }, + { .dev_name = "mgmt_phy"}, + { .dev_name = "port2_phy"}, + { .dev_name = "port3_phy"}, + { .dev_name = "sfp_phy"}, + }, + }, +}; + +/* Platform devices for switches */ +static struct platform_device switch_dev_device_array[] = { + { + .name = "bcm53134", + .id = 1, /* Device ID for switch 0 */ + .dev = { + .platform_data = &switch_dev_info_array[0], + .release = wb_switch_dev_device_release, + }, + }, +}; + +static int __init wb_switch_dev_device_init(void) +{ + int i; + int ret = 0; + switch_dev_info_t *switch_dev_info; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(switch_dev_device_array); i++) { + switch_dev_info = switch_dev_device_array[i].dev.platform_data; + ret = platform_device_register(&switch_dev_device_array[i]); + if (ret < 0) { + switch_dev_info->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "switch device.%d register failed!\n", i + 1); + } else { + switch_dev_info->device_flag = 0; /* device register success, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_switch_dev_device_exit(void) +{ + int i; + switch_dev_info_t *switch_dev_info; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(switch_dev_device_array) - 1; i >= 0; i--) { + switch_dev_info = switch_dev_device_array[i].dev.platform_data; + if (switch_dev_info->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&switch_dev_device_array[i]); + } + } +} + +module_init(wb_switch_dev_device_init); +module_exit(wb_switch_dev_device_exit); +MODULE_DESCRIPTION("Generic Switch Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_vr_common_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_vr_common_dev_device.c new file mode 100644 index 0000000000..613169b7dd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_vr_common_dev_device.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +#define WB_VR_DEVICE_NAME(_bus, _addr) vr_device_data##_bus##_##_addr + +#define WB_VR_DEVICE_DEFINE(_bus, _addr) \ + wb_vr_common_device_t WB_VR_DEVICE_NAME(_bus, _addr) = \ + { .i2c_bus = (_bus), .i2c_addr = (_addr), .device_flag = 0 } + +static WB_VR_DEVICE_DEFINE(54 , 0x72); +static WB_VR_DEVICE_DEFINE(54 , 0x74); +static WB_VR_DEVICE_DEFINE(94 , 0x60); +static WB_VR_DEVICE_DEFINE(95 , 0x60); +static WB_VR_DEVICE_DEFINE(96 , 0x60); +static WB_VR_DEVICE_DEFINE(97 , 0x60); +static WB_VR_DEVICE_DEFINE(102, 0x60); +static WB_VR_DEVICE_DEFINE(103, 0x60); +static WB_VR_DEVICE_DEFINE(104, 0x60); +static WB_VR_DEVICE_DEFINE(105, 0x60); +static WB_VR_DEVICE_DEFINE(107, 0x60); +static WB_VR_DEVICE_DEFINE(108, 0x60); +static WB_VR_DEVICE_DEFINE(109, 0x60); +static WB_VR_DEVICE_DEFINE(110, 0x60); +static WB_VR_DEVICE_DEFINE(111, 0x60); +static WB_VR_DEVICE_DEFINE(112, 0x60); +static WB_VR_DEVICE_DEFINE(113, 0x60); +static WB_VR_DEVICE_DEFINE(114, 0x60); +static WB_VR_DEVICE_DEFINE(115, 0x60); +static WB_VR_DEVICE_DEFINE(116, 0x60); +static WB_VR_DEVICE_DEFINE(117, 0x60); +static WB_VR_DEVICE_DEFINE(118, 0x60); +static WB_VR_DEVICE_DEFINE(119, 0x60); +static WB_VR_DEVICE_DEFINE(120, 0x60); +static WB_VR_DEVICE_DEFINE(121, 0x60); +static WB_VR_DEVICE_DEFINE(122, 0x60); +static WB_VR_DEVICE_DEFINE(136, 0x60); + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +#define WB_VR_DEV_ENTRY(_id, _bus, _addr) \ + { \ + .name = "wb-vr-common", \ + .id = (_id), \ + .dev = { \ + .platform_data = &WB_VR_DEVICE_NAME(_bus, _addr), \ + .release = wb_io_dev_device_release, \ + }, \ + } + +static struct platform_device vr_dev_devices[] = { + WB_VR_DEV_ENTRY(1, 54, 0x72), + WB_VR_DEV_ENTRY(2, 54, 0x74), + WB_VR_DEV_ENTRY(3, 94, 0x60), + WB_VR_DEV_ENTRY(4, 95, 0x60), + WB_VR_DEV_ENTRY(5, 96, 0x60), + WB_VR_DEV_ENTRY(6, 97, 0x60), + WB_VR_DEV_ENTRY(7, 102, 0x60), + WB_VR_DEV_ENTRY(8, 103, 0x60), + WB_VR_DEV_ENTRY(9, 104, 0x60), + WB_VR_DEV_ENTRY(10, 105, 0x60), + WB_VR_DEV_ENTRY(11, 107, 0x60), + WB_VR_DEV_ENTRY(12, 108, 0x60), + WB_VR_DEV_ENTRY(13, 109, 0x60), + WB_VR_DEV_ENTRY(14, 110, 0x60), + WB_VR_DEV_ENTRY(15, 111, 0x60), + WB_VR_DEV_ENTRY(16, 112, 0x60), + WB_VR_DEV_ENTRY(17, 113, 0x60), + WB_VR_DEV_ENTRY(18, 114, 0x60), + WB_VR_DEV_ENTRY(19, 115, 0x60), + WB_VR_DEV_ENTRY(20, 116, 0x60), + WB_VR_DEV_ENTRY(21, 117, 0x60), + WB_VR_DEV_ENTRY(22, 118, 0x60), + WB_VR_DEV_ENTRY(23, 119, 0x60), + WB_VR_DEV_ENTRY(24, 120, 0x60), + WB_VR_DEV_ENTRY(25, 121, 0x60), + WB_VR_DEV_ENTRY(26, 122, 0x60), + WB_VR_DEV_ENTRY(27, 136, 0x60), +}; + +static int __init wb_vr_dev_device_init(void) +{ + int i; + int ret = 0; + wb_vr_common_device_t *vr_dev_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(vr_dev_devices); i++) { + vr_dev_data = vr_dev_devices[i].dev.platform_data; + ret = platform_device_register(&vr_dev_devices[i]); + if (ret < 0) { + vr_dev_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-vr-dev.%d register failed!\n", i + 1); + } else { + vr_dev_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_vr_dev_device_exit(void) +{ + int i; + wb_vr_common_device_t *vr_dev_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(vr_dev_devices) - 1; i >= 0; i--) { + vr_dev_data = vr_dev_devices[i].dev.platform_data; + if (vr_dev_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&vr_dev_devices[i]); + } + } +} + +module_init(wb_vr_dev_device_init); +module_exit(wb_vr_dev_device_exit); +MODULE_DESCRIPTION("VR DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_wdt_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_wdt_device.c new file mode 100644 index 0000000000..dc2327c1c5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/modules/driver/wb_wdt_device.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include + +#include +#include + +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +static wb_wdt_device_t wb_wdt_device_data_0 = { + .feed_wdt_type = 1, /* 0: WATCHDOG_DEVICE 1: HRTIMER, 2: THREAD */ + .hw_margin = 90000, + .feed_time = 5000, + .config_dev_name = "/dev/cpld1", + .config_mode = 1, /* GPIO_FEED_WDT */ + .priv_func_mode = 1, /* SYMBOL_I2C_DEV */ + .enable_reg = 0xb0, + .enable_val = 0x1, + .disable_val = 0x0, + .enable_mask = 0x1, + .timeout_cfg_reg = 0xb2, + .timeleft_cfg_reg = 0xb3, + .hw_algo = "toggle", + .wdt_config_mode.gpio_wdt = { + .gpio = 642, /* AGPIO130 */ + .flags = 1 + }, + .timer_accuracy = 1600, /* 1.6s */ +}; + +/* sys led */ +static wb_wdt_device_t wb_wdt_device_data_1 = { + .feed_wdt_type = 2, /* 0: WATCHDOG_DEVICE 1: HRTIMER, 2: THREAD */ + .hw_margin = 180000, + .feed_time = 30000, + .config_dev_name = "/dev/cpld1", + .config_mode = 2, /* LOGIC_FEED_WDT */ + .priv_func_mode = 1, /* SYMBOL_I2C_DEV */ + .enable_reg = 0xc0, + .enable_val = 0x1, + .disable_val = 0x0, + .enable_mask = 0x1, + .timeout_cfg_reg = 0xc2, + .timeleft_cfg_reg = 0xc3, + .hw_algo = "eigenvalues", + .wdt_config_mode.logic_wdt = { + .feed_dev_name = "/dev/cpld1", + .feed_reg = 0xc4, + .active_val = 0x01, + .logic_func_mode = 1, /* SYMBOL_I2C_DEV */ + }, + .timer_accuracy = 1600, /* 1.6s */ +}; + +static void wb_wdt_device_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_wdt_device[] = { + { + .name = "wb_wdt", + .id = 0, + .dev = { + .platform_data = &wb_wdt_device_data_0, + .release = wb_wdt_device_release, + }, + }, + { + .name = "wb_wdt", + .id = 1, + .dev = { + .platform_data = &wb_wdt_device_data_1, + .release = wb_wdt_device_release, + }, + }, +}; + +static int __init wb_wdt_device_init(void) +{ + int i; + int ret = 0; + wb_wdt_device_t *wb_wdt_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(wb_wdt_device); i++) { + wb_wdt_device_data = wb_wdt_device[i].dev.platform_data; + ret = platform_device_register(&wb_wdt_device[i]); + if (ret < 0) { + wb_wdt_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-wdt.%d register failed!\n", i + 1); + } else { + wb_wdt_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_wdt_device_exit(void) +{ + int i; + wb_wdt_device_t *wb_wdt_device_data; + + DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(wb_wdt_device) - 1; i >= 0; i--) { + wb_wdt_device_data = wb_wdt_device[i].dev.platform_data; + if (wb_wdt_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&wb_wdt_device[i]); + } + } +} + +module_init(wb_wdt_device_init); +module_exit(wb_wdt_device_exit); +MODULE_DESCRIPTION("WB WDT Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/CPLD.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/CPLD.cfg new file mode 100644 index 0000000000..5e79ed022f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/CPLD.cfg @@ -0,0 +1,412 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Set item: System E2 i2c bus address +# Description: Format other_i2c_dev.bus_[main_dev]_[minor_dev] other_i2c_dev.addr_[main_dev]_[minor_dev], +# .bus is configuration item corresponds to the bus number (/dev/i2c-bus) +# .addr is address of the device corresponding to the configuration item on the bus +# Note: main_dev look rg_main_dev_type_t definition, main board is 0, minor_dev is 0 +other_i2c_dev.bus_0_0=1 +other_i2c_dev.addr_0_0=0x56 + +# Configuration item: System E2 path +eeprom_path_0_0=/sys/bus/i2c/devices/1-0056/eeprom + +# Configuration item: System E2 size +eeprom_size_0_0=256 + +# Configuration item: cpld logic_dev patch +# Description: Format cpld_logic_dev_[cpld_slot]_[cpld_id] +# All cpld numbers of each product are customized and do not have to be repeated. +# The numbers are reflected in the upper eight digits of the offset address of the cpld device +# cpld_id: 0:X86_CPLD, 1:MAC_CPLDA, 2:MAC_CPLDB +# Note: This field is optional. This field is not required for CPLDS that are not accessed by logic_dev +cpld_logic_dev_0_0=/dev/cpld0 +cpld_logic_dev_0_1=/dev/cpld1 +cpld_logic_dev_0_2=/dev/cpld2 +cpld_logic_dev_0_3=/dev/cpld3 +cpld_logic_dev_0_4=/dev/cpld4 +cpld_logic_dev_0_5=/dev/cpld5 +cpld_logic_dev_0_6=/dev/cpld6 +cpld_logic_dev_0_7=/dev/cpld7 +cpld_logic_dev_0_8=/dev/cpld8 +cpld_logic_dev_0_9=/dev/cpld9 + + +# Configuration item: Access mode of each cpld(LPC/I2C) +# Description: Format mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c/logic_dev, cpld_id is cpld number,Start at 0 +# Note: This field is required +mode_cpld_0_0=logic_dev +mode_cpld_0_1=logic_dev +mode_cpld_0_2=logic_dev +mode_cpld_0_3=logic_dev +mode_cpld_0_4=logic_dev +mode_cpld_0_5=logic_dev +mode_cpld_0_6=logic_dev +mode_cpld_0_7=logic_dev +mode_cpld_0_8=logic_dev +mode_cpld_0_9=logic_dev + + +# Configuration item: the number of CPLD +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev: indicates that the mainboard is 0, the subPLD is 5, and the minor_dev: CPLD is 8 +dev_num_0_8=10 + +# Configuration item: Name of each cpld +# Description: Format cpld_name_[cpld_id] cpld_id is cpld number,start with 1 +# Note: This field is required +cpld_name_0_0=CPU_CPLD +cpld_name_0_1=MGMT_CPLD +cpld_name_0_2=MAC_CPLD_A +cpld_name_0_3=MAC_CPLD_B +cpld_name_0_4=MAC_CPLD_C +cpld_name_0_5=UPORT_CPLD +cpld_name_0_6=DPORT_CPLD +cpld_name_0_7=UFAN_CPLD +cpld_name_0_8=DFAN_CPLD +cpld_name_0_9=MAC_CPLD_D + +# Configuration item: Model of each cpld +# Description: Format cpld_type_[cpld_id] cpld_idis cpld number,start with 1 +# Note: This frequired +cpld_type_0_0=LCMXO3LF-6900C-5BG400C +cpld_type_0_1=LCMXO3LF-6900C-5BG400C +cpld_type_0_2=LCMXO3LF-6900C-5BG400C +cpld_type_0_3=LCMXO3LF-4300C-5BG324C +cpld_type_0_4=LCMXO3LF-6900C-5BG400C +cpld_type_0_5=LCMXO3LF-6900C-5BG400C +cpld_type_0_6=LCMXO3LF-6900C-5BG400C +cpld_type_0_7=LCMXO3LF-2100C-5BG256C +cpld_type_0_8=LCMXO3LF-2100C-5BG256C +cpld_type_0_9=LCMXO3LF-2100C-5BG256C + +cpld_vendor_0_0=LATTICE +cpld_vendor_0_1=LATTICE +cpld_vendor_0_2=LATTICE +cpld_vendor_0_3=LATTICE +cpld_vendor_0_4=LATTICE +cpld_vendor_0_5=LATTICE +cpld_vendor_0_6=LATTICE +cpld_vendor_0_7=LATTICE +cpld_vendor_0_8=LATTICE +cpld_vendor_0_9=LATTICE + +# Configuration item: Version register of each CPLD +# Description: Format cpld_version_[cpld_id] cpld_id is cpld number,start with 1 +# Note: This field is required +cpld_version.mode_0_0=config +cpld_version.int_cons_0_0= +cpld_version.src_0_0=logic_file +cpld_version.frmt_0_0=num_bytes +cpld_version.pola_0_0= +cpld_version.fpath_0_0=/dev/cpld0 +cpld_version.addr_0_0=0x0 +cpld_version.len_0_0=4 +cpld_version.bit_offset_0_0= + +cpld_version.mode_0_1=config +cpld_version.int_cons_0_1= +cpld_version.src_0_1=logic_file +cpld_version.frmt_0_1=num_bytes +cpld_version.pola_0_1= +cpld_version.fpath_0_1=/dev/cpld1 +cpld_version.addr_0_1=0x0 +cpld_version.len_0_1=4 +cpld_version.bit_offset_0_1= + +cpld_version.mode_0_2=config +cpld_version.int_cons_0_2= +cpld_version.src_0_2=logic_file +cpld_version.frmt_0_2=num_bytes +cpld_version.pola_0_2= +cpld_version.fpath_0_2=/dev/cpld2 +cpld_version.addr_0_2=0x0 +cpld_version.len_0_2=4 +cpld_version.bit_offset_0_2= + +cpld_version.mode_0_3=config +cpld_version.int_cons_0_3= +cpld_version.src_0_3=logic_file +cpld_version.frmt_0_3=num_bytes +cpld_version.pola_0_3= +cpld_version.fpath_0_3=/dev/cpld3 +cpld_version.addr_0_3=0x0 +cpld_version.len_0_3=4 +cpld_version.bit_offset_0_3= + +cpld_version.mode_0_4=config +cpld_version.int_cons_0_4= +cpld_version.src_0_4=logic_file +cpld_version.frmt_0_4=num_bytes +cpld_version.pola_0_4= +cpld_version.fpath_0_4=/dev/cpld4 +cpld_version.addr_0_4=0x0 +cpld_version.len_0_4=4 +cpld_version.bit_offset_0_4= + +cpld_version.mode_0_5=config +cpld_version.int_cons_0_5= +cpld_version.src_0_5=logic_file +cpld_version.frmt_0_5=num_bytes +cpld_version.pola_0_5= +cpld_version.fpath_0_5=/dev/cpld5 +cpld_version.addr_0_5=0x0 +cpld_version.len_0_5=4 +cpld_version.bit_offset_0_5= + +cpld_version.mode_0_6=config +cpld_version.int_cons_0_6= +cpld_version.src_0_6=logic_file +cpld_version.frmt_0_6=num_bytes +cpld_version.pola_0_6= +cpld_version.fpath_0_6=/dev/cpld6 +cpld_version.addr_0_6=0x0 +cpld_version.len_0_6=4 +cpld_version.bit_offset_0_6= + +cpld_version.mode_0_7=config +cpld_version.int_cons_0_7= +cpld_version.src_0_7=logic_file +cpld_version.frmt_0_7=num_bytes +cpld_version.pola_0_7= +cpld_version.fpath_0_7=/dev/cpld7 +cpld_version.addr_0_7=0x0 +cpld_version.len_0_7=4 +cpld_version.bit_offset_0_7= + +cpld_version.mode_0_8=config +cpld_version.int_cons_0_8= +cpld_version.src_0_8=logic_file +cpld_version.frmt_0_8=num_bytes +cpld_version.pola_0_8= +cpld_version.fpath_0_8=/dev/cpld8 +cpld_version.addr_0_8=0x0 +cpld_version.len_0_8=4 +cpld_version.bit_offset_0_8= + +cpld_version.mode_0_9=config +cpld_version.int_cons_0_9= +cpld_version.src_0_9=logic_file +cpld_version.frmt_0_9=num_bytes +cpld_version.pola_0_9= +cpld_version.fpath_0_9=/dev/cpld9 +cpld_version.addr_0_9=0x0 +cpld_version.len_0_9=4 +cpld_version.bit_offset_0_9= + +# Configuration item: Test register for each CPLD +# Description: Format cpld_test_reg_[cpld_id] cpld_id is cpld number,start with 1 +# Note: This field is required + +cpld_test_reg.mode_0_0=config +cpld_test_reg.int_cons_0_0= +cpld_test_reg.src_0_0=logic_file +cpld_test_reg.frmt_0_0=byte +cpld_test_reg.pola_0_0= +cpld_test_reg.fpath_0_0=/dev/cpld0 +cpld_test_reg.addr_0_0=0xf +cpld_test_reg.len_0_0=1 +cpld_test_reg.bit_offset_0_0= + +cpld_test_reg.mode_0_1=config +cpld_test_reg.int_cons_0_1= +cpld_test_reg.src_0_1=logic_file +cpld_test_reg.frmt_0_1=byte +cpld_test_reg.pola_0_1= +cpld_test_reg.fpath_0_1=/dev/cpld1 +cpld_test_reg.addr_0_1=0xf +cpld_test_reg.len_0_1=1 +cpld_test_reg.bit_offset_0_1= + +cpld_test_reg.mode_0_2=config +cpld_test_reg.int_cons_0_2= +cpld_test_reg.src_0_2=logic_file +cpld_test_reg.frmt_0_2=byte +cpld_test_reg.pola_0_2= +cpld_test_reg.fpath_0_2=/dev/cpld2 +cpld_test_reg.addr_0_2=0xf +cpld_test_reg.len_0_2=1 +cpld_test_reg.bit_offset_0_2= + +cpld_test_reg.mode_0_3=config +cpld_test_reg.int_cons_0_3= +cpld_test_reg.src_0_3=logic_file +cpld_test_reg.frmt_0_3=byte +cpld_test_reg.pola_0_3= +cpld_test_reg.fpath_0_3=/dev/cpld3 +cpld_test_reg.addr_0_3=0xf +cpld_test_reg.len_0_3=1 +cpld_test_reg.bit_offset_0_3= + +cpld_test_reg.mode_0_4=config +cpld_test_reg.int_cons_0_4= +cpld_test_reg.src_0_4=logic_file +cpld_test_reg.frmt_0_4=byte +cpld_test_reg.pola_0_4= +cpld_test_reg.fpath_0_4=/dev/cpld4 +cpld_test_reg.addr_0_4=0xf +cpld_test_reg.len_0_4=1 +cpld_test_reg.bit_offset_0_4= + +cpld_test_reg.mode_0_5=config +cpld_test_reg.int_cons_0_5= +cpld_test_reg.src_0_5=logic_file +cpld_test_reg.frmt_0_5=byte +cpld_test_reg.pola_0_5= +cpld_test_reg.fpath_0_5=/dev/cpld5 +cpld_test_reg.addr_0_5=0xf +cpld_test_reg.len_0_5=1 +cpld_test_reg.bit_offset_0_5= + +cpld_test_reg.mode_0_6=config +cpld_test_reg.int_cons_0_6= +cpld_test_reg.src_0_6=logic_file +cpld_test_reg.frmt_0_6=byte +cpld_test_reg.pola_0_6= +cpld_test_reg.fpath_0_6=/dev/cpld6 +cpld_test_reg.addr_0_6=0xf +cpld_test_reg.len_0_6=1 +cpld_test_reg.bit_offset_0_6= + +cpld_test_reg.mode_0_7=config +cpld_test_reg.int_cons_0_7= +cpld_test_reg.src_0_7=logic_file +cpld_test_reg.frmt_0_7=byte +cpld_test_reg.pola_0_7= +cpld_test_reg.fpath_0_7=/dev/cpld7 +cpld_test_reg.addr_0_7=0x55 +cpld_test_reg.len_0_7=1 +cpld_test_reg.bit_offset_0_7= + +cpld_test_reg.mode_0_8=config +cpld_test_reg.int_cons_0_8= +cpld_test_reg.src_0_8=logic_file +cpld_test_reg.frmt_0_8=byte +cpld_test_reg.pola_0_8= +cpld_test_reg.fpath_0_8=/dev/cpld8 +cpld_test_reg.addr_0_8=0x55 +cpld_test_reg.len_0_8=1 +cpld_test_reg.bit_offset_0_8= + +cpld_test_reg.mode_0_9=config +cpld_test_reg.int_cons_0_9= +cpld_test_reg.src_0_9=logic_file +cpld_test_reg.frmt_0_9=byte +cpld_test_reg.pola_0_9= +cpld_test_reg.fpath_0_9=/dev/cpld9 +cpld_test_reg.addr_0_9=0x55 +cpld_test_reg.len_0_9=1 +cpld_test_reg.bit_offset_0_9= + +# Configuration item: Hardware version register of each CPLD +# Description: Format cpld_hw_version_[cpld_id] cpld_id is cpld number,start with 1 +# Note: Optional + +cpld_hw_version.mode_0_0=config +cpld_hw_version.int_cons_0_0= +cpld_hw_version.src_0_0=logic_file +cpld_hw_version.frmt_0_0=byte +cpld_hw_version.pola_0_0= +cpld_hw_version.fpath_0_0=/dev/cpld0 +cpld_hw_version.addr_0_0=0x7 +cpld_hw_version.len_0_0=1 +cpld_hw_version.bit_offset_0_0= + +cpld_hw_version.mode_0_1=config +cpld_hw_version.int_cons_0_1= +cpld_hw_version.src_0_1=logic_file +cpld_hw_version.frmt_0_1=byte +cpld_hw_version.pola_0_1= +cpld_hw_version.fpath_0_1=/dev/cpld1 +cpld_hw_version.addr_0_1=0xc +cpld_hw_version.len_0_1=1 +cpld_hw_version.bit_offset_0_1= + +cpld_hw_version.mode_0_2=config +cpld_hw_version.int_cons_0_2= +cpld_hw_version.src_0_2=logic_file +cpld_hw_version.frmt_0_2=byte +cpld_hw_version.pola_0_2= +cpld_hw_version.fpath_0_2=/dev/cpld2 +cpld_hw_version.addr_0_2=0xc +cpld_hw_version.len_0_2=1 +cpld_hw_version.bit_offset_0_2= + +cpld_hw_version.mode_0_3=config +cpld_hw_version.int_cons_0_3= +cpld_hw_version.src_0_3=logic_file +cpld_hw_version.frmt_0_3=byte +cpld_hw_version.pola_0_3= +cpld_hw_version.fpath_0_3=/dev/cpld3 +cpld_hw_version.addr_0_3=0xc +cpld_hw_version.len_0_3=1 +cpld_hw_version.bit_offset_0_3= + +cpld_hw_version.mode_0_4=config +cpld_hw_version.int_cons_0_4= +cpld_hw_version.src_0_4=logic_file +cpld_hw_version.frmt_0_4=byte +cpld_hw_version.pola_0_4= +cpld_hw_version.fpath_0_4=/dev/cpld4 +cpld_hw_version.addr_0_4=0xc +cpld_hw_version.len_0_4=1 +cpld_hw_version.bit_offset_0_4= + +cpld_hw_version.mode_0_5=config +cpld_hw_version.int_cons_0_5= +cpld_hw_version.src_0_5=logic_file +cpld_hw_version.frmt_0_5=byte +cpld_hw_version.pola_0_5= +cpld_hw_version.fpath_0_5=/dev/cpld5 +cpld_hw_version.addr_0_5=0xc +cpld_hw_version.len_0_5=1 +cpld_hw_version.bit_offset_0_5= + +cpld_hw_version.mode_0_6=config +cpld_hw_version.int_cons_0_6= +cpld_hw_version.src_0_6=logic_file +cpld_hw_version.frmt_0_6=byte +cpld_hw_version.pola_0_6= +cpld_hw_version.fpath_0_6=/dev/cpld6 +cpld_hw_version.addr_0_6=0xc +cpld_hw_version.len_0_6=1 +cpld_hw_version.bit_offset_0_6= + +cpld_hw_version.mode_0_7=config +cpld_hw_version.int_cons_0_7= +cpld_hw_version.src_0_7=logic_file +cpld_hw_version.frmt_0_7=byte +cpld_hw_version.pola_0_7= +cpld_hw_version.fpath_0_7=/dev/cpld7 +cpld_hw_version.addr_0_7=0x9 +cpld_hw_version.len_0_7=1 +cpld_hw_version.bit_offset_0_7= + +cpld_hw_version.mode_0_8=config +cpld_hw_version.int_cons_0_8= +cpld_hw_version.src_0_8=logic_file +cpld_hw_version.frmt_0_8=byte +cpld_hw_version.pola_0_8= +cpld_hw_version.fpath_0_8=/dev/cpld8 +cpld_hw_version.addr_0_8=0x9 +cpld_hw_version.len_0_8=1 +cpld_hw_version.bit_offset_0_8= + +cpld_hw_version.mode_0_9=config +cpld_hw_version.int_cons_0_9= +cpld_hw_version.src_0_9=logic_file +cpld_hw_version.frmt_0_9=byte +cpld_hw_version.pola_0_9= +cpld_hw_version.fpath_0_9=/dev/cpld9 +cpld_hw_version.addr_0_9=0x9 +cpld_hw_version.len_0_9=1 +cpld_hw_version.bit_offset_0_9= + + diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FAN.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FAN.cfg new file mode 100644 index 0000000000..104f4ceeed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FAN.cfg @@ -0,0 +1,608 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration items: E2 i2c bus address +# Description: Format other_i2c_dev.bus_[main_dev]_[minor_dev] other_i2c_dev.addr_[main_dev]_[minor_dev], +# .bus is configuration item corresponds to the bus number (/dev/i2c-bus) +# .addr is address of the device corresponding to the configuration item on the bus +# Note: main_dev is defined in rg_main_dev_type_t. mainboard is 0, fan is 1, dev_index is device index +other_i2c_dev.bus_1_1=77 +other_i2c_dev.addr_1_1=0x50 +other_i2c_dev.bus_1_2=85 +other_i2c_dev.addr_1_2=0x50 +other_i2c_dev.bus_1_3=78 +other_i2c_dev.addr_1_3=0x50 +other_i2c_dev.bus_1_4=86 +other_i2c_dev.addr_1_4=0x50 +other_i2c_dev.bus_1_5=79 +other_i2c_dev.addr_1_5=0x50 +other_i2c_dev.bus_1_6=87 +other_i2c_dev.addr_1_6=0x50 +other_i2c_dev.bus_1_7=80 +other_i2c_dev.addr_1_7=0x50 +other_i2c_dev.bus_1_8=88 +other_i2c_dev.addr_1_8=0x50 + +# Configuration items: Fan dependent constant +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,Fan is 1 minor_dev, 0: does not exist, 5: motor + + +# Number of fans +dev_num_1_0=8 + +# Number of motors +dev_num_1_5=2 + +# Configuration items: Product fan E2 format +# Description: Format fan_e2_mode +# Note: required +fan_e2_mode=fru + +# Configuration items: Mode of reading fan E2 +# Description: Format fan_sysfs_name +# Note: If not configured, it is read by i2c, otherwise it is read by sysfs +fan_sysfs_name=eeprom + +# Configuration items: Fan air duct type +# Filling instructions: fan_direction_[fan_type]__[fan_sub_type] = [direction] +# direction is air duct 0:F2B 1:B2F +# Note: required +fan_direction_1_1=0 + +# Configuration items: Fan status CPLD register address +# Description: Format dev_present_status_[main_dev_id][fan_index] fan_indexstart with 1 +# Note: fan main_dev_id is 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=logic_file +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.fpath_1_1=/dev/cpld7 +dev_present_status.addr_1_1=0x5b +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=logic_file +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.fpath_1_2=/dev/cpld8 +dev_present_status.addr_1_2=0x5b +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=0 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=logic_file +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.fpath_1_3=/dev/cpld7 +dev_present_status.addr_1_3=0x5b +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=1 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=logic_file +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.fpath_1_4=/dev/cpld8 +dev_present_status.addr_1_4=0x5b +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=1 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=logic_file +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.fpath_1_5=/dev/cpld7 +dev_present_status.addr_1_5=0x5b +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=2 + +dev_present_status.mode_1_6=config +dev_present_status.src_1_6=logic_file +dev_present_status.frmt_1_6=bit +dev_present_status.pola_1_6=negative +dev_present_status.fpath_1_6=/dev/cpld8 +dev_present_status.addr_1_6=0x5b +dev_present_status.len_1_6=1 +dev_present_status.bit_offset_1_6=2 + +dev_present_status.mode_1_7=config +dev_present_status.src_1_7=logic_file +dev_present_status.frmt_1_7=bit +dev_present_status.pola_1_7=negative +dev_present_status.fpath_1_7=/dev/cpld7 +dev_present_status.addr_1_7=0x5b +dev_present_status.len_1_7=1 +dev_present_status.bit_offset_1_7=3 + +dev_present_status.mode_1_8=config +dev_present_status.src_1_8=logic_file +dev_present_status.frmt_1_8=bit +dev_present_status.pola_1_8=negative +dev_present_status.fpath_1_8=/dev/cpld8 +dev_present_status.addr_1_8=0x5b +dev_present_status.len_1_8=1 +dev_present_status.bit_offset_1_8=3 + +# Configuration items: Fan rotation status CPLD register address +# Description: Format fan_roll_status_[fan_id]_[motor_id] fan_idstart with 1, motor_idstart with 1 +# Note: required +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=logic_file +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1=/dev/cpld7 +fan_roll_status.addr_1_1=0x5c +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_1_2=config +fan_roll_status.int_cons_1_2= +fan_roll_status.src_1_2=logic_file +fan_roll_status.frmt_1_2=bit +fan_roll_status.pola_1_2=positive +fan_roll_status.fpath_1_2=/dev/cpld7 +fan_roll_status.addr_1_2=0x5d +fan_roll_status.len_1_2=1/dev/cpld +fan_roll_status.bit_offset_1_2=0 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=logic_file +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1=/dev/cpld8 +fan_roll_status.addr_2_1=0x5c +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=0 + +fan_roll_status.mode_2_2=config +fan_roll_status.int_cons_2_2= +fan_roll_status.src_2_2=logic_file +fan_roll_status.frmt_2_2=bit +fan_roll_status.pola_2_2=positive +fan_roll_status.fpath_2_2=/dev/cpld8 +fan_roll_status.addr_2_2=0x5d +fan_roll_status.len_2_2=1 +fan_roll_status.bit_offset_2_2=0 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=logic_file +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1=/dev/cpld7 +fan_roll_status.addr_3_1=0x5c +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=1 + +fan_roll_status.mode_3_2=config +fan_roll_status.int_cons_3_2= +fan_roll_status.src_3_2=logic_file +fan_roll_status.frmt_3_2=bit +fan_roll_status.pola_3_2=positive +fan_roll_status.fpath_3_2=/dev/cpld7 +fan_roll_status.addr_3_2=0x5d +fan_roll_status.len_3_2=1 +fan_roll_status.bit_offset_3_2=1 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=logic_file +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1=/dev/cpld8 +fan_roll_status.addr_4_1=0x5c +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=1 + +fan_roll_status.mode_4_2=config +fan_roll_status.int_cons_4_2= +fan_roll_status.src_4_2=logic_file +fan_roll_status.frmt_4_2=bit +fan_roll_status.pola_4_2=positive +fan_roll_status.fpath_4_2=/dev/cpld8 +fan_roll_status.addr_4_2=0x5d +fan_roll_status.len_4_2=1 +fan_roll_status.bit_offset_4_2=1 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=logic_file +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1=/dev/cpld7 +fan_roll_status.addr_5_1=0x5c +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=2 + +fan_roll_status.mode_5_2=config +fan_roll_status.int_cons_5_2= +fan_roll_status.src_5_2=logic_file +fan_roll_status.frmt_5_2=bit +fan_roll_status.pola_5_2=positive +fan_roll_status.fpath_5_2=/dev/cpld7 +fan_roll_status.addr_5_2=0x5d +fan_roll_status.len_5_2=1 +fan_roll_status.bit_offset_5_2=2 + +fan_roll_status.mode_6_1=config +fan_roll_status.int_cons_6_1= +fan_roll_status.src_6_1=logic_file +fan_roll_status.frmt_6_1=bit +fan_roll_status.pola_6_1=positive +fan_roll_status.fpath_6_1=/dev/cpld8 +fan_roll_status.addr_6_1=0x5c +fan_roll_status.len_6_1=1 +fan_roll_status.bit_offset_6_1=2 + +fan_roll_status.mode_6_2=config +fan_roll_status.int_cons_6_2= +fan_roll_status.src_6_2=logic_file +fan_roll_status.frmt_6_2=bit +fan_roll_status.pola_6_2=positive +fan_roll_status.fpath_6_2=/dev/cpld8 +fan_roll_status.addr_6_2=0x5d +fan_roll_status.len_6_2=1 +fan_roll_status.bit_offset_6_2=2 + +fan_roll_status.mode_7_1=config +fan_roll_status.int_cons_7_1= +fan_roll_status.src_7_1=logic_file +fan_roll_status.frmt_7_1=bit +fan_roll_status.pola_7_1=positive +fan_roll_status.fpath_7_1=/dev/cpld7 +fan_roll_status.addr_7_1=0x5c +fan_roll_status.len_7_1=1 +fan_roll_status.bit_offset_7_1=3 + +fan_roll_status.mode_7_2=config +fan_roll_status.int_cons_7_2= +fan_roll_status.src_7_2=logic_file +fan_roll_status.frmt_7_2=bit +fan_roll_status.pola_7_2=positive +fan_roll_status.fpath_7_2=/dev/cpld7 +fan_roll_status.addr_7_2=0x5d +fan_roll_status.len_7_2=1 +fan_roll_status.bit_offset_7_2=3 + +fan_roll_status.mode_8_1=config +fan_roll_status.int_cons_8_1= +fan_roll_status.src_8_1=logic_file +fan_roll_status.frmt_8_1=bit +fan_roll_status.pola_8_1=positive +fan_roll_status.fpath_8_1=/dev/cpld8 +fan_roll_status.addr_8_1=0x5c +fan_roll_status.len_8_1=1 +fan_roll_status.bit_offset_8_1=3 + +fan_roll_status.mode_8_2=config +fan_roll_status.int_cons_8_2= +fan_roll_status.src_8_2=logic_file +fan_roll_status.frmt_8_2=bit +fan_roll_status.pola_8_2=positive +fan_roll_status.fpath_8_2=/dev/cpld8 +fan_roll_status.addr_8_2=0x5d +fan_roll_status.len_8_2=1 +fan_roll_status.bit_offset_8_2=3 + +# Configuration items: Fan rotation status CPLD register address +# Description: Format fan_roll_status_[fan_id]_[motor_id] fan_idstart with 1, motor_idstart with 1 +# Note: required +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=logic_file +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1=/dev/cpld7 +fan_speed.addr_1_1=0x94 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_1_2=config +fan_speed.int_cons_1_2= +fan_speed.src_1_2=logic_file +fan_speed.frmt_1_2=num_bytes +fan_speed.pola_1_2=negative +fan_speed.fpath_1_2=/dev/cpld7 +fan_speed.addr_1_2=0xa0 +fan_speed.len_1_2=2 +fan_speed.bit_offset_1_2= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=logic_file +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1=/dev/cpld8 +fan_speed.addr_2_1=0x94 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_2_2=config +fan_speed.int_cons_2_2= +fan_speed.src_2_2=logic_file +fan_speed.frmt_2_2=num_bytes +fan_speed.pola_2_2=negative +fan_speed.fpath_2_2=/dev/cpld8 +fan_speed.addr_2_2=0xa0 +fan_speed.len_2_2=2 +fan_speed.bit_offset_2_2= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=logic_file +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1=/dev/cpld7 +fan_speed.addr_3_1=0x96 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_3_2=config +fan_speed.int_cons_3_2= +fan_speed.src_3_2=logic_file +fan_speed.frmt_3_2=num_bytes +fan_speed.pola_3_2=negative +fan_speed.fpath_3_2=/dev/cpld7 +fan_speed.addr_3_2=0xa2 +fan_speed.len_3_2=2 +fan_speed.bit_offset_3_2= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=logic_file +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1=/dev/cpld8 +fan_speed.addr_4_1=0x96 +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_4_2=config +fan_speed.int_cons_4_2= +fan_speed.src_4_2=logic_file +fan_speed.frmt_4_2=num_bytes +fan_speed.pola_4_2=negative +fan_speed.fpath_4_2=/dev/cpld8 +fan_speed.addr_4_2=0xa2 +fan_speed.len_4_2=2 +fan_speed.bit_offset_4_2= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=logic_file +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1=/dev/cpld7 +fan_speed.addr_5_1=0x98 +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + +fan_speed.mode_5_2=config +fan_speed.int_cons_5_2= +fan_speed.src_5_2=logic_file +fan_speed.frmt_5_2=num_bytes +fan_speed.pola_5_2=negative +fan_speed.fpath_5_2=/dev/cpld7 +fan_speed.addr_5_2=0xa4 +fan_speed.len_5_2=2 +fan_speed.bit_offset_5_2= + +fan_speed.mode_6_1=config +fan_speed.int_cons_6_1= +fan_speed.src_6_1=logic_file +fan_speed.frmt_6_1=num_bytes +fan_speed.pola_6_1=negative +fan_speed.fpath_6_1=/dev/cpld8 +fan_speed.addr_6_1=0x98 +fan_speed.len_6_1=2 +fan_speed.bit_offset_6_1= + +fan_speed.mode_6_2=config +fan_speed.int_cons_6_2= +fan_speed.src_6_2=logic_file +fan_speed.frmt_6_2=num_bytes +fan_speed.pola_6_2=negative +fan_speed.fpath_6_2=/dev/cpld8 +fan_speed.addr_6_2=0xa4 +fan_speed.len_6_2=2 +fan_speed.bit_offset_6_2= + +fan_speed.mode_7_1=config +fan_speed.int_cons_7_1= +fan_speed.src_7_1=logic_file +fan_speed.frmt_7_1=num_bytes +fan_speed.pola_7_1=negative +fan_speed.fpath_7_1=/dev/cpld7 +fan_speed.addr_7_1=0x9a +fan_speed.len_7_1=2 +fan_speed.bit_offset_7_1= + +fan_speed.mode_7_2=config +fan_speed.int_cons_7_2= +fan_speed.src_7_2=logic_file +fan_speed.frmt_7_2=num_bytes +fan_speed.pola_7_2=negative +fan_speed.fpath_7_2=/dev/cpld7 +fan_speed.addr_7_2=0xa6 +fan_speed.len_7_2=2 +fan_speed.bit_offset_7_2= + +fan_speed.mode_8_1=config +fan_speed.int_cons_8_1= +fan_speed.src_8_1=logic_file +fan_speed.frmt_8_1=num_bytes +fan_speed.pola_8_1=negative +fan_speed.fpath_8_1=/dev/cpld8 +fan_speed.addr_8_1=0x9a +fan_speed.len_8_1=2 +fan_speed.bit_offset_8_1= + +fan_speed.mode_8_2=config +fan_speed.int_cons_8_2= +fan_speed.src_8_2=logic_file +fan_speed.frmt_8_2=num_bytes +fan_speed.pola_8_2=negative +fan_speed.fpath_8_2=/dev/cpld8 +fan_speed.addr_8_2=0xa6 +fan_speed.len_8_2=2 +fan_speed.bit_offset_8_2= + +# Configuration items: Fan speed level CPLD register address +# Description: Format fan_ratio_[fan_id]_[motor_id] fan_idstart with 1, motor_idstart with 1 +# Note: required +fan_ratio.mode_1=config +fan_ratio.int_cons_1= +fan_ratio.src_1=logic_file +fan_ratio.frmt_1=byte +fan_ratio.pola_1= +fan_ratio.fpath_1=/dev/cpld7 +fan_ratio.addr_1=0x90 +fan_ratio.len_1=1 +fan_ratio.bit_offset_1= + +fan_ratio.mode_2=config +fan_ratio.int_cons_2= +fan_ratio.src_2=logic_file +fan_ratio.frmt_2=byte +fan_ratio.pola_2= +fan_ratio.fpath_2=/dev/cpld8 +fan_ratio.addr_2=0x90 +fan_ratio.len_2=1 +fan_ratio.bit_offset_2= + +fan_ratio.mode_3=config +fan_ratio.int_cons_3= +fan_ratio.src_3=logic_file +fan_ratio.frmt_3=byte +fan_ratio.pola_3= +fan_ratio.fpath_3=/dev/cpld7 +fan_ratio.addr_3=0x91 +fan_ratio.len_3=1 +fan_ratio.bit_offset_3= + +fan_ratio.mode_4=config +fan_ratio.int_cons_4= +fan_ratio.src_4=logic_file +fan_ratio.frmt_4=byte +fan_ratio.pola_4= +fan_ratio.fpath_4=/dev/cpld8 +fan_ratio.addr_4=0x91 +fan_ratio.len_4=1 +fan_ratio.bit_offset_4= + +fan_ratio.mode_5=config +fan_ratio.int_cons_5= +fan_ratio.src_5=logic_file +fan_ratio.frmt_5=byte +fan_ratio.pola_5= +fan_ratio.fpath_5=/dev/cpld7 +fan_ratio.addr_5=0x92 +fan_ratio.len_5=1 +fan_ratio.bit_offset_5= + +fan_ratio.mode_6=config +fan_ratio.int_cons_6= +fan_ratio.src_6=logic_file +fan_ratio.frmt_6=byte +fan_ratio.pola_6= +fan_ratio.fpath_6=/dev/cpld8 +fan_ratio.addr_6=0x92 +fan_ratio.len_6=1 +fan_ratio.bit_offset_6= + +fan_ratio.mode_7=config +fan_ratio.int_cons_7= +fan_ratio.src_7=logic_file +fan_ratio.frmt_7=byte +fan_ratio.pola_7= +fan_ratio.fpath_7=/dev/cpld7 +fan_ratio.addr_7=0x93 +fan_ratio.len_7=1 +fan_ratio.bit_offset_7= + +fan_ratio.mode_8=config +fan_ratio.int_cons_8= +fan_ratio.src_8=logic_file +fan_ratio.frmt_8=byte +fan_ratio.pola_8= +fan_ratio.fpath_8=/dev/cpld8 +fan_ratio.addr_8=0x93 +fan_ratio.len_8=1 +fan_ratio.bit_offset_8= + +# Fan speed tolerance +fan_threshold_0x0301_0x11=30 +fan_threshold_0x0301_0x12=30 + +# Maximum fan speed +fan_threshold_0x0201_0x11=21600 +fan_threshold_0x0201_0x12=19200 + +# Minimum fan speed +fan_threshold_0x0101_0x11=2880 +fan_threshold_0x0101_0x12=2560 + +# Rated fan speed +fan_threshold_0x1001_0x11=0 +fan_threshold_0x1001_0x12=0 + +fan_threshold_0x1101_0x11=0 +fan_threshold_0x1101_0x12=0 + +fan_threshold_0x1201_0x11=3600 +fan_threshold_0x1201_0x12=3200 + +fan_threshold_0x1301_0x11=5400 +fan_threshold_0x1301_0x12=4800 + +fan_threshold_0x1401_0x11=7200 +fan_threshold_0x1401_0x12=6400 + +fan_threshold_0x1501_0x11=9000 +fan_threshold_0x1501_0x12=8000 + +fan_threshold_0x1601_0x11=10800 +fan_threshold_0x1601_0x12=9600 + +fan_threshold_0x1701_0x11=12600 +fan_threshold_0x1701_0x12=11200 + +fan_threshold_0x1801_0x11=14400 +fan_threshold_0x1801_0x12=12800 + +fan_threshold_0x1901_0x11=16200 +fan_threshold_0x1901_0x12=14400 + +fan_threshold_0x1a01_0x11=18000 +fan_threshold_0x1a01_0x12=16000 + +# Configuration items: the number of fan names displayed in the product +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,FAN is 1, minor_dev, 7: The number of fan names displayed +dev_num_1_7=1 + +# Configuration items: number of fan types supported by each fan name +# Description: Format fan_type_num_[fan type] +# Note: fan_id start with 1 +fan_type_num_1=1 + +# Configuration items: product Fan type Name +# Description: Format fan_name_[index1]_[index2] +# Note: index1 indicates the fan type that is displayed, start with 1, +# index2 Indicates different fan sub_type with the same fan_type, start with 1, correspond to fan_type_num +fan_name_1_1=FAN80-180F-BD + +# Configuration items: fan name is displayed +# Description: Format decode_fan_name_[fan_type] +# Note: fan_type indicates the fan_type of the fan that is displayed +decode_fan_name_1=FAN80-180F-BD diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FPGA.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FPGA.cfg new file mode 100644 index 0000000000..007c82260e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/FPGA.cfg @@ -0,0 +1,131 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + + +# Configuration item: motherboard FPGA number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev: motherboard is 0,daughter card is 5, minor_dev: FPGA is 9 +dev_num_0_9=3 + +# Configuration item: name of each fpga +# Description: Format fpga_name_[fpga_id] fpga_id is fpga number,Start at 0 +# Note: required +fpga_name_0_0=MAC_FPGA +fpga_name_0_1=UPORT_FPGA +fpga_name_0_2=DPORT_FPGA + +# Configuration item: Version register for each FPGA +# Description: Format fpga_version_[fpga_id] fpga_id is fpga number,Start at 0 +# Note: required +fpga_version.mode_0_0=config +fpga_version.int_cons_0_0= +fpga_version.src_0_0=logic_file +fpga_version.frmt_0_0=num_bytes +fpga_version.pola_0_0=negative +fpga_version.fpath_0_0=/dev/fpga0 +fpga_version.addr_0_0=0x0 +fpga_version.len_0_0=4 +fpga_version.bit_offset_0_0= + +fpga_version.mode_0_1=config +fpga_version.int_cons_0_1= +fpga_version.src_0_1=logic_file +fpga_version.frmt_0_1=num_bytes +fpga_version.pola_0_1=negative +fpga_version.fpath_0_1=/dev/fpga1 +fpga_version.addr_0_1=0x0 +fpga_version.len_0_1=4 +fpga_version.bit_offset_0_1= + +fpga_version.mode_0_2=config +fpga_version.int_cons_0_2= +fpga_version.src_0_2=logic_file +fpga_version.frmt_0_2=num_bytes +fpga_version.pola_0_2=negative +fpga_version.fpath_0_2=/dev/fpga2 +fpga_version.addr_0_2=0x0 +fpga_version.len_0_2=4 +fpga_version.bit_offset_0_2= + +# Configuration item: Test registers for each FPGA +# Description: Format fpga_test_reg_[fpga_id] fpga_id is fpga number,Start at 0 +# Note: required +fpga_test_reg.mode_0_0=config +fpga_test_reg.int_cons_0_0= +fpga_test_reg.src_0_0=logic_file +fpga_test_reg.frmt_0_0=num_bytes +fpga_test_reg.pola_0_0=negative +fpga_test_reg.fpath_0_0=/dev/fpga0 +fpga_test_reg.addr_0_0=0x08 +fpga_test_reg.len_0_0=4 +fpga_test_reg.bit_offset_0_0= + +fpga_test_reg.mode_0_1=config +fpga_test_reg.int_cons_0_1= +fpga_test_reg.src_0_1=logic_file +fpga_test_reg.frmt_0_1=num_bytes +fpga_test_reg.pola_0_1=negative +fpga_test_reg.fpath_0_1=/dev/fpga1 +fpga_test_reg.addr_0_1=0x08 +fpga_test_reg.len_0_1=4 +fpga_test_reg.bit_offset_0_1= + +fpga_test_reg.mode_0_2=config +fpga_test_reg.int_cons_0_2= +fpga_test_reg.src_0_2=logic_file +fpga_test_reg.frmt_0_2=num_bytes +fpga_test_reg.pola_0_2=negative +fpga_test_reg.fpath_0_2=/dev/fpga2 +fpga_test_reg.addr_0_2=0x08 +fpga_test_reg.len_0_2=4 +fpga_test_reg.bit_offset_0_2= + +# Configuration item: Device type register for each FPGA +# Description: Format fpga_model_reg_[main_dev]_[fpga_id] +# Note: main_dev: motherboard is 0, daughter card is 5, fpga_id is fpga number,Start at 0 +fpga_model_reg.mode_0_0=config +fpga_model_reg.int_cons_0_0= +fpga_model_reg.src_0_0=logic_file +fpga_model_reg.frmt_0_0=num_bytes +fpga_model_reg.pola_0_0=negative +fpga_model_reg.fpath_0_0=/dev/fpga0 +fpga_model_reg.addr_0_0=0x10 +fpga_model_reg.len_0_0=4 +fpga_model_reg.bit_offset_0_0= + +fpga_model_reg.mode_0_1=config +fpga_model_reg.int_cons_0_1= +fpga_model_reg.src_0_1=logic_file +fpga_model_reg.frmt_0_1=num_bytes +fpga_model_reg.pola_0_1=negative +fpga_model_reg.fpath_0_1=/dev/fpga1 +fpga_model_reg.addr_0_1=0x10 +fpga_model_reg.len_0_1=4 +fpga_model_reg.bit_offset_0_1= + +fpga_model_reg.mode_0_2=config +fpga_model_reg.int_cons_0_2= +fpga_model_reg.src_0_2=logic_file +fpga_model_reg.frmt_0_2=num_bytes +fpga_model_reg.pola_0_2=negative +fpga_model_reg.fpath_0_2=/dev/fpga2 +fpga_model_reg.addr_0_2=0x10 +fpga_model_reg.len_0_2=4 +fpga_model_reg.bit_offset_0_2= + +# Configuration item: Device conversion configuration for each FPGA +# Description: Format fpga_model_decode_[origin_value] +# Note: origin_value is the value read from the FPGA device model register cannot exceed 0xffff +fpga_model_decode_0x50=XC7A50T-2FGG484I +fpga_model_decode_0x100=XC7A100T-2FGG484I + +fpga_vendor_0_0=XILINX +fpga_vendor_0_1=XILINX +fpga_vendor_0_2=XILINX + diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/LED.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/LED.cfg new file mode 100644 index 0000000000..0edec676da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/LED.cfg @@ -0,0 +1,209 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration item: LED CPLD register address +# Description: Formatled_status_[led_id]_[led_index] +# Note: led_id By definition wb_led_t +# led_index:If there is no index, fill in 0. If there is an index (such as a fan light), the number starts from 1 + +# Front panel SYS light +led_status.mode_0_0=config +led_status.src_0_0=logic_file +led_status.frmt_0_0=bit +led_status.fpath_0_0=/dev/cpld1 +led_status.addr_0_0=0x6c +led_status.len_0_0=3 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 0- Front panel SYS light +led_status_decode_0_0=0 +led_status_decode_0_1=7 +led_status_decode_0_2=3 +led_status_decode_0_3=5 +led_status_decode_0_4=1 +led_status_decode_0_5=6 +led_status_decode_0_6=2 +led_status_decode_0_17=5 +led_status_decode_0_18=7 +led_status_decode_0_19=6 +led_status_decode_0_33=5 +led_status_decode_0_34=7 +led_status_decode_0_35=6 +led_status_decode_0_65=5 +led_status_decode_0_66=7 +led_status_decode_0_67=6 +led_status_decode_0_129=5 +led_status_decode_0_130=7 +led_status_decode_0_131=6 +led_status_decode_0_255=0 + +# Front panel BMC light +led_status.mode_2_0=config +led_status.src_2_0=logic_file +led_status.frmt_2_0=bit +led_status.fpath_2_0=/dev/cpld1 +led_status.addr_2_0=0x6d +led_status.len_2_0=3 + +led_status_decode_2_0=0 +led_status_decode_2_1=7 +led_status_decode_2_2=3 +led_status_decode_2_3=5 +led_status_decode_2_4=1 +led_status_decode_2_5=6 +led_status_decode_2_6=2 +led_status_decode_2_7=0 + +# Front panel FAN light +led_status.mode_4_0=config +led_status.src_4_0=logic_file +led_status.frmt_4_0=bit +led_status.fpath_4_0=/dev/cpld1 +led_status.addr_4_0=0x6e +led_status.len_4_0=3 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 4-Front panel FAN light +led_status_decode_4_0=0 +led_status_decode_4_1=7 +led_status_decode_4_2=3 +led_status_decode_4_3=5 +led_status_decode_4_4=1 +led_status_decode_4_5=6 +led_status_decode_4_6=2 +led_status_decode_4_7=0 + +# Front panel PSU light +led_status.mode_6_0=config +led_status.src_6_0=logic_file +led_status.frmt_6_0=bit +led_status.fpath_6_0=/dev/cpld1 +led_status.addr_6_0=0x6f +led_status.len_6_0=3 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 6-Front panel PSU light +led_status_decode_6_0=0 +led_status_decode_6_1=7 +led_status_decode_6_2=3 +led_status_decode_6_3=5 +led_status_decode_6_4=1 +led_status_decode_6_5=6 +led_status_decode_6_6=2 +led_status_decode_6_7=0 + +# Front panel positioning light +led_status.mode_8_0=config +led_status.src_8_0=logic_file +led_status.frmt_8_0=bit +led_status.fpath_8_0=/dev/cpld1 +led_status.addr_8_0=0x6b +led_status.len_8_0=1 + +# Configuration item: The LED light CPLD register value is converted to the standard value +# Description: format led_status_decode_[led_id]_[origin_value] origin_value: indicates the original CPLD value +# led_id defined with LED light type 8- Front panel positioning light +led_status_decode_8_0=0 +led_status_decode_8_1=4 + +# Fan body lamp1 +led_status.mode_10_1=config +led_status.src_10_1=logic_file +led_status.frmt_10_1=bit +led_status.fpath_10_1=/dev/cpld7 +led_status.addr_10_1=0xd0 +led_status.len_10_1=3 + +# Fan body lamp2 +led_status.mode_10_2=config +led_status.src_10_2=logic_file +led_status.frmt_10_2=bit +led_status.fpath_10_2=/dev/cpld8 +led_status.addr_10_2=0xd0 +led_status.len_10_2=3 + +# Fan body lamp3 +led_status.mode_10_3=config +led_status.src_10_3=logic_file +led_status.frmt_10_3=bit +led_status.fpath_10_3=/dev/cpld7 +led_status.addr_10_3=0xd1 +led_status.len_10_3=3 + +# Fan body lamp4 +led_status.mode_10_4=config +led_status.src_10_4=logic_file +led_status.frmt_10_4=bit +led_status.fpath_10_4=/dev/cpld8 +led_status.addr_10_4=0xd1 +led_status.len_10_4=3 + +# Fan body lamp5 +led_status.mode_10_5=config +led_status.src_10_5=logic_file +led_status.frmt_10_5=bit +led_status.fpath_10_5=/dev/cpld7 +led_status.addr_10_5=0xd2 +led_status.len_10_5=3 + +# Fan body lamp6 +led_status.mode_10_6=config +led_status.src_10_6=logic_file +led_status.frmt_10_6=bit +led_status.fpath_10_6=/dev/cpld8 +led_status.addr_10_6=0xd2 +led_status.len_10_6=3 + +# Fan body lamp7 +led_status.mode_10_7=config +led_status.src_10_7=logic_file +led_status.frmt_10_7=bit +led_status.fpath_10_7=/dev/cpld7 +led_status.addr_10_7=0xd3 +led_status.len_10_7=3 + +# Fan body lamp8 +led_status.mode_10_8=config +led_status.src_10_8=logic_file +led_status.frmt_10_8=bit +led_status.fpath_10_8=/dev/cpld8 +led_status.addr_10_8=0xd3 +led_status.len_10_8=3 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 10-Fan body lamp +led_status_decode_10_0=0 +led_status_decode_10_1=7 +led_status_decode_10_2=3 +led_status_decode_10_3=5 +led_status_decode_10_4=1 +led_status_decode_10_5=6 +led_status_decode_10_6=2 + + +# Front sfp light +led_status.mode_13_0=config +led_status.src_13_0=logic_file +led_status.frmt_13_0=bit +led_status.fpath_13_0=/dev/cpld1 +led_status.addr_13_0=0x6b +led_status.len_13_0=3 + +led_status_decode_13_0=0 +led_status_decode_13_1=7 +led_status_decode_13_2=3 +led_status_decode_13_3=5 +led_status_decode_13_4=1 +led_status_decode_13_5=6 +led_status_decode_13_6=2 +led_status_decode_13_7=0 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/PSU.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/PSU.cfg new file mode 100644 index 0000000000..cb63114f18 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/PSU.cfg @@ -0,0 +1,1179 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration items: PSU number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev,0 indicates the obtained number +dev_num_2_0=4 + +# Configuration items: PSU temperature sensors number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev, 1:temperature +dev_num_2_1=1 + +# psu eeprom +eeprom_size_2_1=256 +eeprom_size_2_2=256 +eeprom_size_2_3=256 +eeprom_size_2_4=256 + +eeprom_path_2_1=/sys/bus/i2c/devices/67-0050/eeprom +eeprom_path_2_2=/sys/bus/i2c/devices/68-0050/eeprom +eeprom_path_2_3=/sys/bus/i2c/devices/69-0050/eeprom +eeprom_path_2_4=/sys/bus/i2c/devices/70-0050/eeprom + +# Configuration item: Method of reading power FRU information +# Description: Format psu_fru_mode +# Note: If not configured, read through EEPROM, otherwise read through pmbus + + +# Configuration item: Method of reading power FRU information +# Fill in the description: format psu_fru_pmbus_[psu_index]_[fruid] +# Note: psu_index: indicates the power supply number, starting from 1 +# Note: fruid: 3:serial_number(mfr_serial), 5:hardware_version(mfr_revision), 8:part_number(mfr_model), 12:date(mfr_date), 13:vendor(mfr_id), +# mfr_serial +psu_fru_pmbus.mode_1_3=config +psu_fru_pmbus.int_cons_1_3=0 +psu_fru_pmbus.src_1_3=file +psu_fru_pmbus.frmt_1_3=buf +psu_fru_pmbus.fpath_1_3=/sys/bus/i2c/devices/67-0058/mfr_serial +psu_fru_pmbus.addr_1_3=0 +psu_fru_pmbus.len_1_3=32 +psu_fru_pmbus.bit_offset_1_3= +psu_fru_pmbus.str_cons_1_3= + +# mfr_revision +psu_fru_pmbus.mode_1_5=config +psu_fru_pmbus.int_cons_1_5=0 +psu_fru_pmbus.src_1_5=file +psu_fru_pmbus.frmt_1_5=buf +psu_fru_pmbus.fpath_1_5=/sys/bus/i2c/devices/67-0058/mfr_revision +psu_fru_pmbus.addr_1_5=0 +psu_fru_pmbus.len_1_5=32 +psu_fru_pmbus.bit_offset_1_5= +psu_fru_pmbus.str_cons_1_5= + +# mfr_model +psu_fru_pmbus.mode_1_8=config +psu_fru_pmbus.int_cons_1_8=0 +psu_fru_pmbus.src_1_8=file +psu_fru_pmbus.frmt_1_8=buf +psu_fru_pmbus.fpath_1_8=/sys/bus/i2c/devices/67-0058/mfr_model +psu_fru_pmbus.addr_1_8=0 +psu_fru_pmbus.len_1_8=32 +psu_fru_pmbus.bit_offset_1_8= +psu_fru_pmbus.str_cons_1_8= + +# mfr_date +psu_fru_pmbus.mode_1_12=config +psu_fru_pmbus.int_cons_1_12=0 +psu_fru_pmbus.src_1_12=file +psu_fru_pmbus.frmt_1_12=buf +psu_fru_pmbus.fpath_1_12=/sys/bus/i2c/devices/67-0058/mfr_date +psu_fru_pmbus.addr_1_12=0 +psu_fru_pmbus.len_1_12=32 +psu_fru_pmbus.bit_offset_1_12= +psu_fru_pmbus.str_cons_1_12= + +# mfr_id +psu_fru_pmbus.mode_1_13=config +psu_fru_pmbus.int_cons_1_13=0 +psu_fru_pmbus.src_1_13=file +psu_fru_pmbus.frmt_1_13=buf +psu_fru_pmbus.fpath_1_13=/sys/bus/i2c/devices/67-0058/mfr_id +psu_fru_pmbus.addr_1_13=0 +psu_fru_pmbus.len_1_13=32 +psu_fru_pmbus.bit_offset_1_13= +psu_fru_pmbus.str_cons_1_13= + + +# mfr_serial +psu_fru_pmbus.mode_2_3=config +psu_fru_pmbus.int_cons_2_3=0 +psu_fru_pmbus.src_2_3=file +psu_fru_pmbus.frmt_2_3=buf +psu_fru_pmbus.fpath_2_3=/sys/bus/i2c/devices/68-0058/mfr_serial +psu_fru_pmbus.addr_2_3=0 +psu_fru_pmbus.len_2_3=32 +psu_fru_pmbus.bit_offset_2_3= +psu_fru_pmbus.str_cons_2_3= + +# mfr_revision +psu_fru_pmbus.mode_2_5=config +psu_fru_pmbus.int_cons_2_5=0 +psu_fru_pmbus.src_2_5=file +psu_fru_pmbus.frmt_2_5=buf +psu_fru_pmbus.fpath_2_5=/sys/bus/i2c/devices/68-0058/mfr_revision +psu_fru_pmbus.addr_2_5=0 +psu_fru_pmbus.len_2_5=32 +psu_fru_pmbus.bit_offset_2_5= +psu_fru_pmbus.str_cons_2_5= + +# mfr_model +psu_fru_pmbus.mode_2_8=config +psu_fru_pmbus.int_cons_2_8=0 +psu_fru_pmbus.src_2_8=file +psu_fru_pmbus.frmt_2_8=buf +psu_fru_pmbus.fpath_2_8=/sys/bus/i2c/devices/68-0058/mfr_model +psu_fru_pmbus.addr_2_8=0 +psu_fru_pmbus.len_2_8=32 +psu_fru_pmbus.bit_offset_2_8= +psu_fru_pmbus.str_cons_2_8= + +# mfr_date +psu_fru_pmbus.mode_2_12=config +psu_fru_pmbus.int_cons_2_12=0 +psu_fru_pmbus.src_2_12=file +psu_fru_pmbus.frmt_2_12=buf +psu_fru_pmbus.fpath_2_12=/sys/bus/i2c/devices/68-0058/mfr_date +psu_fru_pmbus.addr_2_12=0 +psu_fru_pmbus.len_2_12=32 +psu_fru_pmbus.bit_offset_2_12= +psu_fru_pmbus.str_cons_2_12= + +# mfr_id +psu_fru_pmbus.mode_2_13=config +psu_fru_pmbus.int_cons_2_13=0 +psu_fru_pmbus.src_2_13=file +psu_fru_pmbus.frmt_2_13=buf +psu_fru_pmbus.fpath_2_13=/sys/bus/i2c/devices/68-0058/mfr_id +psu_fru_pmbus.addr_2_13=0 +psu_fru_pmbus.len_2_13=32 +psu_fru_pmbus.bit_offset_2_13= +psu_fru_pmbus.str_cons_2_13= + + +# mfr_serial +psu_fru_pmbus.mode_3_3=config +psu_fru_pmbus.int_cons_3_3=0 +psu_fru_pmbus.src_3_3=file +psu_fru_pmbus.frmt_3_3=buf +psu_fru_pmbus.fpath_3_3=/sys/bus/i2c/devices/69-0058/mfr_serial +psu_fru_pmbus.addr_3_3=0 +psu_fru_pmbus.len_3_3=32 +psu_fru_pmbus.bit_offset_3_3= +psu_fru_pmbus.str_cons_3_3= + +# mfr_revision +psu_fru_pmbus.mode_3_5=config +psu_fru_pmbus.int_cons_3_5=0 +psu_fru_pmbus.src_3_5=file +psu_fru_pmbus.frmt_3_5=buf +psu_fru_pmbus.fpath_3_5=/sys/bus/i2c/devices/69-0058/mfr_revision +psu_fru_pmbus.addr_3_5=0 +psu_fru_pmbus.len_3_5=32 +psu_fru_pmbus.bit_offset_3_5= +psu_fru_pmbus.str_cons_3_5= + +# mfr_model +psu_fru_pmbus.mode_3_8=config +psu_fru_pmbus.int_cons_3_8=0 +psu_fru_pmbus.src_3_8=file +psu_fru_pmbus.frmt_3_8=buf +psu_fru_pmbus.fpath_3_8=/sys/bus/i2c/devices/69-0058/mfr_model +psu_fru_pmbus.addr_3_8=0 +psu_fru_pmbus.len_3_8=32 +psu_fru_pmbus.bit_offset_3_8= +psu_fru_pmbus.str_cons_3_8= + +# mfr_date +psu_fru_pmbus.mode_3_12=config +psu_fru_pmbus.int_cons_3_12=0 +psu_fru_pmbus.src_3_12=file +psu_fru_pmbus.frmt_3_12=buf +psu_fru_pmbus.fpath_3_12=/sys/bus/i2c/devices/69-0058/mfr_date +psu_fru_pmbus.addr_3_12=0 +psu_fru_pmbus.len_3_12=32 +psu_fru_pmbus.bit_offset_3_12= +psu_fru_pmbus.str_cons_3_12= + +# mfr_id +psu_fru_pmbus.mode_3_13=config +psu_fru_pmbus.int_cons_3_13=0 +psu_fru_pmbus.src_3_13=file +psu_fru_pmbus.frmt_3_13=buf +psu_fru_pmbus.fpath_3_13=/sys/bus/i2c/devices/69-0058/mfr_id +psu_fru_pmbus.addr_3_13=0 +psu_fru_pmbus.len_3_13=32 +psu_fru_pmbus.bit_offset_3_13= +psu_fru_pmbus.str_cons_3_13= + + +# mfr_serial +psu_fru_pmbus.mode_4_3=config +psu_fru_pmbus.int_cons_4_3=0 +psu_fru_pmbus.src_4_3=file +psu_fru_pmbus.frmt_4_3=buf +psu_fru_pmbus.fpath_4_3=/sys/bus/i2c/devices/70-0058/mfr_serial +psu_fru_pmbus.addr_4_3=0 +psu_fru_pmbus.len_4_3=32 +psu_fru_pmbus.bit_offset_4_3= +psu_fru_pmbus.str_cons_4_3= + +# mfr_revision +psu_fru_pmbus.mode_4_5=config +psu_fru_pmbus.int_cons_4_5=0 +psu_fru_pmbus.src_4_5=file +psu_fru_pmbus.frmt_4_5=buf +psu_fru_pmbus.fpath_4_5=/sys/bus/i2c/devices/70-0058/mfr_revision +psu_fru_pmbus.addr_4_5=0 +psu_fru_pmbus.len_4_5=32 +psu_fru_pmbus.bit_offset_4_5= +psu_fru_pmbus.str_cons_4_5= + +# mfr_model +psu_fru_pmbus.mode_4_8=config +psu_fru_pmbus.int_cons_4_8=0 +psu_fru_pmbus.src_4_8=file +psu_fru_pmbus.frmt_4_8=buf +psu_fru_pmbus.fpath_4_8=/sys/bus/i2c/devices/70-0058/mfr_model +psu_fru_pmbus.addr_4_8=0 +psu_fru_pmbus.len_4_8=32 +psu_fru_pmbus.bit_offset_4_8= +psu_fru_pmbus.str_cons_4_8= + +# mfr_date +psu_fru_pmbus.mode_4_12=config +psu_fru_pmbus.int_cons_4_12=0 +psu_fru_pmbus.src_4_12=file +psu_fru_pmbus.frmt_4_12=buf +psu_fru_pmbus.fpath_4_12=/sys/bus/i2c/devices/70-0058/mfr_date +psu_fru_pmbus.addr_4_12=0 +psu_fru_pmbus.len_4_12=32 +psu_fru_pmbus.bit_offset_4_12= +psu_fru_pmbus.str_cons_4_12= + +# mfr_id +psu_fru_pmbus.mode_4_13=config +psu_fru_pmbus.int_cons_4_13=0 +psu_fru_pmbus.src_4_13=file +psu_fru_pmbus.frmt_4_13=buf +psu_fru_pmbus.fpath_4_13=/sys/bus/i2c/devices/70-0058/mfr_id +psu_fru_pmbus.addr_4_13=0 +psu_fru_pmbus.len_4_13=32 +psu_fru_pmbus.bit_offset_4_13= +psu_fru_pmbus.str_cons_4_13= + +# Configuration items: PSU E2 information +# Description: Format other_i2c_dev_[main_dev]_[psu_index] +# Note: main_dev,PSU is 2, psu_index:Power supply number, start with 1 +other_i2c_dev.bus_2_1=67 +other_i2c_dev.addr_2_1=0x50 +other_i2c_dev.bus_2_2=68 +other_i2c_dev.addr_2_2=0x50 +other_i2c_dev.bus_2_3=69 +other_i2c_dev.addr_2_3=0x50 +other_i2c_dev.bus_2_4=70 +other_i2c_dev.addr_2_4=0x50 + +# Configuration items: Mode of reading power supply E2 +# Description: Format psu_sysfs_name +# Note: If not configured, it is read by i2c, otherwise it is read by sysfs +psu_sysfs_name=eeprom + +other_i2c_dev.bus_2_5=67 +other_i2c_dev.addr_2_5=0x58 +other_i2c_dev.bus_2_6=68 +other_i2c_dev.addr_2_6=0x58 +other_i2c_dev.bus_2_7=69 +other_i2c_dev.addr_2_7=0x58 +other_i2c_dev.bus_2_8=70 +other_i2c_dev.addr_2_8=0x58 + +# Configuration items: PMBUS register address of the power supply +# Description: Format psu_status_[psu_index]_[reg_id] +# Note:psu_index:Power supply number,start with 1 reg_id, 9:Power Output Status (0x79) +psu_pmbus_reg.mode_1_9=config +psu_pmbus_reg.src_1_9=other_i2c +psu_pmbus_reg.frmt_1_9=byte +psu_pmbus_reg.pola_1_9=negative +psu_pmbus_reg.addr_1_9=0x02050079 +psu_pmbus_reg.len_1_9=2 +psu_pmbus_reg.bit_offset_1_9= + +psu_pmbus_reg.mode_2_9=config +psu_pmbus_reg.src_2_9=other_i2c +psu_pmbus_reg.frmt_2_9=byte +psu_pmbus_reg.pola_2_9=negative +psu_pmbus_reg.addr_2_9=0x02060079 +psu_pmbus_reg.len_2_9=2 +psu_pmbus_reg.bit_offset_2_9= + +psu_pmbus_reg.mode_3_9=config +psu_pmbus_reg.src_3_9=other_i2c +psu_pmbus_reg.frmt_3_9=byte +psu_pmbus_reg.pola_3_9=negative +psu_pmbus_reg.addr_3_9=0x02070079 +psu_pmbus_reg.len_3_9=2 +psu_pmbus_reg.bit_offset_3_9= + +psu_pmbus_reg.mode_4_9=config +psu_pmbus_reg.src_4_9=other_i2c +psu_pmbus_reg.frmt_4_9=byte +psu_pmbus_reg.pola_4_9=negative +psu_pmbus_reg.addr_4_9=0x02080079 +psu_pmbus_reg.len_4_9=2 +psu_pmbus_reg.bit_offset_4_9= + +# Configuration items:PMBUS register address of the power supply +# Description: Format psu_status_[psu_index]_[reg_id] +# Note:psu_index:Power supply number,start with 1 reg_id, 10:Power input Status (0x79) +psu_pmbus_reg.mode_1_10=config +psu_pmbus_reg.src_1_10=other_i2c +psu_pmbus_reg.frmt_1_10=byte +psu_pmbus_reg.pola_1_10=negative +psu_pmbus_reg.addr_1_10=0x02050079 +psu_pmbus_reg.len_1_10=2 +psu_pmbus_reg.bit_offset_1_10= + +psu_pmbus_reg.mode_2_10=config +psu_pmbus_reg.src_2_10=other_i2c +psu_pmbus_reg.frmt_2_10=byte +psu_pmbus_reg.pola_2_10=negative +psu_pmbus_reg.addr_2_10=0x02060079 +psu_pmbus_reg.len_2_10=2 +psu_pmbus_reg.bit_offset_2_10= + +psu_pmbus_reg.mode_3_10=config +psu_pmbus_reg.src_3_10=other_i2c +psu_pmbus_reg.frmt_3_10=byte +psu_pmbus_reg.pola_3_10=negative +psu_pmbus_reg.addr_3_10=0x02070079 +psu_pmbus_reg.len_3_10=2 +psu_pmbus_reg.bit_offset_3_10= + +psu_pmbus_reg.mode_4_10=config +psu_pmbus_reg.src_4_10=other_i2c +psu_pmbus_reg.frmt_4_10=byte +psu_pmbus_reg.pola_4_10=negative +psu_pmbus_reg.addr_4_10=0x02080079 +psu_pmbus_reg.len_4_10=2 +psu_pmbus_reg.bit_offset_4_10= + +# Configuration items:PMBUS register address of the power supply +# Description: Format psu_status_[psu_index]_[reg_id] +# Note:psu_index:Power supply number,,start with 1 reg_id 11:Power Input type (0x80) +psu_pmbus_reg.mode_1_11=config +psu_pmbus_reg.src_1_11=other_i2c +psu_pmbus_reg.frmt_1_11=byte +psu_pmbus_reg.pola_1_11=positive +psu_pmbus_reg.addr_1_11=0x02050080 +psu_pmbus_reg.len_1_11=1 +psu_pmbus_reg.bit_offset_1_11= + +psu_pmbus_reg.mode_2_11=config +psu_pmbus_reg.src_2_11=other_i2c +psu_pmbus_reg.frmt_2_11=byte +psu_pmbus_reg.pola_2_11=positive +psu_pmbus_reg.addr_2_11=0x02060080 +psu_pmbus_reg.len_2_11=1 +psu_pmbus_reg.bit_offset_2_11= + +psu_pmbus_reg.mode_3_11=config +psu_pmbus_reg.src_3_11=other_i2c +psu_pmbus_reg.frmt_3_11=byte +psu_pmbus_reg.pola_3_11=positive +psu_pmbus_reg.addr_3_11=0x02070080 +psu_pmbus_reg.len_3_11=1 +psu_pmbus_reg.bit_offset_3_11= + +psu_pmbus_reg.mode_4_11=config +psu_pmbus_reg.src_4_11=other_i2c +psu_pmbus_reg.frmt_4_11=byte +psu_pmbus_reg.pola_4_11=positive +psu_pmbus_reg.addr_4_11=0x02080080 +psu_pmbus_reg.len_4_11=1 +psu_pmbus_reg.bit_offset_4_11= + +psu_pmbus_reg.mode_1_12=config +psu_pmbus_reg.src_1_12=other_i2c +psu_pmbus_reg.frmt_1_12=byte +psu_pmbus_reg.pola_1_12=positive +psu_pmbus_reg.addr_1_12=0x0205003b +psu_pmbus_reg.len_1_12=1 +psu_pmbus_reg.bit_offset_1_12= + +psu_pmbus_reg.mode_2_12=config +psu_pmbus_reg.src_2_12=other_i2c +psu_pmbus_reg.frmt_2_12=byte +psu_pmbus_reg.pola_2_12=positive +psu_pmbus_reg.addr_2_12=0x0206003b +psu_pmbus_reg.len_2_12=1 +psu_pmbus_reg.bit_offset_2_12= + +psu_pmbus_reg.mode_3_12=config +psu_pmbus_reg.src_3_12=other_i2c +psu_pmbus_reg.frmt_3_12=byte +psu_pmbus_reg.pola_3_12=positive +psu_pmbus_reg.addr_3_12=0x0207003b +psu_pmbus_reg.len_3_12=1 +psu_pmbus_reg.bit_offset_3_12= + +psu_pmbus_reg.mode_4_12=config +psu_pmbus_reg.src_4_12=other_i2c +psu_pmbus_reg.frmt_4_12=byte +psu_pmbus_reg.pola_4_12=positive +psu_pmbus_reg.addr_4_12=0x0208003b +psu_pmbus_reg.len_4_12=1 +psu_pmbus_reg.bit_offset_4_12= + +# Configuration items: PSU number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev,0 indicates the obtained number +dev_num_2_0=4 + +# Configuration items: Input status of the power module +# Description: Format psu_pmbus_id_[psu_index]_[psu_sensor_type]=value +# Note: psu_index is Power supply number,start with 1, psu_sensor_type is PMBUS type,Input stateis 10 +# value value:bus[8]_addr[16]_offset[8] +psu_status.mode_1_0=config +psu_status.src_1_0=logic_file +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.fpath_1_0=/dev/cpld4 +psu_status.addr_1_0=0x57 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=1 + +psu_status.mode_1_1=config +psu_status.src_1_1=logic_file +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.fpath_1_1=/dev/cpld4 +psu_status.addr_1_1=0x57 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=0 + +psu_status.mode_1_2=config +psu_status.src_1_2=logic_file +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.fpath_1_2=/dev/cpld4 +psu_status.addr_1_2=0x57 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +psu_status.mode_2_0=config +psu_status.src_2_0=logic_file +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.fpath_2_0=/dev/cpld4 +psu_status.addr_2_0=0x57 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=5 + +psu_status.mode_2_1=config +psu_status.src_2_1=logic_file +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.fpath_2_1=/dev/cpld4 +psu_status.addr_2_1=0x57 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=4 + +psu_status.mode_2_2=config +psu_status.src_2_2=logic_file +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.fpath_2_2=/dev/cpld4 +psu_status.addr_2_2=0x57 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 + +psu_status.mode_3_0=config +psu_status.src_3_0=logic_file +psu_status.frmt_3_0=bit +psu_status.pola_3_0=negative +psu_status.fpath_3_0=/dev/cpld4 +psu_status.addr_3_0=0x58 +psu_status.len_3_0=1 +psu_status.bit_offset_3_0=1 + +psu_status.mode_3_1=config +psu_status.src_3_1=logic_file +psu_status.frmt_3_1=bit +psu_status.pola_3_1=positive +psu_status.fpath_3_1=/dev/cpld4 +psu_status.addr_3_1=0x58 +psu_status.len_3_1=1 +psu_status.bit_offset_3_1=0 + +psu_status.mode_3_2=config +psu_status.src_3_2=logic_file +psu_status.frmt_3_2=bit +psu_status.pola_3_2=negative +psu_status.fpath_3_2=/dev/cpld4 +psu_status.addr_3_2=0x58 +psu_status.len_3_2=1 +psu_status.bit_offset_3_2=2 + +psu_status.mode_4_0=config +psu_status.src_4_0=logic_file +psu_status.frmt_4_0=bit +psu_status.pola_4_0=negative +psu_status.fpath_4_0=/dev/cpld4 +psu_status.addr_4_0=0x58 +psu_status.len_4_0=1 +psu_status.bit_offset_4_0=5 + +psu_status.mode_4_1=config +psu_status.src_4_1=logic_file +psu_status.frmt_4_1=bit +psu_status.pola_4_1=positive +psu_status.fpath_4_1=/dev/cpld4 +psu_status.addr_4_1=0x58 +psu_status.len_4_1=1 +psu_status.bit_offset_4_1=4 + +psu_status.mode_4_2=config +psu_status.src_4_2=logic_file +psu_status.frmt_4_2=bit +psu_status.pola_4_2=negative +psu_status.fpath_4_2=/dev/cpld4 +psu_status.addr_4_2=0x58 +psu_status.len_4_2=1 +psu_status.bit_offset_4_2=6 + + +# 0:None 1:in_vol 2:in_curr 3:in_power 4:out_vol 5:out_curr 6:out_power 7:fan +# psu1 in_vol +hwmon_psu.mode_1_1=config +hwmon_psu.int_cons_1_1=0 +hwmon_psu.src_1_1=file +hwmon_psu.frmt_1_1=buf +hwmon_psu.fpath_1_1=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_1=0 +hwmon_psu.len_1_1=8 +hwmon_psu.bit_offset_1_1= +hwmon_psu.str_cons_1_1=in1_input + +# psu1 in_curr +hwmon_psu.mode_1_2=config +hwmon_psu.int_cons_1_2=0 +hwmon_psu.src_1_2=file +hwmon_psu.frmt_1_2=buf +hwmon_psu.fpath_1_2=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_2=0 +hwmon_psu.len_1_2=8 +hwmon_psu.bit_offset_1_2= +hwmon_psu.str_cons_1_2=curr1_input + +# psu1 in_power +hwmon_psu.mode_1_3=config +hwmon_psu.int_cons_1_3=0 +hwmon_psu.src_1_3=file +hwmon_psu.frmt_1_3=buf +hwmon_psu.fpath_1_3=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_3=0 +hwmon_psu.len_1_3=16 +hwmon_psu.bit_offset_1_3=0 +hwmon_psu.str_cons_1_3=power1_input + +# psu1 out_vol +hwmon_psu.mode_1_4=config +hwmon_psu.int_cons_1_4=0 +hwmon_psu.src_1_4=file +hwmon_psu.frmt_1_4=buf +hwmon_psu.fpath_1_4=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_4=0 +hwmon_psu.len_1_4=8 +hwmon_psu.bit_offset_1_4= +hwmon_psu.str_cons_1_4=in2_input + +# psu1 out_curr +hwmon_psu.mode_1_5=config +hwmon_psu.int_cons_1_5=0 +hwmon_psu.src_1_5=file +hwmon_psu.frmt_1_5=buf +hwmon_psu.fpath_1_5=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_5=0 +hwmon_psu.len_1_5=8 +hwmon_psu.bit_offset_1_5= +hwmon_psu.str_cons_1_5=curr2_input + +# psu1 out_power +hwmon_psu.mode_1_6=config +hwmon_psu.int_cons_1_6=0 +hwmon_psu.src_1_6=file +hwmon_psu.frmt_1_6=buf +hwmon_psu.fpath_1_6=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_6=0 +hwmon_psu.len_1_6=16 +hwmon_psu.bit_offset_1_6=0 +hwmon_psu.str_cons_1_6=power2_input + +# psu1 fan +hwmon_psu.mode_1_7=config +hwmon_psu.int_cons_1_7= +hwmon_psu.src_1_7=file +hwmon_psu.frmt_1_7=buf +hwmon_psu.fpath_1_7=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_psu.addr_1_7=0 +hwmon_psu.len_1_7=8 +hwmon_psu.bit_offset_1_7= +hwmon_psu.str_cons_1_7=fan1_input + +# psu2 in_vol +hwmon_psu.mode_2_1=config +hwmon_psu.int_cons_2_1=0 +hwmon_psu.src_2_1=file +hwmon_psu.frmt_2_1=buf +hwmon_psu.fpath_2_1=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_1=0 +hwmon_psu.len_2_1=8 +hwmon_psu.bit_offset_2_1= +hwmon_psu.str_cons_2_1=in1_input + +# psu2 in_curr +hwmon_psu.mode_2_2=config +hwmon_psu.int_cons_2_2=0 +hwmon_psu.src_2_2=file +hwmon_psu.frmt_2_2=buf +hwmon_psu.fpath_2_2=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_2=0 +hwmon_psu.len_2_2=8 +hwmon_psu.bit_offset_2_2= +hwmon_psu.str_cons_2_2=curr1_input + +# psu2 in_power +hwmon_psu.mode_2_3=config +hwmon_psu.int_cons_2_3=0 +hwmon_psu.src_2_3=file +hwmon_psu.frmt_2_3=buf +hwmon_psu.fpath_2_3=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_3=0 +hwmon_psu.len_2_3=16 +hwmon_psu.bit_offset_2_3=0 +hwmon_psu.str_cons_2_3=power1_input + +# psu2 out_vol +hwmon_psu.mode_2_4=config +hwmon_psu.int_cons_2_4=0 +hwmon_psu.src_2_4=file +hwmon_psu.frmt_2_4=buf +hwmon_psu.fpath_2_4=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_4=0 +hwmon_psu.len_2_4=8 +hwmon_psu.bit_offset_2_4= +hwmon_psu.str_cons_2_4=in2_input + +# psu2 out_curr +hwmon_psu.mode_2_5=config +hwmon_psu.int_cons_2_5=0 +hwmon_psu.src_2_5=file +hwmon_psu.frmt_2_5=buf +hwmon_psu.fpath_2_5=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_5=0 +hwmon_psu.len_2_5=8 +hwmon_psu.bit_offset_2_5= +hwmon_psu.str_cons_2_5=curr2_input + +# psu2 out_power +hwmon_psu.mode_2_6=config +hwmon_psu.int_cons_2_6=0 +hwmon_psu.src_2_6=file +hwmon_psu.frmt_2_6=buf +hwmon_psu.fpath_2_6=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_6=0 +hwmon_psu.len_2_6=16 +hwmon_psu.bit_offset_2_6=0 +hwmon_psu.str_cons_2_6=power2_input + +# psu2 fan +hwmon_psu.mode_2_7=config +hwmon_psu.int_cons_2_7= +hwmon_psu.src_2_7=file +hwmon_psu.frmt_2_7=buf +hwmon_psu.fpath_2_7=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_psu.addr_2_7=0 +hwmon_psu.len_2_7=8 +hwmon_psu.bit_offset_2_7= +hwmon_psu.str_cons_2_7=fan1_input + +# psu3 in_vol +hwmon_psu.mode_3_1=config +hwmon_psu.int_cons_3_1=0 +hwmon_psu.src_3_1=file +hwmon_psu.frmt_3_1=buf +hwmon_psu.fpath_3_1=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_1=0 +hwmon_psu.len_3_1=8 +hwmon_psu.bit_offset_3_1= +hwmon_psu.str_cons_3_1=in1_input +# psu3 in_curr +hwmon_psu.mode_3_2=config +hwmon_psu.int_cons_3_2=0 +hwmon_psu.src_3_2=file +hwmon_psu.frmt_3_2=buf +hwmon_psu.fpath_3_2=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_2=0 +hwmon_psu.len_3_2=8 +hwmon_psu.bit_offset_3_2= +hwmon_psu.str_cons_3_2=curr1_input + +# psu3 in_power +hwmon_psu.mode_3_3=config +hwmon_psu.int_cons_3_3=0 +hwmon_psu.src_3_3=file +hwmon_psu.frmt_3_3=buf +hwmon_psu.fpath_3_3=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_3=0 +hwmon_psu.len_3_3=16 +hwmon_psu.bit_offset_3_3=0 +hwmon_psu.str_cons_3_3=power1_input + +# psu3 out_vol +hwmon_psu.mode_3_4=config +hwmon_psu.int_cons_3_4=0 +hwmon_psu.src_3_4=file +hwmon_psu.frmt_3_4=buf +hwmon_psu.fpath_3_4=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_4=0 +hwmon_psu.len_3_4=8 +hwmon_psu.bit_offset_3_4= +hwmon_psu.str_cons_3_4=in2_input + +# psu3 out_curr +hwmon_psu.mode_3_5=config +hwmon_psu.int_cons_3_5=0 +hwmon_psu.src_3_5=file +hwmon_psu.frmt_3_5=buf +hwmon_psu.fpath_3_5=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_5=0 +hwmon_psu.len_3_5=8 +hwmon_psu.bit_offset_3_5= +hwmon_psu.str_cons_3_5=curr2_input + +# psu3 out_power +hwmon_psu.mode_3_6=config +hwmon_psu.int_cons_3_6=0 +hwmon_psu.src_3_6=file +hwmon_psu.frmt_3_6=buf +hwmon_psu.fpath_3_6=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_6=0 +hwmon_psu.len_3_6=16 +hwmon_psu.bit_offset_3_6=0 +hwmon_psu.str_cons_3_6=power2_input + +# psu3 fan +hwmon_psu.mode_3_7=config +hwmon_psu.int_cons_3_7= +hwmon_psu.src_3_7=file +hwmon_psu.frmt_3_7=buf +hwmon_psu.fpath_3_7=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_psu.addr_3_7=0 +hwmon_psu.len_3_7=8 +hwmon_psu.bit_offset_3_7= +hwmon_psu.str_cons_3_7=fan1_input + +# psu4 in_vol +hwmon_psu.mode_4_1=config +hwmon_psu.int_cons_4_1=0 +hwmon_psu.src_4_1=file +hwmon_psu.frmt_4_1=buf +hwmon_psu.fpath_4_1=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_1=0 +hwmon_psu.len_4_1=8 +hwmon_psu.bit_offset_4_1= +hwmon_psu.str_cons_4_1=in1_input + +# psu4 in_curr +hwmon_psu.mode_4_2=config +hwmon_psu.int_cons_4_2=0 +hwmon_psu.src_4_2=file +hwmon_psu.frmt_4_2=buf +hwmon_psu.fpath_4_2=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_2=0 +hwmon_psu.len_4_2=8 +hwmon_psu.bit_offset_4_2= +hwmon_psu.str_cons_4_2=curr1_input + +# psu4 in_power +hwmon_psu.mode_4_3=config +hwmon_psu.int_cons_4_3=0 +hwmon_psu.src_4_3=file +hwmon_psu.frmt_4_3=buf +hwmon_psu.fpath_4_3=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_3=0 +hwmon_psu.len_4_3=16 +hwmon_psu.bit_offset_4_3=0 +hwmon_psu.str_cons_4_3=power1_input + +# psu4 out_vol +hwmon_psu.mode_4_4=config +hwmon_psu.int_cons_4_4=0 +hwmon_psu.src_4_4=file +hwmon_psu.frmt_4_4=buf +hwmon_psu.fpath_4_4=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_4=0 +hwmon_psu.len_4_4=8 +hwmon_psu.bit_offset_4_4= +hwmon_psu.str_cons_4_4=in2_input + +# psu4 out_curr +hwmon_psu.mode_4_5=config +hwmon_psu.int_cons_4_5=0 +hwmon_psu.src_4_5=file +hwmon_psu.frmt_4_5=buf +hwmon_psu.fpath_4_5=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_5=0 +hwmon_psu.len_4_5=8 +hwmon_psu.bit_offset_4_5= +hwmon_psu.str_cons_4_5=curr2_input + +# psu4 out_power +hwmon_psu.mode_4_6=config +hwmon_psu.int_cons_4_6=0 +hwmon_psu.src_4_6=file +hwmon_psu.frmt_4_6=buf +hwmon_psu.fpath_4_6=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_6=0 +hwmon_psu.len_4_6=16 +hwmon_psu.bit_offset_4_6=0 +hwmon_psu.str_cons_4_6=power2_input + +# psu4 fan +hwmon_psu.mode_4_7=config +hwmon_psu.int_cons_4_7= +hwmon_psu.src_4_7=file +hwmon_psu.frmt_4_7=buf +hwmon_psu.fpath_4_7=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_psu.addr_4_7=0 +hwmon_psu.len_4_7=8 +hwmon_psu.bit_offset_4_7= +hwmon_psu.str_cons_4_7=fan1_input + +# Configuration item: temperature hwmon path +# Format: hwmon_temp[key1]_[key2] +# Note: key1: High 8bit indicates the index of the device, starting from 1; low 8bit indicates the temperature index, starting from 1 +# key2: High 4bit indicates the master device type, power supply is 5, low 4bit indicates the temperature type 0:input 1:alias +# 2:type 3:max 4:max_hyst 5:min 6:crit +# mode: str_constant takes the value of str_cons directly and config reads it in the way specified by src +# int_cons:N Original value /(10^N) +# fpath: indicates the first half of the hwmon path +# bit_offset: specifies the number of decimal places. If not configured, the original precision is retained +# str_cons: when mode is str_constant, its value is the result of reading, and when reading from a file, the name of the file being read + +# psu1 temp1 input +hwmon_temp.mode_0x0101_0x20=config +hwmon_temp.int_cons_0x0101_0x20=0 +hwmon_temp.src_0x0101_0x20=file +hwmon_temp.frmt_0x0101_0x20=buf +hwmon_temp.fpath_0x0101_0x20=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_temp.addr_0x0101_0x20=0 +hwmon_temp.len_0x0101_0x20=8 +hwmon_temp.bit_offset_0x0101_0x20= +hwmon_temp.str_cons_0x0101_0x20=temp1_input + +# psu1 temp1 alias +hwmon_temp.mode_0x0101_0x21=str_constant +hwmon_temp.str_cons_0x0101_0x21=temp0 +# psu1 temp1 max +hwmon_temp.mode_0x0101_0x23=str_constant +hwmon_temp.str_cons_0x0101_0x23=65000 +# psu1 temp1 min +hwmon_temp.mode_0x0101_0x25=str_constant +hwmon_temp.str_cons_0x0101_0x25=-20000 +# psu1 temp1 high +hwmon_temp.mode_0x0101_0x29=str_constant +hwmon_temp.str_cons_0x0101_0x29=55000 +# psu1 temp1 low +hwmon_temp.mode_0x0101_0x2a=str_constant +hwmon_temp.str_cons_0x0101_0x2a=-5000 +# psu1 temp1 type +hwmon_temp.mode_0x0101_0x22=str_constant +hwmon_temp.str_cons_0x0101_0x22=psu_pmbus + +# psu2 temp1 input +hwmon_temp.mode_0x0201_0x20=config +hwmon_temp.int_cons_0x0201_0x20=0 +hwmon_temp.src_0x0201_0x20=file +hwmon_temp.frmt_0x0201_0x20=buf +hwmon_temp.fpath_0x0201_0x20=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_temp.addr_0x0201_0x20=0 +hwmon_temp.len_0x0201_0x20=8 +hwmon_temp.bit_offset_0x0201_0x20= +hwmon_temp.str_cons_0x0201_0x20=temp1_input + +# psu2 temp1 alias +hwmon_temp.mode_0x0201_0x21=str_constant +hwmon_temp.str_cons_0x0201_0x21=temp0 +# psu2 temp1 max +hwmon_temp.mode_0x0201_0x23=str_constant +hwmon_temp.str_cons_0x0201_0x23=65000 +# psu2 temp1 min +hwmon_temp.mode_0x0201_0x25=str_constant +hwmon_temp.str_cons_0x0201_0x25=-20000 +# psu2 temp1 high +hwmon_temp.mode_0x0201_0x29=str_constant +hwmon_temp.str_cons_0x0201_0x29=55000 +# psu2 temp1 low +hwmon_temp.mode_0x0201_0x2a=str_constant +hwmon_temp.str_cons_0x0201_0x2a=-5000 +# psu2 temp1 type +hwmon_temp.mode_0x0201_0x22=str_constant +hwmon_temp.str_cons_0x0201_0x22=psu_pmbus + +# psu3 temp1 input +hwmon_temp.mode_0x0301_0x20=config +hwmon_temp.int_cons_0x0301_0x20=0 +hwmon_temp.src_0x0301_0x20=file +hwmon_temp.frmt_0x0301_0x20=buf +hwmon_temp.fpath_0x0301_0x20=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_temp.addr_0x0301_0x20=0 +hwmon_temp.len_0x0301_0x20=8 +hwmon_temp.bit_offset_0x0301_0x20= +hwmon_temp.str_cons_0x0301_0x20=temp1_input + +# psu3 temp1 alias +hwmon_temp.mode_0x0301_0x21=str_constant +hwmon_temp.str_cons_0x0301_0x21=temp0 +# psu3 temp1 max +hwmon_temp.mode_0x0301_0x23=str_constant +hwmon_temp.str_cons_0x0301_0x23=65000 +# psu3 temp1 min +hwmon_temp.mode_0x0301_0x25=str_constant +hwmon_temp.str_cons_0x0301_0x25=-20000 +# psu3 temp1 high +hwmon_temp.mode_0x0301_0x29=str_constant +hwmon_temp.str_cons_0x0301_0x29=55000 +# psu3 temp1 low +hwmon_temp.mode_0x0301_0x2a=str_constant +hwmon_temp.str_cons_0x0301_0x2a=-5000 +# psu3 temp1 type +hwmon_temp.mode_0x0301_0x22=str_constant +hwmon_temp.str_cons_0x0301_0x22=psu_pmbus + +# psu4 temp1 input +hwmon_temp.mode_0x0401_0x20=config +hwmon_temp.int_cons_0x0401_0x20=0 +hwmon_temp.src_0x0401_0x20=file +hwmon_temp.frmt_0x0401_0x20=buf +hwmon_temp.fpath_0x0401_0x20=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_temp.addr_0x0401_0x20=0 +hwmon_temp.len_0x0401_0x20=8 +hwmon_temp.bit_offset_0x0401_0x20= +hwmon_temp.str_cons_0x0401_0x20=temp1_input + +# psu4 temp1 alias +hwmon_temp.mode_0x0401_0x21=str_constant +hwmon_temp.str_cons_0x0401_0x21=temp0 +# psu4 temp1 max +hwmon_temp.mode_0x0401_0x23=str_constant +hwmon_temp.str_cons_0x0401_0x23=65000 +# psu4 temp1 min +hwmon_temp.mode_0x0401_0x25=str_constant +hwmon_temp.str_cons_0x0401_0x25=-20000 +# psu4 temp1 high +hwmon_temp.mode_0x0401_0x29=str_constant +hwmon_temp.str_cons_0x0401_0x29=55000 +# psu4 temp1 low +hwmon_temp.mode_0x0401_0x2a=str_constant +hwmon_temp.str_cons_0x0401_0x2a=-5000 +# psu4 temp1 type +hwmon_temp.mode_0x0401_0x22=str_constant +hwmon_temp.str_cons_0x0401_0x22=psu_pmbus + +# Configuration item: The number of power supply names displayed by the product +# Format: dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev, 6: Number of power supply names displayed +dev_num_2_6=2 + +# Configuration item: product power type name +# Fill in instructions: format power_name_[index1]_[index2] +# Note: index1 indicates the power supply ID displayed, starting from 1, index2 indicates different power supplies with the same ID, starting from 1 +power_name_1_1=GW-CRPS1600D +power_name_1_2=DPS-1600AB-5 +power_name_1_3=CRPS2700D2 +power_name_1_4=DLG2700AN12C11 +power_name_1_5=AP-CA2700F12SA + +# Configuration item: Displays the power supply name +# Fill in instructions: format decode_power_name_[index] +# Note: index indicates the ID of the power supply that is displayed +decode_power_name_1=PA2700II-F-BD + +# Configuration item: rated power of power supply +# Fill in instructions: format power_rate_supply_[index] +# Note: index indicates the ID of the power supply that is displayed +power_rate_supply_1=1600000000 +power_rate_supply_2=1600000000 + +# Configuration item: Show the type of power duct +# Fill in instructions: format decode_power_fan_dir_[index] +# Note: index indicates the ID of the power supply that is displayed +decode_power_fan_dir_1=0 +decode_power_fan_dir_2=1 + +# Psu in voltage max min +hwmon_psu.mode_1_13=str_constant +hwmon_psu.str_cons_1_13=320000 +hwmon_psu.mode_1_15=str_constant +hwmon_psu.str_cons_1_15=180000 +# Psu in current max min +hwmon_psu.mode_1_14=str_constant +hwmon_psu.str_cons_1_14=16000 +hwmon_psu.mode_1_16=str_constant +hwmon_psu.str_cons_1_16=0 +# Psu out voltage max min +hwmon_psu.mode_1_17=str_constant +hwmon_psu.str_cons_1_17=12800 +hwmon_psu.mode_1_19=str_constant +hwmon_psu.str_cons_1_19=11600 +# Psu out current max min +hwmon_psu.mode_1_18=str_constant +hwmon_psu.str_cons_1_18=222000 +hwmon_psu.mode_1_20=str_constant +hwmon_psu.str_cons_1_20=10 +# Psu fan Max min +hwmon_psu.mode_1_21=str_constant +hwmon_psu.str_cons_1_21=37000 +hwmon_psu.mode_1_22=str_constant +hwmon_psu.str_cons_1_22=1000 +# Psu in power max min +hwmon_psu.mode_1_23=str_constant +hwmon_psu.str_cons_1_23=3000000000 +hwmon_psu.mode_1_24=str_constant +hwmon_psu.str_cons_1_24=10000 +# Psu out power max min +hwmon_psu.mode_1_25=str_constant +hwmon_psu.str_cons_1_25=2700000000 +hwmon_psu.mode_1_26=str_constant +hwmon_psu.str_cons_1_26=10000 + +# Psu in voltage max min +hwmon_psu.mode_2_13=str_constant +hwmon_psu.str_cons_2_13=320000 +hwmon_psu.mode_2_15=str_constant +hwmon_psu.str_cons_2_15=180000 +# Psu in current max min +hwmon_psu.mode_2_14=str_constant +hwmon_psu.str_cons_2_14=16000 +hwmon_psu.mode_2_16=str_constant +hwmon_psu.str_cons_2_16=0 +# Psu out voltage max min +hwmon_psu.mode_2_17=str_constant +hwmon_psu.str_cons_2_17=12800 +hwmon_psu.mode_2_19=str_constant +hwmon_psu.str_cons_2_19=11600 +# Psu out current max min +hwmon_psu.mode_2_18=str_constant +hwmon_psu.str_cons_2_18=222000 +hwmon_psu.mode_2_20=str_constant +hwmon_psu.str_cons_2_20=10 +# Psu fan Max min +hwmon_psu.mode_2_21=str_constant +hwmon_psu.str_cons_2_21=37000 +hwmon_psu.mode_2_22=str_constant +hwmon_psu.str_cons_2_22=1000 +# Psu in power max min +hwmon_psu.mode_2_23=str_constant +hwmon_psu.str_cons_2_23=3000000000 +hwmon_psu.mode_2_24=str_constant +hwmon_psu.str_cons_2_24=10000 +# Psu out power max min +hwmon_psu.mode_2_25=str_constant +hwmon_psu.str_cons_2_25=2700000000 +hwmon_psu.mode_2_26=str_constant +hwmon_psu.str_cons_2_26=10000 + +# Psu in voltage max min +hwmon_psu.mode_3_13=str_constant +hwmon_psu.str_cons_3_13=320000 +hwmon_psu.mode_3_15=str_constant +hwmon_psu.str_cons_3_15=180000 +# Psu in current max min +hwmon_psu.mode_3_14=str_constant +hwmon_psu.str_cons_3_14=16000 +hwmon_psu.mode_3_16=str_constant +hwmon_psu.str_cons_3_16=0 +# Psu out voltage max min +hwmon_psu.mode_3_17=str_constant +hwmon_psu.str_cons_3_17=12800 +hwmon_psu.mode_3_19=str_constant +hwmon_psu.str_cons_3_19=11600 +# Psu out current max min +hwmon_psu.mode_3_18=str_constant +hwmon_psu.str_cons_3_18=222000 +hwmon_psu.mode_3_20=str_constant +hwmon_psu.str_cons_3_20=10 +# Psu fan Max min +hwmon_psu.mode_3_21=str_constant +hwmon_psu.str_cons_3_21=37000 +hwmon_psu.mode_3_22=str_constant +hwmon_psu.str_cons_3_22=1000 +# Psu in power max min +hwmon_psu.mode_3_23=str_constant +hwmon_psu.str_cons_3_23=3000000000 +hwmon_psu.mode_3_24=str_constant +hwmon_psu.str_cons_3_24=10000 +# Psu out power max min +hwmon_psu.mode_3_25=str_constant +hwmon_psu.str_cons_3_25=2700000000 +hwmon_psu.mode_3_26=str_constant +hwmon_psu.str_cons_3_26=10000 + +# Psu in voltage max min +hwmon_psu.mode_4_13=str_constant +hwmon_psu.str_cons_4_13=320000 +hwmon_psu.mode_4_15=str_constant +hwmon_psu.str_cons_4_15=180000 +# Psu in current max min +hwmon_psu.mode_4_14=str_constant +hwmon_psu.str_cons_4_14=16000 +hwmon_psu.mode_4_16=str_constant +hwmon_psu.str_cons_4_16=0 +# Psu out voltage max min +hwmon_psu.mode_4_17=str_constant +hwmon_psu.str_cons_4_17=12800 +hwmon_psu.mode_4_19=str_constant +hwmon_psu.str_cons_4_19=11600 +# Psu out current max min +hwmon_psu.mode_4_18=str_constant +hwmon_psu.str_cons_4_18=222000 +hwmon_psu.mode_4_20=str_constant +hwmon_psu.str_cons_4_20=10 +# Psu fan Max min +hwmon_psu.mode_4_21=str_constant +hwmon_psu.str_cons_4_21=37000 +hwmon_psu.mode_4_22=str_constant +hwmon_psu.str_cons_4_22=1000 +# Psu in power max min +hwmon_psu.mode_4_23=str_constant +hwmon_psu.str_cons_4_23=3000000000 +hwmon_psu.mode_4_24=str_constant +hwmon_psu.str_cons_4_24=10000 +# Psu out power max min +hwmon_psu.mode_4_25=str_constant +hwmon_psu.str_cons_4_25=2700000000 +hwmon_psu.mode_4_26=str_constant +hwmon_psu.str_cons_4_26=10000 + +# blackbox info path +psu_blackbox_path_1=/proc/psu/67-0058/blackbox_info +psu_blackbox_path_2=/proc/psu/68-0058/blackbox_info +psu_blackbox_path_3=/proc/psu/69-0058/blackbox_info +psu_blackbox_path_4=/proc/psu/70-0058/blackbox_info + +# blackbox info clear +psu_clear_blackbox_1=/sys/bus/i2c/devices/67-0058/clear_blackbox +psu_clear_blackbox_2=/sys/bus/i2c/devices/68-0058/clear_blackbox +psu_clear_blackbox_3=/sys/bus/i2c/devices/69-0058/clear_blackbox +psu_clear_blackbox_4=/sys/bus/i2c/devices/70-0058/clear_blackbox + +# pmbus info +psu_pmbus_info_1=/sys/bus/i2c/devices/67-0058/pmbus_info +psu_pmbus_info_2=/sys/bus/i2c/devices/68-0058/pmbus_info +psu_pmbus_info_3=/sys/bus/i2c/devices/69-0058/pmbus_info +psu_pmbus_info_4=/sys/bus/i2c/devices/70-0058/pmbus_info + +psu_pmbus_addr_1 = 0x00430058 +psu_pmbus_addr_2 = 0x00440058 +psu_pmbus_addr_3 = 0x00450058 +psu_pmbus_addr_4 = 0x00460058 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg new file mode 100644 index 0000000000..4d8275fb84 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg @@ -0,0 +1,8120 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of configuration items +# and invalid Spaces must not be added between configuration items +# 2. The configuration item value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in in a specific product. In order to facilitate other products to copy and fill in, do not delete them +# 4. Configure items + +# Configuration item: temperature hwmon path +# Format: hwmon_temp[key1]_[key2] +# Note: key1: High 8bit indicates the index of the device, starting from 1; low 8bit indicates the temperature index, starting from 1 +# key2: The high 4bit indicates the primary device type, the sub-card is 5, and the low 4bit indicates the temperature type 0:input 1:alias +# 2:type 3:max 4:max_hyst 5:min 6:crit +# mode: str_constant takes the value of str_cons directly and config reads it in the way specified by src +# int_cons:N Original value /(10^N) +# fpath: indicates the first half of the hwmon path +# bit_offset: specifies the number of decimal places. If not configured, the original precision is retained +# str_cons: when mode is str_constant, its value is the result of reading, and when reading from a file, the name of the file being read + +# Number of motherboard temperature sensors +dev_num_0_1=66 + +# Number of main board voltage sensors +dev_num_0_2=212 + +# Number of current sensors on the mainboard +dev_num_0_3=0 + +# value : 0 +# alias : 1 +# type : 2 +# max : 3 +# hyst : 4 +# min : 5 +# crit : 6 +# range : 7 +# nominal_value : 8 +# high : 9 +# low : 10 + +# temp1 +# temp1 +hwmon_temp.mode_0x0001_0x00=config +hwmon_temp.int_cons_0x0001_0x00=0 +hwmon_temp.src_0x0001_0x00=file +hwmon_temp.frmt_0x0001_0x00=buf +hwmon_temp.fpath_0x0001_0x00=/sys/bus/i2c/devices/55-004b/hwmon/ +hwmon_temp.addr_0x0001_0x00=0 +hwmon_temp.len_0x0001_0x00=8 +hwmon_temp.bit_offset_0x0001_0x00= +hwmon_temp.str_cons_0x0001_0x00=temp1_input + +hwmon_temp.mode_0x0001_0x01=str_constant +hwmon_temp.str_cons_0x0001_0x01=MGMT_AIR_TEMP_01 + +hwmon_temp.mode_0x0001_0x02=str_constant +hwmon_temp.str_cons_0x0001_0x02=CT75_01 + +hwmon_temp.mode_0x0001_0x03=str_constant +hwmon_temp.str_cons_0x0001_0x03=70000 + +hwmon_temp.mode_0x0001_0x05=str_constant +hwmon_temp.str_cons_0x0001_0x05=-30000 + +hwmon_temp.mode_0x0001_0x09=str_constant +hwmon_temp.str_cons_0x0001_0x09=60000 + +hwmon_temp.mode_0x0001_0x0a=str_constant +hwmon_temp.str_cons_0x0001_0x0a=-20000 + +# temp2 +hwmon_temp.mode_0x0002_0x00=config +hwmon_temp.int_cons_0x0002_0x00=0 +hwmon_temp.src_0x0002_0x00=file +hwmon_temp.frmt_0x0002_0x00=buf +hwmon_temp.fpath_0x0002_0x00=/sys/bus/i2c/devices/56-004b/hwmon/ +hwmon_temp.addr_0x0002_0x00=0 +hwmon_temp.len_0x0002_0x00=8 +hwmon_temp.bit_offset_0x0002_0x00=0 +hwmon_temp.str_cons_0x0002_0x00=temp1_input +hwmon_temp.int_extra2_0x0002_0x00=-1000 + +hwmon_temp.mode_0x0002_0x01=str_constant +hwmon_temp.str_cons_0x0002_0x01=MGMT_INLET_TEMP_02 + +hwmon_temp.mode_0x0002_0x02=str_constant +hwmon_temp.str_cons_0x0002_0x02=CT75_02 + +hwmon_temp.mode_0x0002_0x03=str_constant +hwmon_temp.str_cons_0x0002_0x03=70000 + +hwmon_temp.mode_0x0002_0x05=str_constant +hwmon_temp.str_cons_0x0002_0x05=-30000 + +hwmon_temp.mode_0x0002_0x09=str_constant +hwmon_temp.str_cons_0x0002_0x09=60000 + +hwmon_temp.mode_0x0002_0x0a=str_constant +hwmon_temp.str_cons_0x0002_0x0a=-20000 + + +# temp3 +hwmon_temp.mode_0x0003_0x00=config +hwmon_temp.int_cons_0x0003_0x00=0 +hwmon_temp.src_0x0003_0x00=file +hwmon_temp.frmt_0x0003_0x00=buf +hwmon_temp.fpath_0x0003_0x00=/sys/bus/i2c/devices/76-004b/hwmon/ +hwmon_temp.addr_0x0003_0x00=0 +hwmon_temp.len_0x0003_0x00=8 +hwmon_temp.bit_offset_0x0003_0x00= +hwmon_temp.str_cons_0x0003_0x00=temp1_input + +hwmon_temp.mode_0x0003_0x01=str_constant +hwmon_temp.str_cons_0x0003_0x01=FCB_UP_TEMP_03 + +hwmon_temp.mode_0x0003_0x02=str_constant +hwmon_temp.str_cons_0x0003_0x02=CT75_03 + +hwmon_temp.mode_0x0003_0x03=str_constant +hwmon_temp.str_cons_0x0003_0x03=75000 + +hwmon_temp.mode_0x0003_0x05=str_constant +hwmon_temp.str_cons_0x0003_0x05=-30000 + +hwmon_temp.mode_0x0003_0x09=str_constant +hwmon_temp.str_cons_0x0003_0x09=70000 + +hwmon_temp.mode_0x0003_0x0a=str_constant +hwmon_temp.str_cons_0x0003_0x0a=-20000 + +# temp4 +hwmon_temp.mode_0x0004_0x00=config +hwmon_temp.int_cons_0x0004_0x00=0 +hwmon_temp.src_0x0004_0x00=file +hwmon_temp.frmt_0x0004_0x00=buf +hwmon_temp.fpath_0x0004_0x00=/sys/bus/i2c/devices/84-004b/hwmon/ +hwmon_temp.addr_0x0004_0x00=0 +hwmon_temp.len_0x0004_0x00=8 +hwmon_temp.bit_offset_0x0004_0x00= +hwmon_temp.str_cons_0x0004_0x00=temp1_input + +hwmon_temp.mode_0x0004_0x01=str_constant +hwmon_temp.str_cons_0x0004_0x01=FCB_DOWN_TEMP_04 + +hwmon_temp.mode_0x0004_0x02=str_constant +hwmon_temp.str_cons_0x0004_0x02=CT75_04 + +hwmon_temp.mode_0x0004_0x03=str_constant +hwmon_temp.str_cons_0x0004_0x03=75000 + +hwmon_temp.mode_0x0004_0x05=str_constant +hwmon_temp.str_cons_0x0004_0x05=-30000 + +hwmon_temp.mode_0x0004_0x09=str_constant +hwmon_temp.str_cons_0x0004_0x09=70000 + +hwmon_temp.mode_0x0004_0x0a=str_constant +hwmon_temp.str_cons_0x0004_0x0a=-20000 + +# temp5 +hwmon_temp.mode_0x0005_0x00=config +hwmon_temp.int_cons_0x0005_0x00=0 +hwmon_temp.src_0x0005_0x00=file +hwmon_temp.frmt_0x0005_0x00=buf +hwmon_temp.fpath_0x0005_0x00=/sys/bus/i2c/devices/123-004b/hwmon/ +hwmon_temp.addr_0x0005_0x00=0 +hwmon_temp.len_0x0005_0x00=8 +hwmon_temp.bit_offset_0x0005_0x00= +hwmon_temp.str_cons_0x0005_0x00=temp1_input + +hwmon_temp.mode_0x0005_0x01=str_constant +hwmon_temp.str_cons_0x0005_0x01=MAC_TEMP_05 + +hwmon_temp.mode_0x0005_0x02=str_constant +hwmon_temp.str_cons_0x0005_0x02=CT75_05 + +hwmon_temp.mode_0x0005_0x03=str_constant +hwmon_temp.str_cons_0x0005_0x03=105000 + +hwmon_temp.mode_0x0005_0x05=str_constant +hwmon_temp.str_cons_0x0005_0x05=-30000 + +hwmon_temp.mode_0x0005_0x09=str_constant +hwmon_temp.str_cons_0x0005_0x09=90000 + +hwmon_temp.mode_0x0005_0x0a=str_constant +hwmon_temp.str_cons_0x0005_0x0a=-20000 + +# temp6 +hwmon_temp.mode_0x0006_0x00=config +hwmon_temp.int_cons_0x0006_0x00=0 +hwmon_temp.src_0x0006_0x00=file +hwmon_temp.frmt_0x0006_0x00=buf +hwmon_temp.fpath_0x0006_0x00=/sys/bus/i2c/devices/124-004f/hwmon/ +hwmon_temp.addr_0x0006_0x00=0 +hwmon_temp.len_0x0006_0x00=8 +hwmon_temp.bit_offset_0x0006_0x00= +hwmon_temp.str_cons_0x0006_0x00=temp1_input + +hwmon_temp.mode_0x0006_0x01=str_constant +hwmon_temp.str_cons_0x0006_0x01=MAC_TBOARD_TEMP_06 + +hwmon_temp.mode_0x0006_0x02=str_constant +hwmon_temp.str_cons_0x0006_0x02=CT75_06 + +hwmon_temp.mode_0x0006_0x03=str_constant +hwmon_temp.str_cons_0x0006_0x03=105000 + +hwmon_temp.mode_0x0006_0x05=str_constant +hwmon_temp.str_cons_0x0006_0x05=-30000 + +hwmon_temp.mode_0x0006_0x09=str_constant +hwmon_temp.str_cons_0x0006_0x09=95000 + +hwmon_temp.mode_0x0006_0x0a=str_constant +hwmon_temp.str_cons_0x0006_0x0a=-20000 + +# fix temp7 +hwmon_temp.mode_0x0007_0x00=config +hwmon_temp.int_cons_0x0007_0x00=0 +hwmon_temp.src_0x0007_0x00=file +hwmon_temp.frmt_0x0007_0x00=buf +hwmon_temp.fpath_0x0007_0x00=/sys/bus/i2c/devices/124-004f/hwmon/ +hwmon_temp.addr_0x0007_0x00=0 +hwmon_temp.len_0x0007_0x00=8 +hwmon_temp.bit_offset_0x0007_0x00= +hwmon_temp.str_cons_0x0007_0x00=temp1_input + +hwmon_temp.mode_0x0007_0x01=str_constant +hwmon_temp.str_cons_0x0007_0x01=BMC_TEMP_07 + +hwmon_temp.mode_0x0007_0x02=str_constant +hwmon_temp.str_cons_0x0007_0x02=CT75_07 + +hwmon_temp.mode_0x0007_0x03=str_constant +hwmon_temp.str_cons_0x0007_0x03=70000 + +hwmon_temp.mode_0x0007_0x05=str_constant +hwmon_temp.str_cons_0x0007_0x05=-30000 + +hwmon_temp.mode_0x0007_0x09=str_constant +hwmon_temp.str_cons_0x0007_0x09=60000 + +hwmon_temp.mode_0x0007_0x0a=str_constant +hwmon_temp.str_cons_0x0007_0x0a=-20000 + +# temp8 +hwmon_temp.mode_0x0008_0x00=config +hwmon_temp.int_cons_0x0008_0x00=0 +hwmon_temp.src_0x0008_0x00=file +hwmon_temp.frmt_0x0008_0x00=buf +hwmon_temp.fpath_0x0008_0x00=/sys/bus/i2c/devices/93-004b/hwmon/ +hwmon_temp.addr_0x0008_0x00=0 +hwmon_temp.len_0x0008_0x00=8 +hwmon_temp.bit_offset_0x0008_0x00= +hwmon_temp.str_cons_0x0008_0x00=temp1_input + +hwmon_temp.mode_0x0008_0x01=str_constant +hwmon_temp.str_cons_0x0008_0x01=UPORT_TEMP_08 + +hwmon_temp.mode_0x0008_0x02=str_constant +hwmon_temp.str_cons_0x0008_0x02=CT75_08 + +hwmon_temp.mode_0x0008_0x03=str_constant +hwmon_temp.str_cons_0x0008_0x03=105000 + +hwmon_temp.mode_0x0008_0x05=str_constant +hwmon_temp.str_cons_0x0008_0x05=-30000 + +hwmon_temp.mode_0x0008_0x09=str_constant +hwmon_temp.str_cons_0x0008_0x09=90000 + +hwmon_temp.mode_0x0008_0x0a=str_constant +hwmon_temp.str_cons_0x0008_0x0a=-20000 + +# temp9 +hwmon_temp.mode_0x0009_0x00=config +hwmon_temp.int_cons_0x0009_0x00=0 +hwmon_temp.src_0x0009_0x00=file +hwmon_temp.frmt_0x0009_0x00=buf +hwmon_temp.fpath_0x0009_0x00=/sys/bus/i2c/devices/101-004b/hwmon/ +hwmon_temp.addr_0x0009_0x00=0 +hwmon_temp.len_0x0009_0x00=8 +hwmon_temp.bit_offset_0x0009_0x00= +hwmon_temp.str_cons_0x0009_0x00=temp1_input + +hwmon_temp.mode_0x0009_0x01=str_constant +hwmon_temp.str_cons_0x0009_0x01=DPORT_TEMP_09 + +hwmon_temp.mode_0x0009_0x02=str_constant +hwmon_temp.str_cons_0x0009_0x02=CT75_09 + +hwmon_temp.mode_0x0009_0x03=str_constant +hwmon_temp.str_cons_0x0009_0x03=105000 + +hwmon_temp.mode_0x0009_0x05=str_constant +hwmon_temp.str_cons_0x0009_0x05=-30000 + +hwmon_temp.mode_0x0009_0x09=str_constant +hwmon_temp.str_cons_0x0009_0x09=90000 + +hwmon_temp.mode_0x0009_0x0a=str_constant +hwmon_temp.str_cons_0x0009_0x0a=-20000 + +# temp10 +hwmon_temp.mode_0x000a_0x00=config +hwmon_temp.int_cons_0x000a_0x00=0 +hwmon_temp.src_0x000a_0x00=file +hwmon_temp.frmt_0x000a_0x00=buf +hwmon_temp.fpath_0x000a_0x00=/etc/sonic/highest_sff_temp +hwmon_temp.addr_0x000a_0x00=0 +hwmon_temp.len_0x000a_0x00=8 +hwmon_temp.bit_offset_0x000a_0x00= +hwmon_temp.str_cons_0x000a_0x00= + +hwmon_temp.mode_0x000a_0x01=str_constant +hwmon_temp.str_cons_0x000a_0x01=SFP_MAX_TEMP + +hwmon_temp.mode_0x000a_0x02=str_constant +hwmon_temp.str_cons_0x000a_0x02=SFP + +hwmon_temp.mode_0x000a_0x03=str_constant +hwmon_temp.str_cons_0x000a_0x03=70000 + +hwmon_temp.mode_0x000a_0x05=str_constant +hwmon_temp.str_cons_0x000a_0x05=-30000 + +hwmon_temp.mode_0x000a_0x09=str_constant +hwmon_temp.str_cons_0x000a_0x09=68000 + +hwmon_temp.mode_0x000a_0x0a=str_constant +hwmon_temp.str_cons_0x000a_0x0a=-20000 + +# temp11 +hwmon_temp.mode_0x000b_0x00=config +hwmon_temp.int_cons_0x000b_0x00=0 +hwmon_temp.src_0x000b_0x00=file +hwmon_temp.frmt_0x000b_0x00=buf +hwmon_temp.fpath_0x000b_0x00=/sys/devices/pci0000:00/0000:00:18.3/hwmon/ +hwmon_temp.addr_0x000b_0x00=0 +hwmon_temp.len_0x000b_0x00=8 +hwmon_temp.bit_offset_0x000b_0x00= +hwmon_temp.str_cons_0x000b_0x00=temp1_input + +hwmon_temp.mode_0x000b_0x01=str_constant +hwmon_temp.str_cons_0x000b_0x01=CPU_TEMP + +hwmon_temp.mode_0x000b_0x02=str_constant +hwmon_temp.str_cons_0x000b_0x02=CPU + +hwmon_temp.mode_0x000b_0x03=str_constant +hwmon_temp.str_cons_0x000b_0x03=95000 + +hwmon_temp.mode_0x000b_0x05=str_constant +hwmon_temp.str_cons_0x000b_0x05=-30000 + +hwmon_temp.mode_0x000b_0x09=str_constant +hwmon_temp.str_cons_0x000b_0x09=90000 + +hwmon_temp.mode_0x000b_0x0a=str_constant +hwmon_temp.str_cons_0x000b_0x0a=-20000 + +# temp12 +hwmon_temp.mode_0x000c_0x00=config +hwmon_temp.int_cons_0x000c_0x00=0 +hwmon_temp.src_0x000c_0x00=logic_file +hwmon_temp.frmt_0x000c_0x00=num_bytes +hwmon_temp.fpath_0x000c_0x00=/dev/cpld2 +hwmon_temp.addr_0x000c_0x00=0x37 +hwmon_temp.len_0x000c_0x00=2 +hwmon_temp.bit_offset_0x000c_0x00= +hwmon_temp.str_cons_0x000c_0x00=temp0_input +hwmon_temp.int_extra1_0x000c_0x00=8 + +hwmon_temp.mode_0x000c_0x01=str_constant +hwmon_temp.str_cons_0x000c_0x01=MAC_TEMP_MIN + +hwmon_temp.mode_0x000c_0x02=str_constant +hwmon_temp.str_cons_0x000c_0x02=CPLD_04 + +hwmon_temp.mode_0x000c_0x03=str_constant +hwmon_temp.str_cons_0x000c_0x03=105000 + +hwmon_temp.mode_0x000c_0x05=str_constant +hwmon_temp.str_cons_0x000c_0x05=-30000 + +hwmon_temp.mode_0x000c_0x09=str_constant +hwmon_temp.str_cons_0x000c_0x09=100000 + +hwmon_temp.mode_0x000c_0x0a=str_constant +hwmon_temp.str_cons_0x000c_0x0a=-20000 + +# temp13 +hwmon_temp.mode_0x000d_0x00=config +hwmon_temp.int_cons_0x000d_0x00=0 +hwmon_temp.src_0x000d_0x00=logic_file +hwmon_temp.frmt_0x000d_0x00=num_bytes +hwmon_temp.fpath_0x000d_0x00=/dev/cpld2 +hwmon_temp.addr_0x000d_0x00=0x39 +hwmon_temp.len_0x000d_0x00=2 +hwmon_temp.bit_offset_0x000d_0x00= +hwmon_temp.str_cons_0x000d_0x00=temp1_input +hwmon_temp.int_extra1_0x000d_0x00=8 + +hwmon_temp.mode_0x000d_0x01=str_constant +hwmon_temp.str_cons_0x000d_0x01=MAC_TEMP_MAX + +hwmon_temp.mode_0x000d_0x02=str_constant +hwmon_temp.str_cons_0x000d_0x02=CPLD_04 + +hwmon_temp.mode_0x000d_0x03=str_constant +hwmon_temp.str_cons_0x000d_0x03=105000 + +hwmon_temp.mode_0x000d_0x05=str_constant +hwmon_temp.str_cons_0x000d_0x05=-30000 + +hwmon_temp.mode_0x000d_0x09=str_constant +hwmon_temp.str_cons_0x000d_0x09=100000 + +hwmon_temp.mode_0x000d_0x0a=str_constant +hwmon_temp.str_cons_0x000d_0x0a=-20000 + +# temp14 +hwmon_temp.mode_0x000e_0x00=config +hwmon_temp.int_cons_0x000e_0x00=0 +hwmon_temp.src_0x000e_0x00=file +hwmon_temp.frmt_0x000e_0x00=buf +hwmon_temp.fpath_0x000e_0x00=/sys/bus/i2c/devices/136-0060/hwmon/ +hwmon_temp.addr_0x000e_0x00=0 +hwmon_temp.len_0x000e_0x00=8 +hwmon_temp.bit_offset_0x000e_0x00= +hwmon_temp.str_cons_0x000e_0x00=temp1_input + +hwmon_temp.mode_0x000e_0x01=str_constant +hwmon_temp.str_cons_0x000e_0x01=TMOS_MAC_VDDC_0V8 + +hwmon_temp.mode_0x000e_0x02=str_constant +hwmon_temp.str_cons_0x000e_0x02=XDPE1A2G5B_01 + +hwmon_temp.mode_0x000e_0x03=str_constant +hwmon_temp.str_cons_0x000e_0x03=125000 + +hwmon_temp.mode_0x000e_0x05=str_constant +hwmon_temp.str_cons_0x000e_0x05=-30000 + +hwmon_temp.mode_0x000e_0x09=str_constant +hwmon_temp.str_cons_0x000e_0x09=110000 + +hwmon_temp.mode_0x000e_0x0a=str_constant +hwmon_temp.str_cons_0x000e_0x0a=-20000 + +# temp15 +hwmon_temp.mode_0x000f_0x00=config +hwmon_temp.int_cons_0x000f_0x00=0 +hwmon_temp.src_0x000f_0x00=file +hwmon_temp.frmt_0x000f_0x00=buf +hwmon_temp.fpath_0x000f_0x00=/sys/bus/i2c/devices/107-0060/hwmon/ +hwmon_temp.addr_0x000f_0x00=0 +hwmon_temp.len_0x000f_0x00=8 +hwmon_temp.bit_offset_0x000f_0x00= +hwmon_temp.str_cons_0x000f_0x00=temp1_input + +hwmon_temp.mode_0x000f_0x01=str_constant +hwmon_temp.str_cons_0x000f_0x01=TMOS_MAC_PT0_VDDC_0V8 + +hwmon_temp.mode_0x000f_0x02=str_constant +hwmon_temp.str_cons_0x000f_0x02=XDPE12284C_05 + +hwmon_temp.mode_0x000f_0x03=str_constant +hwmon_temp.str_cons_0x000f_0x03=125000 + +hwmon_temp.mode_0x000f_0x05=str_constant +hwmon_temp.str_cons_0x000f_0x05=-30000 + +hwmon_temp.mode_0x000f_0x09=str_constant +hwmon_temp.str_cons_0x000f_0x09=110000 + +hwmon_temp.mode_0x000f_0x0a=str_constant +hwmon_temp.str_cons_0x000f_0x0a=-20000 + +# temp16 +hwmon_temp.mode_0x0010_0x00=config +hwmon_temp.int_cons_0x0010_0x00=0 +hwmon_temp.src_0x0010_0x00=file +hwmon_temp.frmt_0x0010_0x00=buf +hwmon_temp.fpath_0x0010_0x00=/sys/bus/i2c/devices/107-0060/hwmon/ +hwmon_temp.addr_0x0010_0x00=0 +hwmon_temp.len_0x0010_0x00=8 +hwmon_temp.bit_offset_0x0010_0x00= +hwmon_temp.str_cons_0x0010_0x00=temp2_input + +hwmon_temp.mode_0x0010_0x01=str_constant +hwmon_temp.str_cons_0x0010_0x01=TMOS_MAC_PT1_VDDC_0V8 + +hwmon_temp.mode_0x0010_0x02=str_constant +hwmon_temp.str_cons_0x0010_0x02=XDPE12284C_05 + +hwmon_temp.mode_0x0010_0x03=str_constant +hwmon_temp.str_cons_0x0010_0x03=125000 + +hwmon_temp.mode_0x0010_0x05=str_constant +hwmon_temp.str_cons_0x0010_0x05=-30000 + +hwmon_temp.mode_0x0010_0x09=str_constant +hwmon_temp.str_cons_0x0010_0x09=110000 + +hwmon_temp.mode_0x0010_0x0a=str_constant +hwmon_temp.str_cons_0x0010_0x0a=-20000 + +# temp17 +hwmon_temp.mode_0x0011_0x00=config +hwmon_temp.int_cons_0x0011_0x00=0 +hwmon_temp.src_0x0011_0x00=file +hwmon_temp.frmt_0x0011_0x00=buf +hwmon_temp.fpath_0x0011_0x00=/sys/bus/i2c/devices/108-0060/hwmon/ +hwmon_temp.addr_0x0011_0x00=0 +hwmon_temp.len_0x0011_0x00=8 +hwmon_temp.bit_offset_0x0011_0x00= +hwmon_temp.str_cons_0x0011_0x00=temp1_input + +hwmon_temp.mode_0x0011_0x01=str_constant +hwmon_temp.str_cons_0x0011_0x01=TMOS_MAC_PT2_VDDC_0V8 + +hwmon_temp.mode_0x0011_0x02=str_constant +hwmon_temp.str_cons_0x0011_0x02=XDPE12284C_06 + +hwmon_temp.mode_0x0011_0x03=str_constant +hwmon_temp.str_cons_0x0011_0x03=125000 + +hwmon_temp.mode_0x0011_0x05=str_constant +hwmon_temp.str_cons_0x0011_0x05=-30000 + +hwmon_temp.mode_0x0011_0x09=str_constant +hwmon_temp.str_cons_0x0011_0x09=110000 + +hwmon_temp.mode_0x0011_0x0a=str_constant +hwmon_temp.str_cons_0x0011_0x0a=-20000 + +# temp18 +hwmon_temp.mode_0x0012_0x00=config +hwmon_temp.int_cons_0x0012_0x00=0 +hwmon_temp.src_0x0012_0x00=file +hwmon_temp.frmt_0x0012_0x00=buf +hwmon_temp.fpath_0x0012_0x00=/sys/bus/i2c/devices/108-0060/hwmon/ +hwmon_temp.addr_0x0012_0x00=0 +hwmon_temp.len_0x0012_0x00=8 +hwmon_temp.bit_offset_0x0012_0x00= +hwmon_temp.str_cons_0x0012_0x00=temp2_input + +hwmon_temp.mode_0x0012_0x01=str_constant +hwmon_temp.str_cons_0x0012_0x01=TMOS_MAC_PT3_VDDC_0V8 + +hwmon_temp.mode_0x0012_0x02=str_constant +hwmon_temp.str_cons_0x0012_0x02=XDPE12284C_06 + +hwmon_temp.mode_0x0012_0x03=str_constant +hwmon_temp.str_cons_0x0012_0x03=125000 + +hwmon_temp.mode_0x0012_0x05=str_constant +hwmon_temp.str_cons_0x0012_0x05=-30000 + +hwmon_temp.mode_0x0012_0x09=str_constant +hwmon_temp.str_cons_0x0012_0x09=110000 + +hwmon_temp.mode_0x0012_0x0a=str_constant +hwmon_temp.str_cons_0x0012_0x0a=-20000 + +# temp19 +hwmon_temp.mode_0x0013_0x00=config +hwmon_temp.int_cons_0x0013_0x00=0 +hwmon_temp.src_0x0013_0x00=file +hwmon_temp.frmt_0x0013_0x00=buf +hwmon_temp.fpath_0x0013_0x00=/sys/bus/i2c/devices/109-0060/hwmon/ +hwmon_temp.addr_0x0013_0x00=0 +hwmon_temp.len_0x0013_0x00=8 +hwmon_temp.bit_offset_0x0013_0x00= +hwmon_temp.str_cons_0x0013_0x00=temp1_input + +hwmon_temp.mode_0x0013_0x01=str_constant +hwmon_temp.str_cons_0x0013_0x01=TMOS_MAC_PT4_VDDC_0V8 + +hwmon_temp.mode_0x0013_0x02=str_constant +hwmon_temp.str_cons_0x0013_0x02=XDPE12284C_07 + +hwmon_temp.mode_0x0013_0x03=str_constant +hwmon_temp.str_cons_0x0013_0x03=125000 + +hwmon_temp.mode_0x0013_0x05=str_constant +hwmon_temp.str_cons_0x0013_0x05=-30000 + +hwmon_temp.mode_0x0013_0x09=str_constant +hwmon_temp.str_cons_0x0013_0x09=110000 + +hwmon_temp.mode_0x0013_0x0a=str_constant +hwmon_temp.str_cons_0x0013_0x0a=-20000 + +# temp20 +hwmon_temp.mode_0x0014_0x00=config +hwmon_temp.int_cons_0x0014_0x00=0 +hwmon_temp.src_0x0014_0x00=file +hwmon_temp.frmt_0x0014_0x00=buf +hwmon_temp.fpath_0x0014_0x00=/sys/bus/i2c/devices/109-0060/hwmon/ +hwmon_temp.addr_0x0014_0x00=0 +hwmon_temp.len_0x0014_0x00=8 +hwmon_temp.bit_offset_0x0014_0x00= +hwmon_temp.str_cons_0x0014_0x00=temp2_input + +hwmon_temp.mode_0x0014_0x01=str_constant +hwmon_temp.str_cons_0x0014_0x01=TMOS_MAC_PT5_VDDC_0V8 + +hwmon_temp.mode_0x0014_0x02=str_constant +hwmon_temp.str_cons_0x0014_0x02=XDPE12284C_07 + +hwmon_temp.mode_0x0014_0x03=str_constant +hwmon_temp.str_cons_0x0014_0x03=125000 + +hwmon_temp.mode_0x0014_0x05=str_constant +hwmon_temp.str_cons_0x0014_0x05=-30000 + +hwmon_temp.mode_0x0014_0x09=str_constant +hwmon_temp.str_cons_0x0014_0x09=110000 + +hwmon_temp.mode_0x0014_0x0a=str_constant +hwmon_temp.str_cons_0x0014_0x0a=-20000 + +# temp21 +hwmon_temp.mode_0x0015_0x00=config +hwmon_temp.int_cons_0x0015_0x00=0 +hwmon_temp.src_0x0015_0x00=file +hwmon_temp.frmt_0x0015_0x00=buf +hwmon_temp.fpath_0x0015_0x00=/sys/bus/i2c/devices/110-0060/hwmon/ +hwmon_temp.addr_0x0015_0x00=0 +hwmon_temp.len_0x0015_0x00=8 +hwmon_temp.bit_offset_0x0015_0x00= +hwmon_temp.str_cons_0x0015_0x00=temp1_input + +hwmon_temp.mode_0x0015_0x01=str_constant +hwmon_temp.str_cons_0x0015_0x01=TMOS_MAC_PT6_VDDC_0V8 + +hwmon_temp.mode_0x0015_0x02=str_constant +hwmon_temp.str_cons_0x0015_0x02=XDPE12284C_08 + +hwmon_temp.mode_0x0015_0x03=str_constant +hwmon_temp.str_cons_0x0015_0x03=125000 + +hwmon_temp.mode_0x0015_0x05=str_constant +hwmon_temp.str_cons_0x0015_0x05=-30000 + +hwmon_temp.mode_0x0015_0x09=str_constant +hwmon_temp.str_cons_0x0015_0x09=110000 + +hwmon_temp.mode_0x0015_0x0a=str_constant +hwmon_temp.str_cons_0x0015_0x0a=-20000 + +# temp22 +hwmon_temp.mode_0x0016_0x00=config +hwmon_temp.int_cons_0x0016_0x00=0 +hwmon_temp.src_0x0016_0x00=file +hwmon_temp.frmt_0x0016_0x00=buf +hwmon_temp.fpath_0x0016_0x00=/sys/bus/i2c/devices/110-0060/hwmon/ +hwmon_temp.addr_0x0016_0x00=0 +hwmon_temp.len_0x0016_0x00=8 +hwmon_temp.bit_offset_0x0016_0x00= +hwmon_temp.str_cons_0x0016_0x00=temp2_input + +hwmon_temp.mode_0x0016_0x01=str_constant +hwmon_temp.str_cons_0x0016_0x01=TMOS_MAC_PT7_VDDC_0V8 + +hwmon_temp.mode_0x0016_0x02=str_constant +hwmon_temp.str_cons_0x0016_0x02=XDPE12284C_08 + +hwmon_temp.mode_0x0016_0x03=str_constant +hwmon_temp.str_cons_0x0016_0x03=125000 + +hwmon_temp.mode_0x0016_0x05=str_constant +hwmon_temp.str_cons_0x0016_0x05=-30000 + +hwmon_temp.mode_0x0016_0x09=str_constant +hwmon_temp.str_cons_0x0016_0x09=110000 + +hwmon_temp.mode_0x0016_0x0a=str_constant +hwmon_temp.str_cons_0x0016_0x0a=-20000 + +# temp23 +hwmon_temp.mode_0x0017_0x00=config +hwmon_temp.int_cons_0x0017_0x00=0 +hwmon_temp.src_0x0017_0x00=file +hwmon_temp.frmt_0x0017_0x00=buf +hwmon_temp.fpath_0x0017_0x00=/sys/bus/i2c/devices/111-0060/hwmon/ +hwmon_temp.addr_0x0017_0x00=0 +hwmon_temp.len_0x0017_0x00=8 +hwmon_temp.bit_offset_0x0017_0x00= +hwmon_temp.str_cons_0x0017_0x00=temp1_input + +hwmon_temp.mode_0x0017_0x01=str_constant +hwmon_temp.str_cons_0x0017_0x01=TMOS_MAC_PB0_PB7_TRVDD + +hwmon_temp.mode_0x0017_0x02=str_constant +hwmon_temp.str_cons_0x0017_0x02=XDPE12284C_09 + +hwmon_temp.mode_0x0017_0x03=str_constant +hwmon_temp.str_cons_0x0017_0x03=125000 + +hwmon_temp.mode_0x0017_0x05=str_constant +hwmon_temp.str_cons_0x0017_0x05=-30000 + +hwmon_temp.mode_0x0017_0x09=str_constant +hwmon_temp.str_cons_0x0017_0x09=110000 + +hwmon_temp.mode_0x0017_0x0a=str_constant +hwmon_temp.str_cons_0x0017_0x0a=-20000 + +# temp24 +hwmon_temp.mode_0x0018_0x00=config +hwmon_temp.int_cons_0x0018_0x00=0 +hwmon_temp.src_0x0018_0x00=file +hwmon_temp.frmt_0x0018_0x00=buf +hwmon_temp.fpath_0x0018_0x00=/sys/bus/i2c/devices/111-0060/hwmon/ +hwmon_temp.addr_0x0018_0x00=0 +hwmon_temp.len_0x0018_0x00=8 +hwmon_temp.bit_offset_0x0018_0x00= +hwmon_temp.str_cons_0x0018_0x00=temp2_input + +hwmon_temp.mode_0x0018_0x01=str_constant +hwmon_temp.str_cons_0x0018_0x01=TMOS_MAC_PB1_PB2_TRVDD + +hwmon_temp.mode_0x0018_0x02=str_constant +hwmon_temp.str_cons_0x0018_0x02=XDPE12284C_09 + +hwmon_temp.mode_0x0018_0x03=str_constant +hwmon_temp.str_cons_0x0018_0x03=125000 + +hwmon_temp.mode_0x0018_0x05=str_constant +hwmon_temp.str_cons_0x0018_0x05=-30000 + +hwmon_temp.mode_0x0018_0x09=str_constant +hwmon_temp.str_cons_0x0018_0x09=110000 + +hwmon_temp.mode_0x0018_0x0a=str_constant +hwmon_temp.str_cons_0x0018_0x0a=-20000 + +# temp25 +hwmon_temp.mode_0x0019_0x00=config +hwmon_temp.int_cons_0x0019_0x00=0 +hwmon_temp.src_0x0019_0x00=file +hwmon_temp.frmt_0x0019_0x00=buf +hwmon_temp.fpath_0x0019_0x00=/sys/bus/i2c/devices/112-0060/hwmon/ +hwmon_temp.addr_0x0019_0x00=0 +hwmon_temp.len_0x0019_0x00=8 +hwmon_temp.bit_offset_0x0019_0x00= +hwmon_temp.str_cons_0x0019_0x00=temp1_input + +hwmon_temp.mode_0x0019_0x01=str_constant +hwmon_temp.str_cons_0x0019_0x01=TMOS_MAC_PB3_PB4_TRVDD + +hwmon_temp.mode_0x0019_0x02=str_constant +hwmon_temp.str_cons_0x0019_0x02=XDPE12284C_10 + +hwmon_temp.mode_0x0019_0x03=str_constant +hwmon_temp.str_cons_0x0019_0x03=125000 + +hwmon_temp.mode_0x0019_0x05=str_constant +hwmon_temp.str_cons_0x0019_0x05=-30000 + +hwmon_temp.mode_0x0019_0x09=str_constant +hwmon_temp.str_cons_0x0019_0x09=110000 + +hwmon_temp.mode_0x0019_0x0a=str_constant +hwmon_temp.str_cons_0x0019_0x0a=-20000 + +# temp26 +hwmon_temp.mode_0x001a_0x00=config +hwmon_temp.int_cons_0x001a_0x00=0 +hwmon_temp.src_0x001a_0x00=file +hwmon_temp.frmt_0x001a_0x00=buf +hwmon_temp.fpath_0x001a_0x00=/sys/bus/i2c/devices/112-0060/hwmon/ +hwmon_temp.addr_0x001a_0x00=0 +hwmon_temp.len_0x001a_0x00=8 +hwmon_temp.bit_offset_0x001a_0x00= +hwmon_temp.str_cons_0x001a_0x00=temp2_input + +hwmon_temp.mode_0x001a_0x01=str_constant +hwmon_temp.str_cons_0x001a_0x01=TMOS_MAC_PB5_PB6_TRVDD + +hwmon_temp.mode_0x001a_0x02=str_constant +hwmon_temp.str_cons_0x001a_0x02=XDPE12284C_10 + +hwmon_temp.mode_0x001a_0x03=str_constant +hwmon_temp.str_cons_0x001a_0x03=125000 + +hwmon_temp.mode_0x001a_0x05=str_constant +hwmon_temp.str_cons_0x001a_0x05=-30000 + +hwmon_temp.mode_0x001a_0x09=str_constant +hwmon_temp.str_cons_0x001a_0x09=110000 + +hwmon_temp.mode_0x001a_0x0a=str_constant +hwmon_temp.str_cons_0x001a_0x0a=-20000 + +# temp27 +hwmon_temp.mode_0x001b_0x00=config +hwmon_temp.int_cons_0x001b_0x00=0 +hwmon_temp.src_0x001b_0x00=file +hwmon_temp.frmt_0x001b_0x00=buf +hwmon_temp.fpath_0x001b_0x00=/sys/bus/i2c/devices/113-0060/hwmon/ +hwmon_temp.addr_0x001b_0x00=0 +hwmon_temp.len_0x001b_0x00=8 +hwmon_temp.bit_offset_0x001b_0x00= +hwmon_temp.str_cons_0x001b_0x00=temp1_input + +hwmon_temp.mode_0x001b_0x01=str_constant +hwmon_temp.str_cons_0x001b_0x01=TMOS_MAC_TRVDD0_0V9 + +hwmon_temp.mode_0x001b_0x02=str_constant +hwmon_temp.str_cons_0x001b_0x02=XDPE12284C_11 + +hwmon_temp.mode_0x001b_0x03=str_constant +hwmon_temp.str_cons_0x001b_0x03=125000 + +hwmon_temp.mode_0x001b_0x05=str_constant +hwmon_temp.str_cons_0x001b_0x05=-30000 + +hwmon_temp.mode_0x001b_0x09=str_constant +hwmon_temp.str_cons_0x001b_0x09=110000 + +hwmon_temp.mode_0x001b_0x0a=str_constant +hwmon_temp.str_cons_0x001b_0x0a=-20000 + +# temp28 +hwmon_temp.mode_0x001c_0x00=config +hwmon_temp.int_cons_0x001c_0x00=0 +hwmon_temp.src_0x001c_0x00=file +hwmon_temp.frmt_0x001c_0x00=buf +hwmon_temp.fpath_0x001c_0x00=/sys/bus/i2c/devices/113-0060/hwmon/ +hwmon_temp.addr_0x001c_0x00=0 +hwmon_temp.len_0x001c_0x00=8 +hwmon_temp.bit_offset_0x001c_0x00= +hwmon_temp.str_cons_0x001c_0x00=temp2_input + +hwmon_temp.mode_0x001c_0x01=str_constant +hwmon_temp.str_cons_0x001c_0x01=TMOS_MAC_TRVDD0_0V75 + +hwmon_temp.mode_0x001c_0x02=str_constant +hwmon_temp.str_cons_0x001c_0x02=XDPE12284C_11 + +hwmon_temp.mode_0x001c_0x03=str_constant +hwmon_temp.str_cons_0x001c_0x03=125000 + +hwmon_temp.mode_0x001c_0x05=str_constant +hwmon_temp.str_cons_0x001c_0x05=-30000 + +hwmon_temp.mode_0x001c_0x09=str_constant +hwmon_temp.str_cons_0x001c_0x09=110000 + +hwmon_temp.mode_0x001c_0x0a=str_constant +hwmon_temp.str_cons_0x001c_0x0a=-20000 + +# temp29 +hwmon_temp.mode_0x001d_0x00=config +hwmon_temp.int_cons_0x001d_0x00=0 +hwmon_temp.src_0x001d_0x00=file +hwmon_temp.frmt_0x001d_0x00=buf +hwmon_temp.fpath_0x001d_0x00=/sys/bus/i2c/devices/114-0060/hwmon/ +hwmon_temp.addr_0x001d_0x00=0 +hwmon_temp.len_0x001d_0x00=8 +hwmon_temp.bit_offset_0x001d_0x00= +hwmon_temp.str_cons_0x001d_0x00=temp1_input + +hwmon_temp.mode_0x001d_0x01=str_constant +hwmon_temp.str_cons_0x001d_0x01=TMOS_MAC_TRVDD1_0V9 + +hwmon_temp.mode_0x001d_0x02=str_constant +hwmon_temp.str_cons_0x001d_0x02=XDPE12284C_12 + +hwmon_temp.mode_0x001d_0x03=str_constant +hwmon_temp.str_cons_0x001d_0x03=125000 + +hwmon_temp.mode_0x001d_0x05=str_constant +hwmon_temp.str_cons_0x001d_0x05=-30000 + +hwmon_temp.mode_0x001d_0x09=str_constant +hwmon_temp.str_cons_0x001d_0x09=110000 + +hwmon_temp.mode_0x001d_0x0a=str_constant +hwmon_temp.str_cons_0x001d_0x0a=-20000 + +# temp30 +hwmon_temp.mode_0x001e_0x00=config +hwmon_temp.int_cons_0x001e_0x00=0 +hwmon_temp.src_0x001e_0x00=file +hwmon_temp.frmt_0x001e_0x00=buf +hwmon_temp.fpath_0x001e_0x00=/sys/bus/i2c/devices/114-0060/hwmon/ +hwmon_temp.addr_0x001e_0x00=0 +hwmon_temp.len_0x001e_0x00=8 +hwmon_temp.bit_offset_0x001e_0x00= +hwmon_temp.str_cons_0x001e_0x00=temp2_input + +hwmon_temp.mode_0x001e_0x01=str_constant +hwmon_temp.str_cons_0x001e_0x01=TMOS_MAC_TRVDD1_0V75 + +hwmon_temp.mode_0x001e_0x02=str_constant +hwmon_temp.str_cons_0x001e_0x02=XDPE12284C_12 + +hwmon_temp.mode_0x001e_0x03=str_constant +hwmon_temp.str_cons_0x001e_0x03=125000 + +hwmon_temp.mode_0x001e_0x05=str_constant +hwmon_temp.str_cons_0x001e_0x05=-30000 + +hwmon_temp.mode_0x001e_0x09=str_constant +hwmon_temp.str_cons_0x001e_0x09=110000 + +hwmon_temp.mode_0x001e_0x0a=str_constant +hwmon_temp.str_cons_0x001e_0x0a=-20000 + +# temp31 +hwmon_temp.mode_0x001f_0x00=config +hwmon_temp.int_cons_0x001f_0x00=0 +hwmon_temp.src_0x001f_0x00=file +hwmon_temp.frmt_0x001f_0x00=buf +hwmon_temp.fpath_0x001f_0x00=/sys/bus/i2c/devices/115-0060/hwmon/ +hwmon_temp.addr_0x001f_0x00=0 +hwmon_temp.len_0x001f_0x00=8 +hwmon_temp.bit_offset_0x001f_0x00= +hwmon_temp.str_cons_0x001f_0x00=temp1_input + +hwmon_temp.mode_0x001f_0x01=str_constant +hwmon_temp.str_cons_0x001f_0x01=TMOS_MAC_OSFP_VDD3V3_A1 + +hwmon_temp.mode_0x001f_0x02=str_constant +hwmon_temp.str_cons_0x001f_0x02=XDPE12284C_13 + +hwmon_temp.mode_0x001f_0x03=str_constant +hwmon_temp.str_cons_0x001f_0x03=125000 + +hwmon_temp.mode_0x001f_0x05=str_constant +hwmon_temp.str_cons_0x001f_0x05=-30000 + +hwmon_temp.mode_0x001f_0x09=str_constant +hwmon_temp.str_cons_0x001f_0x09=110000 + +hwmon_temp.mode_0x001f_0x0a=str_constant +hwmon_temp.str_cons_0x001f_0x0a=-20000 + +# temp32 +hwmon_temp.mode_0x0020_0x00=config +hwmon_temp.int_cons_0x0020_0x00=0 +hwmon_temp.src_0x0020_0x00=file +hwmon_temp.frmt_0x0020_0x00=buf +hwmon_temp.fpath_0x0020_0x00=/sys/bus/i2c/devices/115-0060/hwmon/ +hwmon_temp.addr_0x0020_0x00=0 +hwmon_temp.len_0x0020_0x00=8 +hwmon_temp.bit_offset_0x0020_0x00= +hwmon_temp.str_cons_0x0020_0x00=temp2_input + +hwmon_temp.mode_0x0020_0x01=str_constant +hwmon_temp.str_cons_0x0020_0x01=TMOS_MAC_OSFP_VDD3V3_B1 + +hwmon_temp.mode_0x0020_0x02=str_constant +hwmon_temp.str_cons_0x0020_0x02=XDPE12284C_13 + +hwmon_temp.mode_0x0020_0x03=str_constant +hwmon_temp.str_cons_0x0020_0x03=125000 + +hwmon_temp.mode_0x0020_0x05=str_constant +hwmon_temp.str_cons_0x0020_0x05=-30000 + +hwmon_temp.mode_0x0020_0x09=str_constant +hwmon_temp.str_cons_0x0020_0x09=110000 + +hwmon_temp.mode_0x0020_0x0a=str_constant +hwmon_temp.str_cons_0x0020_0x0a=-20000 + +# temp33 +hwmon_temp.mode_0x0021_0x00=config +hwmon_temp.int_cons_0x0021_0x00=0 +hwmon_temp.src_0x0021_0x00=file +hwmon_temp.frmt_0x0021_0x00=buf +hwmon_temp.fpath_0x0021_0x00=/sys/bus/i2c/devices/116-0060/hwmon/ +hwmon_temp.addr_0x0021_0x00=0 +hwmon_temp.len_0x0021_0x00=8 +hwmon_temp.bit_offset_0x0021_0x00= +hwmon_temp.str_cons_0x0021_0x00=temp1_input + +hwmon_temp.mode_0x0021_0x01=str_constant +hwmon_temp.str_cons_0x0021_0x01=TMOS_MAC_OSFP_VDD3V3_A2 + +hwmon_temp.mode_0x0021_0x02=str_constant +hwmon_temp.str_cons_0x0021_0x02=XDPE12284C_14 + +hwmon_temp.mode_0x0021_0x03=str_constant +hwmon_temp.str_cons_0x0021_0x03=125000 + +hwmon_temp.mode_0x0021_0x05=str_constant +hwmon_temp.str_cons_0x0021_0x05=-30000 + +hwmon_temp.mode_0x0021_0x09=str_constant +hwmon_temp.str_cons_0x0021_0x09=110000 + +hwmon_temp.mode_0x0021_0x0a=str_constant +hwmon_temp.str_cons_0x0021_0x0a=-20000 + +# temp34 +hwmon_temp.mode_0x0022_0x00=config +hwmon_temp.int_cons_0x0022_0x00=0 +hwmon_temp.src_0x0022_0x00=file +hwmon_temp.frmt_0x0022_0x00=buf +hwmon_temp.fpath_0x0022_0x00=/sys/bus/i2c/devices/116-0060/hwmon/ +hwmon_temp.addr_0x0022_0x00=0 +hwmon_temp.len_0x0022_0x00=8 +hwmon_temp.bit_offset_0x0022_0x00= +hwmon_temp.str_cons_0x0022_0x00=temp2_input + +hwmon_temp.mode_0x0022_0x01=str_constant +hwmon_temp.str_cons_0x0022_0x01=TMOS_MAC_OSFP_VDD3V3_B2 + +hwmon_temp.mode_0x0022_0x02=str_constant +hwmon_temp.str_cons_0x0022_0x02=XDPE12284C_14 + +hwmon_temp.mode_0x0022_0x03=str_constant +hwmon_temp.str_cons_0x0022_0x03=125000 + +hwmon_temp.mode_0x0022_0x05=str_constant +hwmon_temp.str_cons_0x0022_0x05=-30000 + +hwmon_temp.mode_0x0022_0x09=str_constant +hwmon_temp.str_cons_0x0022_0x09=110000 + +hwmon_temp.mode_0x0022_0x0a=str_constant +hwmon_temp.str_cons_0x0022_0x0a=-20000 + +# temp35 +hwmon_temp.mode_0x0023_0x00=config +hwmon_temp.int_cons_0x0023_0x00=0 +hwmon_temp.src_0x0023_0x00=file +hwmon_temp.frmt_0x0023_0x00=buf +hwmon_temp.fpath_0x0023_0x00=/sys/bus/i2c/devices/117-0060/hwmon/ +hwmon_temp.addr_0x0023_0x00=0 +hwmon_temp.len_0x0023_0x00=8 +hwmon_temp.bit_offset_0x0023_0x00= +hwmon_temp.str_cons_0x0023_0x00=temp1_input + +hwmon_temp.mode_0x0023_0x01=str_constant +hwmon_temp.str_cons_0x0023_0x01=TMOS_MAC_OSFP_VDD3V3_A3 + +hwmon_temp.mode_0x0023_0x02=str_constant +hwmon_temp.str_cons_0x0023_0x02=XDPE12284C_15 + +hwmon_temp.mode_0x0023_0x03=str_constant +hwmon_temp.str_cons_0x0023_0x03=125000 + +hwmon_temp.mode_0x0023_0x05=str_constant +hwmon_temp.str_cons_0x0023_0x05=-30000 + +hwmon_temp.mode_0x0023_0x09=str_constant +hwmon_temp.str_cons_0x0023_0x09=110000 + +hwmon_temp.mode_0x0023_0x0a=str_constant +hwmon_temp.str_cons_0x0023_0x0a=-20000 + +# temp36 +hwmon_temp.mode_0x0024_0x00=config +hwmon_temp.int_cons_0x0024_0x00=0 +hwmon_temp.src_0x0024_0x00=file +hwmon_temp.frmt_0x0024_0x00=buf +hwmon_temp.fpath_0x0024_0x00=/sys/bus/i2c/devices/117-0060/hwmon/ +hwmon_temp.addr_0x0024_0x00=0 +hwmon_temp.len_0x0024_0x00=8 +hwmon_temp.bit_offset_0x0024_0x00= +hwmon_temp.str_cons_0x0024_0x00=temp2_input + +hwmon_temp.mode_0x0024_0x01=str_constant +hwmon_temp.str_cons_0x0024_0x01=TMOS_MAC_OSFP_VDD3V3_B3 + +hwmon_temp.mode_0x0024_0x02=str_constant +hwmon_temp.str_cons_0x0024_0x02=XDPE12284C_15 + +hwmon_temp.mode_0x0024_0x03=str_constant +hwmon_temp.str_cons_0x0024_0x03=125000 + +hwmon_temp.mode_0x0024_0x05=str_constant +hwmon_temp.str_cons_0x0024_0x05=-30000 + +hwmon_temp.mode_0x0024_0x09=str_constant +hwmon_temp.str_cons_0x0024_0x09=110000 + +hwmon_temp.mode_0x0024_0x0a=str_constant +hwmon_temp.str_cons_0x0024_0x0a=-20000 + +# temp37 +hwmon_temp.mode_0x0025_0x00=config +hwmon_temp.int_cons_0x0025_0x00=0 +hwmon_temp.src_0x0025_0x00=file +hwmon_temp.frmt_0x0025_0x00=buf +hwmon_temp.fpath_0x0025_0x00=/sys/bus/i2c/devices/118-0060/hwmon/ +hwmon_temp.addr_0x0025_0x00=0 +hwmon_temp.len_0x0025_0x00=8 +hwmon_temp.bit_offset_0x0025_0x00= +hwmon_temp.str_cons_0x0025_0x00=temp1_input + +hwmon_temp.mode_0x0025_0x01=str_constant +hwmon_temp.str_cons_0x0025_0x01=TMOS_MAC_OSFP_VDD3V3_A4 + +hwmon_temp.mode_0x0025_0x02=str_constant +hwmon_temp.str_cons_0x0025_0x02=XDPE12284C_16 + +hwmon_temp.mode_0x0025_0x03=str_constant +hwmon_temp.str_cons_0x0025_0x03=125000 + +hwmon_temp.mode_0x0025_0x05=str_constant +hwmon_temp.str_cons_0x0025_0x05=-30000 + +hwmon_temp.mode_0x0025_0x09=str_constant +hwmon_temp.str_cons_0x0025_0x09=110000 + +hwmon_temp.mode_0x0025_0x0a=str_constant +hwmon_temp.str_cons_0x0025_0x0a=-20000 + +# temp38 +hwmon_temp.mode_0x0026_0x00=config +hwmon_temp.int_cons_0x0026_0x00=0 +hwmon_temp.src_0x0026_0x00=file +hwmon_temp.frmt_0x0026_0x00=buf +hwmon_temp.fpath_0x0026_0x00=/sys/bus/i2c/devices/118-0060/hwmon/ +hwmon_temp.addr_0x0026_0x00=0 +hwmon_temp.len_0x0026_0x00=8 +hwmon_temp.bit_offset_0x0026_0x00= +hwmon_temp.str_cons_0x0026_0x00=temp2_input + +hwmon_temp.mode_0x0026_0x01=str_constant +hwmon_temp.str_cons_0x0026_0x01=TMOS_MAC_OSFP_VDD3V3_B4 + +hwmon_temp.mode_0x0026_0x02=str_constant +hwmon_temp.str_cons_0x0026_0x02=XDPE12284C_16 + +hwmon_temp.mode_0x0026_0x03=str_constant +hwmon_temp.str_cons_0x0026_0x03=125000 + +hwmon_temp.mode_0x0026_0x05=str_constant +hwmon_temp.str_cons_0x0026_0x05=-30000 + +hwmon_temp.mode_0x0026_0x09=str_constant +hwmon_temp.str_cons_0x0026_0x09=110000 + +hwmon_temp.mode_0x0026_0x0a=str_constant +hwmon_temp.str_cons_0x0026_0x0a=-20000 + +# temp39 +hwmon_temp.mode_0x0027_0x00=config +hwmon_temp.int_cons_0x0027_0x00=0 +hwmon_temp.src_0x0027_0x00=file +hwmon_temp.frmt_0x0027_0x00=buf +hwmon_temp.fpath_0x0027_0x00=/sys/bus/i2c/devices/119-0060/hwmon/ +hwmon_temp.addr_0x0027_0x00=0 +hwmon_temp.len_0x0027_0x00=8 +hwmon_temp.bit_offset_0x0027_0x00= +hwmon_temp.str_cons_0x0027_0x00=temp1_input + +hwmon_temp.mode_0x0027_0x01=str_constant +hwmon_temp.str_cons_0x0027_0x01=TMOS_MAC_OSFP_VDD3V3_A5 + +hwmon_temp.mode_0x0027_0x02=str_constant +hwmon_temp.str_cons_0x0027_0x02=XDPE12284C_17 + +hwmon_temp.mode_0x0027_0x03=str_constant +hwmon_temp.str_cons_0x0027_0x03=125000 + +hwmon_temp.mode_0x0027_0x05=str_constant +hwmon_temp.str_cons_0x0027_0x05=-30000 + +hwmon_temp.mode_0x0027_0x09=str_constant +hwmon_temp.str_cons_0x0027_0x09=110000 + +hwmon_temp.mode_0x0027_0x0a=str_constant +hwmon_temp.str_cons_0x0027_0x0a=-20000 + +# temp40 +hwmon_temp.mode_0x0028_0x00=config +hwmon_temp.int_cons_0x0028_0x00=0 +hwmon_temp.src_0x0028_0x00=file +hwmon_temp.frmt_0x0028_0x00=buf +hwmon_temp.fpath_0x0028_0x00=/sys/bus/i2c/devices/119-0060/hwmon/ +hwmon_temp.addr_0x0028_0x00=0 +hwmon_temp.len_0x0028_0x00=8 +hwmon_temp.bit_offset_0x0028_0x00= +hwmon_temp.str_cons_0x0028_0x00=temp2_input + +hwmon_temp.mode_0x0028_0x01=str_constant +hwmon_temp.str_cons_0x0028_0x01=TMOS_MAC_OSFP_VDD3V3_B5 + +hwmon_temp.mode_0x0028_0x02=str_constant +hwmon_temp.str_cons_0x0028_0x02=XDPE12284C_17 + +hwmon_temp.mode_0x0028_0x03=str_constant +hwmon_temp.str_cons_0x0028_0x03=125000 + +hwmon_temp.mode_0x0028_0x05=str_constant +hwmon_temp.str_cons_0x0028_0x05=-30000 + +hwmon_temp.mode_0x0028_0x09=str_constant +hwmon_temp.str_cons_0x0028_0x09=110000 + +hwmon_temp.mode_0x0028_0x0a=str_constant +hwmon_temp.str_cons_0x0028_0x0a=-20000 + +# temp41 +hwmon_temp.mode_0x0029_0x00=config +hwmon_temp.int_cons_0x0029_0x00=0 +hwmon_temp.src_0x0029_0x00=file +hwmon_temp.frmt_0x0029_0x00=buf +hwmon_temp.fpath_0x0029_0x00=/sys/bus/i2c/devices/120-0060/hwmon/ +hwmon_temp.addr_0x0029_0x00=0 +hwmon_temp.len_0x0029_0x00=8 +hwmon_temp.bit_offset_0x0029_0x00= +hwmon_temp.str_cons_0x0029_0x00=temp1_input + +hwmon_temp.mode_0x0029_0x01=str_constant +hwmon_temp.str_cons_0x0029_0x01=TMOS_MAC_OSFP_VDD3V3_A6 + +hwmon_temp.mode_0x0029_0x02=str_constant +hwmon_temp.str_cons_0x0029_0x02=XDPE12284C_18 + +hwmon_temp.mode_0x0029_0x03=str_constant +hwmon_temp.str_cons_0x0029_0x03=125000 + +hwmon_temp.mode_0x0029_0x05=str_constant +hwmon_temp.str_cons_0x0029_0x05=-30000 + +hwmon_temp.mode_0x0029_0x09=str_constant +hwmon_temp.str_cons_0x0029_0x09=110000 + +hwmon_temp.mode_0x0029_0x0a=str_constant +hwmon_temp.str_cons_0x0029_0x0a=-20000 + +# temp42 +hwmon_temp.mode_0x002a_0x00=config +hwmon_temp.int_cons_0x002a_0x00=0 +hwmon_temp.src_0x002a_0x00=file +hwmon_temp.frmt_0x002a_0x00=buf +hwmon_temp.fpath_0x002a_0x00=/sys/bus/i2c/devices/120-0060/hwmon/ +hwmon_temp.addr_0x002a_0x00=0 +hwmon_temp.len_0x002a_0x00=8 +hwmon_temp.bit_offset_0x002a_0x00= +hwmon_temp.str_cons_0x002a_0x00=temp2_input + +hwmon_temp.mode_0x002a_0x01=str_constant +hwmon_temp.str_cons_0x002a_0x01=TMOS_MAC_OSFP_VDD3V3_B6 + +hwmon_temp.mode_0x002a_0x02=str_constant +hwmon_temp.str_cons_0x002a_0x02=XDPE12284C_18 + +hwmon_temp.mode_0x002a_0x03=str_constant +hwmon_temp.str_cons_0x002a_0x03=125000 + +hwmon_temp.mode_0x002a_0x05=str_constant +hwmon_temp.str_cons_0x002a_0x05=-30000 + +hwmon_temp.mode_0x002a_0x09=str_constant +hwmon_temp.str_cons_0x002a_0x09=110000 + +hwmon_temp.mode_0x002a_0x0a=str_constant +hwmon_temp.str_cons_0x002a_0x0a=-20000 + +# temp43 +hwmon_temp.mode_0x002b_0x00=config +hwmon_temp.int_cons_0x002b_0x00=0 +hwmon_temp.src_0x002b_0x00=file +hwmon_temp.frmt_0x002b_0x00=buf +hwmon_temp.fpath_0x002b_0x00=/sys/bus/i2c/devices/121-0060/hwmon/ +hwmon_temp.addr_0x002b_0x00=0 +hwmon_temp.len_0x002b_0x00=8 +hwmon_temp.bit_offset_0x002b_0x00= +hwmon_temp.str_cons_0x002b_0x00=temp1_input + +hwmon_temp.mode_0x002b_0x01=str_constant +hwmon_temp.str_cons_0x002b_0x01=TMOS_MAC_OSFP_VDD3V3_A7 + +hwmon_temp.mode_0x002b_0x02=str_constant +hwmon_temp.str_cons_0x002b_0x02=XDPE12284C_19 + +hwmon_temp.mode_0x002b_0x03=str_constant +hwmon_temp.str_cons_0x002b_0x03=125000 + +hwmon_temp.mode_0x002b_0x05=str_constant +hwmon_temp.str_cons_0x002b_0x05=-30000 + +hwmon_temp.mode_0x002b_0x09=str_constant +hwmon_temp.str_cons_0x002b_0x09=110000 + +hwmon_temp.mode_0x002b_0x0a=str_constant +hwmon_temp.str_cons_0x002b_0x0a=-20000 + +# temp44 +hwmon_temp.mode_0x002c_0x00=config +hwmon_temp.int_cons_0x002c_0x00=0 +hwmon_temp.src_0x002c_0x00=file +hwmon_temp.frmt_0x002c_0x00=buf +hwmon_temp.fpath_0x002c_0x00=/sys/bus/i2c/devices/121-0060/hwmon/ +hwmon_temp.addr_0x002c_0x00=0 +hwmon_temp.len_0x002c_0x00=8 +hwmon_temp.bit_offset_0x002c_0x00= +hwmon_temp.str_cons_0x002c_0x00=temp2_input + +hwmon_temp.mode_0x002c_0x01=str_constant +hwmon_temp.str_cons_0x002c_0x01=TMOS_MAC_OSFP_VDD3V3_B7 + +hwmon_temp.mode_0x002c_0x02=str_constant +hwmon_temp.str_cons_0x002c_0x02=XDPE12284C_19 + +hwmon_temp.mode_0x002c_0x03=str_constant +hwmon_temp.str_cons_0x002c_0x03=125000 + +hwmon_temp.mode_0x002c_0x05=str_constant +hwmon_temp.str_cons_0x002c_0x05=-30000 + +hwmon_temp.mode_0x002c_0x09=str_constant +hwmon_temp.str_cons_0x002c_0x09=110000 + +hwmon_temp.mode_0x002c_0x0a=str_constant +hwmon_temp.str_cons_0x002c_0x0a=-20000 + +# temp45 +hwmon_temp.mode_0x002d_0x00=config +hwmon_temp.int_cons_0x002d_0x00=0 +hwmon_temp.src_0x002d_0x00=file +hwmon_temp.frmt_0x002d_0x00=buf +hwmon_temp.fpath_0x002d_0x00=/sys/bus/i2c/devices/122-0060/hwmon/ +hwmon_temp.addr_0x002d_0x00=0 +hwmon_temp.len_0x002d_0x00=8 +hwmon_temp.bit_offset_0x002d_0x00= +hwmon_temp.str_cons_0x002d_0x00=temp1_input + +hwmon_temp.mode_0x002d_0x01=str_constant +hwmon_temp.str_cons_0x002d_0x01=TMOS_MAC_OSFP_VDD3V3_A8 + +hwmon_temp.mode_0x002d_0x02=str_constant +hwmon_temp.str_cons_0x002d_0x02=XDPE12284C_20 + +hwmon_temp.mode_0x002d_0x03=str_constant +hwmon_temp.str_cons_0x002d_0x03=125000 + +hwmon_temp.mode_0x002d_0x05=str_constant +hwmon_temp.str_cons_0x002d_0x05=-30000 + +hwmon_temp.mode_0x002d_0x09=str_constant +hwmon_temp.str_cons_0x002d_0x09=110000 + +hwmon_temp.mode_0x002d_0x0a=str_constant +hwmon_temp.str_cons_0x002d_0x0a=-20000 + +# temp46 +hwmon_temp.mode_0x002e_0x00=config +hwmon_temp.int_cons_0x002e_0x00=0 +hwmon_temp.src_0x002e_0x00=file +hwmon_temp.frmt_0x002e_0x00=buf +hwmon_temp.fpath_0x002e_0x00=/sys/bus/i2c/devices/122-0060/hwmon/ +hwmon_temp.addr_0x002e_0x00=0 +hwmon_temp.len_0x002e_0x00=8 +hwmon_temp.bit_offset_0x002e_0x00= +hwmon_temp.str_cons_0x002e_0x00=temp2_input + +hwmon_temp.mode_0x002e_0x01=str_constant +hwmon_temp.str_cons_0x002e_0x01=TMOS_MAC_OSFP_VDD3V3_B8 + +hwmon_temp.mode_0x002e_0x02=str_constant +hwmon_temp.str_cons_0x002e_0x02=XDPE12284C_20 + +hwmon_temp.mode_0x002e_0x03=str_constant +hwmon_temp.str_cons_0x002e_0x03=125000 + +hwmon_temp.mode_0x002e_0x05=str_constant +hwmon_temp.str_cons_0x002e_0x05=-30000 + +hwmon_temp.mode_0x002e_0x09=str_constant +hwmon_temp.str_cons_0x002e_0x09=110000 + +hwmon_temp.mode_0x002e_0x0a=str_constant +hwmon_temp.str_cons_0x002e_0x0a=-20000 + +# temp47 +hwmon_temp.mode_0x002f_0x00=config +hwmon_temp.int_cons_0x002f_0x00=0 +hwmon_temp.src_0x002f_0x00=file +hwmon_temp.frmt_0x002f_0x00=buf +hwmon_temp.fpath_0x002f_0x00=/sys/bus/i2c/devices/94-0060/hwmon/ +hwmon_temp.addr_0x002f_0x00=0 +hwmon_temp.len_0x002f_0x00=8 +hwmon_temp.bit_offset_0x002f_0x00= +hwmon_temp.str_cons_0x002f_0x00=temp1_input + +hwmon_temp.mode_0x002f_0x01=str_constant +hwmon_temp.str_cons_0x002f_0x01=TMOS_UPORT_OSFP_VDD3V3_A1 + +hwmon_temp.mode_0x002f_0x02=str_constant +hwmon_temp.str_cons_0x002f_0x02=XDPE12284C_21 + +hwmon_temp.mode_0x002f_0x03=str_constant +hwmon_temp.str_cons_0x002f_0x03=125000 + +hwmon_temp.mode_0x002f_0x05=str_constant +hwmon_temp.str_cons_0x002f_0x05=-30000 + +hwmon_temp.mode_0x002f_0x09=str_constant +hwmon_temp.str_cons_0x002f_0x09=110000 + +hwmon_temp.mode_0x002f_0x0a=str_constant +hwmon_temp.str_cons_0x002f_0x0a=-20000 + +# temp48 +hwmon_temp.mode_0x0030_0x00=config +hwmon_temp.int_cons_0x0030_0x00=0 +hwmon_temp.src_0x0030_0x00=file +hwmon_temp.frmt_0x0030_0x00=buf +hwmon_temp.fpath_0x0030_0x00=/sys/bus/i2c/devices/94-0060/hwmon/ +hwmon_temp.addr_0x0030_0x00=0 +hwmon_temp.len_0x0030_0x00=8 +hwmon_temp.bit_offset_0x0030_0x00= +hwmon_temp.str_cons_0x0030_0x00=temp2_input + +hwmon_temp.mode_0x0030_0x01=str_constant +hwmon_temp.str_cons_0x0030_0x01=TMOS_UPORT_OSFP_VDD3V3_B1 + +hwmon_temp.mode_0x0030_0x02=str_constant +hwmon_temp.str_cons_0x0030_0x02=XDPE12284C_21 + +hwmon_temp.mode_0x0030_0x03=str_constant +hwmon_temp.str_cons_0x0030_0x03=125000 + +hwmon_temp.mode_0x0030_0x05=str_constant +hwmon_temp.str_cons_0x0030_0x05=-30000 + +hwmon_temp.mode_0x0030_0x09=str_constant +hwmon_temp.str_cons_0x0030_0x09=110000 + +hwmon_temp.mode_0x0030_0x0a=str_constant +hwmon_temp.str_cons_0x0030_0x0a=-20000 + +# temp49 +hwmon_temp.mode_0x0031_0x00=config +hwmon_temp.int_cons_0x0031_0x00=0 +hwmon_temp.src_0x0031_0x00=file +hwmon_temp.frmt_0x0031_0x00=buf +hwmon_temp.fpath_0x0031_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_temp.addr_0x0031_0x00=0 +hwmon_temp.len_0x0031_0x00=8 +hwmon_temp.bit_offset_0x0031_0x00= +hwmon_temp.str_cons_0x0031_0x00=temp1_input + +hwmon_temp.mode_0x0031_0x01=str_constant +hwmon_temp.str_cons_0x0031_0x01=TMOS_UPORT_OSFP_VDD3V3_A2 + +hwmon_temp.mode_0x0031_0x02=str_constant +hwmon_temp.str_cons_0x0031_0x02=XDPE12284C_22 + +hwmon_temp.mode_0x0031_0x03=str_constant +hwmon_temp.str_cons_0x0031_0x03=125000 + +hwmon_temp.mode_0x0031_0x05=str_constant +hwmon_temp.str_cons_0x0031_0x05=-30000 + +hwmon_temp.mode_0x0031_0x09=str_constant +hwmon_temp.str_cons_0x0031_0x09=110000 + +hwmon_temp.mode_0x0031_0x0a=str_constant +hwmon_temp.str_cons_0x0031_0x0a=-20000 + +# temp50 +hwmon_temp.mode_0x0032_0x00=config +hwmon_temp.int_cons_0x0032_0x00=0 +hwmon_temp.src_0x0032_0x00=file +hwmon_temp.frmt_0x0032_0x00=buf +hwmon_temp.fpath_0x0032_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_temp.addr_0x0032_0x00=0 +hwmon_temp.len_0x0032_0x00=8 +hwmon_temp.bit_offset_0x0032_0x00= +hwmon_temp.str_cons_0x0032_0x00=temp2_input + +hwmon_temp.mode_0x0032_0x01=str_constant +hwmon_temp.str_cons_0x0032_0x01=TMOS_UPORT_OSFP_VDD3V3_B2 + +hwmon_temp.mode_0x0032_0x02=str_constant +hwmon_temp.str_cons_0x0032_0x02=XDPE12284C_22 + +hwmon_temp.mode_0x0032_0x03=str_constant +hwmon_temp.str_cons_0x0032_0x03=125000 + +hwmon_temp.mode_0x0032_0x05=str_constant +hwmon_temp.str_cons_0x0032_0x05=-30000 + +hwmon_temp.mode_0x0032_0x09=str_constant +hwmon_temp.str_cons_0x0032_0x09=110000 + +hwmon_temp.mode_0x0032_0x0a=str_constant +hwmon_temp.str_cons_0x0032_0x0a=-20000 + +# temp51 +hwmon_temp.mode_0x0033_0x00=config +hwmon_temp.int_cons_0x0033_0x00=0 +hwmon_temp.src_0x0033_0x00=file +hwmon_temp.frmt_0x0033_0x00=buf +hwmon_temp.fpath_0x0033_0x00=/sys/bus/i2c/devices/96-0060/hwmon/ +hwmon_temp.addr_0x0033_0x00=0 +hwmon_temp.len_0x0033_0x00=8 +hwmon_temp.bit_offset_0x0033_0x00= +hwmon_temp.str_cons_0x0033_0x00=temp1_input + +hwmon_temp.mode_0x0033_0x01=str_constant +hwmon_temp.str_cons_0x0033_0x01=TMOS_UPORT_OSFP_VDD3V3_A3 + +hwmon_temp.mode_0x0033_0x02=str_constant +hwmon_temp.str_cons_0x0033_0x02=XDPE12284C_23 + +hwmon_temp.mode_0x0033_0x03=str_constant +hwmon_temp.str_cons_0x0033_0x03=125000 + +hwmon_temp.mode_0x0033_0x05=str_constant +hwmon_temp.str_cons_0x0033_0x05=-30000 + +hwmon_temp.mode_0x0033_0x09=str_constant +hwmon_temp.str_cons_0x0033_0x09=110000 + +hwmon_temp.mode_0x0033_0x0a=str_constant +hwmon_temp.str_cons_0x0033_0x0a=-20000 + +# temp52 +hwmon_temp.mode_0x0034_0x00=config +hwmon_temp.int_cons_0x0034_0x00=0 +hwmon_temp.src_0x0034_0x00=file +hwmon_temp.frmt_0x0034_0x00=buf +hwmon_temp.fpath_0x0034_0x00=/sys/bus/i2c/devices/96-0060/hwmon/ +hwmon_temp.addr_0x0034_0x00=0 +hwmon_temp.len_0x0034_0x00=8 +hwmon_temp.bit_offset_0x0034_0x00= +hwmon_temp.str_cons_0x0034_0x00=temp2_input + +hwmon_temp.mode_0x0034_0x01=str_constant +hwmon_temp.str_cons_0x0034_0x01=TMOS_UPORT_OSFP_VDD3V3_B3 + +hwmon_temp.mode_0x0034_0x02=str_constant +hwmon_temp.str_cons_0x0034_0x02=XDPE12284C_23 + +hwmon_temp.mode_0x0034_0x03=str_constant +hwmon_temp.str_cons_0x0034_0x03=125000 + +hwmon_temp.mode_0x0034_0x05=str_constant +hwmon_temp.str_cons_0x0034_0x05=-30000 + +hwmon_temp.mode_0x0034_0x09=str_constant +hwmon_temp.str_cons_0x0034_0x09=110000 + +hwmon_temp.mode_0x0034_0x0a=str_constant +hwmon_temp.str_cons_0x0034_0x0a=-20000 + +# temp53 +hwmon_temp.mode_0x0035_0x00=config +hwmon_temp.int_cons_0x0035_0x00=0 +hwmon_temp.src_0x0035_0x00=file +hwmon_temp.frmt_0x0035_0x00=buf +hwmon_temp.fpath_0x0035_0x00=/sys/bus/i2c/devices/97-0060/hwmon/ +hwmon_temp.addr_0x0035_0x00=0 +hwmon_temp.len_0x0035_0x00=8 +hwmon_temp.bit_offset_0x0035_0x00= +hwmon_temp.str_cons_0x0035_0x00=temp1_input + +hwmon_temp.mode_0x0035_0x01=str_constant +hwmon_temp.str_cons_0x0035_0x01=TMOS_UPORT_OSFP_VDD3V3_A4 + +hwmon_temp.mode_0x0035_0x02=str_constant +hwmon_temp.str_cons_0x0035_0x02=XDPE12284C_24 + +hwmon_temp.mode_0x0035_0x03=str_constant +hwmon_temp.str_cons_0x0035_0x03=125000 + +hwmon_temp.mode_0x0035_0x05=str_constant +hwmon_temp.str_cons_0x0035_0x05=-30000 + +hwmon_temp.mode_0x0035_0x09=str_constant +hwmon_temp.str_cons_0x0035_0x09=110000 + +hwmon_temp.mode_0x0035_0x0a=str_constant +hwmon_temp.str_cons_0x0035_0x0a=-20000 + +# temp54 +hwmon_temp.mode_0x0036_0x00=config +hwmon_temp.int_cons_0x0036_0x00=0 +hwmon_temp.src_0x0036_0x00=file +hwmon_temp.frmt_0x0036_0x00=buf +hwmon_temp.fpath_0x0036_0x00=/sys/bus/i2c/devices/97-0060/hwmon/ +hwmon_temp.addr_0x0036_0x00=0 +hwmon_temp.len_0x0036_0x00=8 +hwmon_temp.bit_offset_0x0036_0x00= +hwmon_temp.str_cons_0x0036_0x00=temp2_input + +hwmon_temp.mode_0x0036_0x01=str_constant +hwmon_temp.str_cons_0x0036_0x01=TMOS_UPORT_OSFP_VDD3V3_B4 + +hwmon_temp.mode_0x0036_0x02=str_constant +hwmon_temp.str_cons_0x0036_0x02=XDPE12284C_24 + +hwmon_temp.mode_0x0036_0x03=str_constant +hwmon_temp.str_cons_0x0036_0x03=125000 + +hwmon_temp.mode_0x0036_0x05=str_constant +hwmon_temp.str_cons_0x0036_0x05=-30000 + +hwmon_temp.mode_0x0036_0x09=str_constant +hwmon_temp.str_cons_0x0036_0x09=110000 + +hwmon_temp.mode_0x0036_0x0a=str_constant +hwmon_temp.str_cons_0x0036_0x0a=-20000 + +# temp55 +hwmon_temp.mode_0x0037_0x00=config +hwmon_temp.int_cons_0x0037_0x00=0 +hwmon_temp.src_0x0037_0x00=file +hwmon_temp.frmt_0x0037_0x00=buf +hwmon_temp.fpath_0x0037_0x00=/sys/bus/i2c/devices/102-0060/hwmon/ +hwmon_temp.addr_0x0037_0x00=0 +hwmon_temp.len_0x0037_0x00=8 +hwmon_temp.bit_offset_0x0037_0x00= +hwmon_temp.str_cons_0x0037_0x00=temp1_input + +hwmon_temp.mode_0x0037_0x01=str_constant +hwmon_temp.str_cons_0x0037_0x01=TMOS_DPORT_OSFP_VDD3V3_A1 + +hwmon_temp.mode_0x0037_0x02=str_constant +hwmon_temp.str_cons_0x0037_0x02=XDPE12284C_25 + +hwmon_temp.mode_0x0037_0x03=str_constant +hwmon_temp.str_cons_0x0037_0x03=125000 + +hwmon_temp.mode_0x0037_0x05=str_constant +hwmon_temp.str_cons_0x0037_0x05=-30000 + +hwmon_temp.mode_0x0037_0x09=str_constant +hwmon_temp.str_cons_0x0037_0x09=110000 + +hwmon_temp.mode_0x0037_0x0a=str_constant +hwmon_temp.str_cons_0x0037_0x0a=-20000 + +# temp56 +hwmon_temp.mode_0x0038_0x00=config +hwmon_temp.int_cons_0x0038_0x00=0 +hwmon_temp.src_0x0038_0x00=file +hwmon_temp.frmt_0x0038_0x00=buf +hwmon_temp.fpath_0x0038_0x00=/sys/bus/i2c/devices/102-0060/hwmon/ +hwmon_temp.addr_0x0038_0x00=0 +hwmon_temp.len_0x0038_0x00=8 +hwmon_temp.bit_offset_0x0038_0x00= +hwmon_temp.str_cons_0x0038_0x00=temp2_input + +hwmon_temp.mode_0x0038_0x01=str_constant +hwmon_temp.str_cons_0x0038_0x01=TMOS_DPORT_OSFP_VDD3V3_B1 + +hwmon_temp.mode_0x0038_0x02=str_constant +hwmon_temp.str_cons_0x0038_0x02=XDPE12284C_25 + +hwmon_temp.mode_0x0038_0x03=str_constant +hwmon_temp.str_cons_0x0038_0x03=125000 + +hwmon_temp.mode_0x0038_0x05=str_constant +hwmon_temp.str_cons_0x0038_0x05=-30000 + +hwmon_temp.mode_0x0038_0x09=str_constant +hwmon_temp.str_cons_0x0038_0x09=110000 + +hwmon_temp.mode_0x0038_0x0a=str_constant +hwmon_temp.str_cons_0x0038_0x0a=-20000 + +# temp57 +hwmon_temp.mode_0x0039_0x00=config +hwmon_temp.int_cons_0x0039_0x00=0 +hwmon_temp.src_0x0039_0x00=file +hwmon_temp.frmt_0x0039_0x00=buf +hwmon_temp.fpath_0x0039_0x00=/sys/bus/i2c/devices/103-0060/hwmon/ +hwmon_temp.addr_0x0039_0x00=0 +hwmon_temp.len_0x0039_0x00=8 +hwmon_temp.bit_offset_0x0039_0x00= +hwmon_temp.str_cons_0x0039_0x00=temp1_input + +hwmon_temp.mode_0x0039_0x01=str_constant +hwmon_temp.str_cons_0x0039_0x01=TMOS_DPORT_OSFP_VDD3V3_A2 + +hwmon_temp.mode_0x0039_0x02=str_constant +hwmon_temp.str_cons_0x0039_0x02=XDPE12284C_26 + +hwmon_temp.mode_0x0039_0x03=str_constant +hwmon_temp.str_cons_0x0039_0x03=125000 + +hwmon_temp.mode_0x0039_0x05=str_constant +hwmon_temp.str_cons_0x0039_0x05=-30000 + +hwmon_temp.mode_0x0039_0x09=str_constant +hwmon_temp.str_cons_0x0039_0x09=110000 + +hwmon_temp.mode_0x0039_0x0a=str_constant +hwmon_temp.str_cons_0x0039_0x0a=-20000 + +# temp58 +hwmon_temp.mode_0x003a_0x00=config +hwmon_temp.int_cons_0x003a_0x00=0 +hwmon_temp.src_0x003a_0x00=file +hwmon_temp.frmt_0x003a_0x00=buf +hwmon_temp.fpath_0x003a_0x00=/sys/bus/i2c/devices/103-0060/hwmon/ +hwmon_temp.addr_0x003a_0x00=0 +hwmon_temp.len_0x003a_0x00=8 +hwmon_temp.bit_offset_0x003a_0x00= +hwmon_temp.str_cons_0x003a_0x00=temp2_input + +hwmon_temp.mode_0x003a_0x01=str_constant +hwmon_temp.str_cons_0x003a_0x01=TMOS_DPORT_OSFP_VDD3V3_B2 + +hwmon_temp.mode_0x003a_0x02=str_constant +hwmon_temp.str_cons_0x003a_0x02=XDPE12284C_26 + +hwmon_temp.mode_0x003a_0x03=str_constant +hwmon_temp.str_cons_0x003a_0x03=125000 + +hwmon_temp.mode_0x003a_0x05=str_constant +hwmon_temp.str_cons_0x003a_0x05=-30000 + +hwmon_temp.mode_0x003a_0x09=str_constant +hwmon_temp.str_cons_0x003a_0x09=110000 + +hwmon_temp.mode_0x003a_0x0a=str_constant +hwmon_temp.str_cons_0x003a_0x0a=-20000 + +# temp59 +hwmon_temp.mode_0x003b_0x00=config +hwmon_temp.int_cons_0x003b_0x00=0 +hwmon_temp.src_0x003b_0x00=file +hwmon_temp.frmt_0x003b_0x00=buf +hwmon_temp.fpath_0x003b_0x00=/sys/bus/i2c/devices/104-0060/hwmon/ +hwmon_temp.addr_0x003b_0x00=0 +hwmon_temp.len_0x003b_0x00=8 +hwmon_temp.bit_offset_0x003b_0x00= +hwmon_temp.str_cons_0x003b_0x00=temp1_input + +hwmon_temp.mode_0x003b_0x01=str_constant +hwmon_temp.str_cons_0x003b_0x01=TMOS_DPORT_OSFP_VDD3V3_A3 + +hwmon_temp.mode_0x003b_0x02=str_constant +hwmon_temp.str_cons_0x003b_0x02=XDPE12284C_27 + +hwmon_temp.mode_0x003b_0x03=str_constant +hwmon_temp.str_cons_0x003b_0x03=125000 + +hwmon_temp.mode_0x003b_0x05=str_constant +hwmon_temp.str_cons_0x003b_0x05=-30000 + +hwmon_temp.mode_0x003b_0x09=str_constant +hwmon_temp.str_cons_0x003b_0x09=110000 + +hwmon_temp.mode_0x003b_0x0a=str_constant +hwmon_temp.str_cons_0x003b_0x0a=-20000 + +# temp60 +hwmon_temp.mode_0x003c_0x00=config +hwmon_temp.int_cons_0x003c_0x00=0 +hwmon_temp.src_0x003c_0x00=file +hwmon_temp.frmt_0x003c_0x00=buf +hwmon_temp.fpath_0x003c_0x00=/sys/bus/i2c/devices/104-0060/hwmon/ +hwmon_temp.addr_0x003c_0x00=0 +hwmon_temp.len_0x003c_0x00=8 +hwmon_temp.bit_offset_0x003c_0x00= +hwmon_temp.str_cons_0x003c_0x00=temp2_input + +hwmon_temp.mode_0x003c_0x01=str_constant +hwmon_temp.str_cons_0x003c_0x01=TMOS_DPORT_OSFP_VDD3V3_B3 + +hwmon_temp.mode_0x003c_0x02=str_constant +hwmon_temp.str_cons_0x003c_0x02=XDPE12284C_27 + +hwmon_temp.mode_0x003c_0x03=str_constant +hwmon_temp.str_cons_0x003c_0x03=125000 + +hwmon_temp.mode_0x003c_0x05=str_constant +hwmon_temp.str_cons_0x003c_0x05=-30000 + +hwmon_temp.mode_0x003c_0x09=str_constant +hwmon_temp.str_cons_0x003c_0x09=110000 + +hwmon_temp.mode_0x003c_0x0a=str_constant +hwmon_temp.str_cons_0x003c_0x0a=-20000 + +# temp61 +hwmon_temp.mode_0x003d_0x00=config +hwmon_temp.int_cons_0x003d_0x00=0 +hwmon_temp.src_0x003d_0x00=file +hwmon_temp.frmt_0x003d_0x00=buf +hwmon_temp.fpath_0x003d_0x00=/sys/bus/i2c/devices/105-0060/hwmon/ +hwmon_temp.addr_0x003d_0x00=0 +hwmon_temp.len_0x003d_0x00=8 +hwmon_temp.bit_offset_0x003d_0x00= +hwmon_temp.str_cons_0x003d_0x00=temp1_input + +hwmon_temp.mode_0x003d_0x01=str_constant +hwmon_temp.str_cons_0x003d_0x01=TMOS_DPORT_OSFP_VDD3V3_A4 + +hwmon_temp.mode_0x003d_0x02=str_constant +hwmon_temp.str_cons_0x003d_0x02=XDPE12284C_28 + +hwmon_temp.mode_0x003d_0x03=str_constant +hwmon_temp.str_cons_0x003d_0x03=125000 + +hwmon_temp.mode_0x003d_0x05=str_constant +hwmon_temp.str_cons_0x003d_0x05=-30000 + +hwmon_temp.mode_0x003d_0x09=str_constant +hwmon_temp.str_cons_0x003d_0x09=110000 + +hwmon_temp.mode_0x003d_0x0a=str_constant +hwmon_temp.str_cons_0x003d_0x0a=-20000 + +# temp62 +hwmon_temp.mode_0x003e_0x00=config +hwmon_temp.int_cons_0x003e_0x00=0 +hwmon_temp.src_0x003e_0x00=file +hwmon_temp.frmt_0x003e_0x00=buf +hwmon_temp.fpath_0x003e_0x00=/sys/bus/i2c/devices/105-0060/hwmon/ +hwmon_temp.addr_0x003e_0x00=0 +hwmon_temp.len_0x003e_0x00=8 +hwmon_temp.bit_offset_0x003e_0x00= +hwmon_temp.str_cons_0x003e_0x00=temp2_input + +hwmon_temp.mode_0x003e_0x01=str_constant +hwmon_temp.str_cons_0x003e_0x01=TMOS_DPORT_OSFP_VDD3V3_B4 + +hwmon_temp.mode_0x003e_0x02=str_constant +hwmon_temp.str_cons_0x003e_0x02=XDPE12284C_28 + +hwmon_temp.mode_0x003e_0x03=str_constant +hwmon_temp.str_cons_0x003e_0x03=125000 + +hwmon_temp.mode_0x003e_0x05=str_constant +hwmon_temp.str_cons_0x003e_0x05=-30000 + +hwmon_temp.mode_0x003e_0x09=str_constant +hwmon_temp.str_cons_0x003e_0x09=110000 + +hwmon_temp.mode_0x003e_0x0a=str_constant +hwmon_temp.str_cons_0x003e_0x0a=-20000 + +# temp63 +hwmon_temp.mode_0x003f_0x00=config +hwmon_temp.int_cons_0x003f_0x00=0 +hwmon_temp.src_0x003f_0x00=file +hwmon_temp.frmt_0x003f_0x00=buf +hwmon_temp.fpath_0x003f_0x00=/sys/bus/i2c/devices/67-0058/hwmon/ +hwmon_temp.addr_0x003f_0x00=0 +hwmon_temp.len_0x003f_0x00=8 +hwmon_temp.bit_offset_0x003f_0x00= +hwmon_temp.str_cons_0x003f_0x00=temp1_input + +hwmon_temp.mode_0x003f_0x01=str_constant +hwmon_temp.str_cons_0x003f_0x01=PSU1_TEMP + +hwmon_temp.mode_0x003f_0x02=str_constant +hwmon_temp.str_cons_0x003f_0x02=PSU + +hwmon_temp.mode_0x003f_0x03=str_constant +hwmon_temp.str_cons_0x003f_0x03=65000 + +hwmon_temp.mode_0x003f_0x05=str_constant +hwmon_temp.str_cons_0x003f_0x05=-20000 + +hwmon_temp.mode_0x003f_0x09=str_constant +hwmon_temp.str_cons_0x003f_0x09=55000 + +hwmon_temp.mode_0x003f_0x0a=str_constant +hwmon_temp.str_cons_0x003f_0x0a=-5000 + +# temp64 +hwmon_temp.mode_0x0040_0x00=config +hwmon_temp.int_cons_0x0040_0x00=0 +hwmon_temp.src_0x0040_0x00=file +hwmon_temp.frmt_0x0040_0x00=buf +hwmon_temp.fpath_0x0040_0x00=/sys/bus/i2c/devices/68-0058/hwmon/ +hwmon_temp.addr_0x0040_0x00=0 +hwmon_temp.len_0x0040_0x00=8 +hwmon_temp.bit_offset_0x0040_0x00= +hwmon_temp.str_cons_0x0040_0x00=temp1_input + +hwmon_temp.mode_0x0040_0x01=str_constant +hwmon_temp.str_cons_0x0040_0x01=PSU2_TEMP + +hwmon_temp.mode_0x0040_0x02=str_constant +hwmon_temp.str_cons_0x0040_0x02=PSU + +hwmon_temp.mode_0x0040_0x03=str_constant +hwmon_temp.str_cons_0x0040_0x03=65000 + +hwmon_temp.mode_0x0040_0x05=str_constant +hwmon_temp.str_cons_0x0040_0x05=-20000 + +hwmon_temp.mode_0x0040_0x09=str_constant +hwmon_temp.str_cons_0x0040_0x09=55000 + +hwmon_temp.mode_0x0040_0x0a=str_constant +hwmon_temp.str_cons_0x0040_0x0a=-5000 + +# temp65 +hwmon_temp.mode_0x0041_0x00=config +hwmon_temp.int_cons_0x0041_0x00=0 +hwmon_temp.src_0x0041_0x00=file +hwmon_temp.frmt_0x0041_0x00=buf +hwmon_temp.fpath_0x0041_0x00=/sys/bus/i2c/devices/69-0058/hwmon/ +hwmon_temp.addr_0x0041_0x00=0 +hwmon_temp.len_0x0041_0x00=8 +hwmon_temp.bit_offset_0x0041_0x00= +hwmon_temp.str_cons_0x0041_0x00=temp1_input + +hwmon_temp.mode_0x0041_0x01=str_constant +hwmon_temp.str_cons_0x0041_0x01=PSU3_TEMP + +hwmon_temp.mode_0x0041_0x02=str_constant +hwmon_temp.str_cons_0x0041_0x02=PSU + +hwmon_temp.mode_0x0041_0x03=str_constant +hwmon_temp.str_cons_0x0041_0x03=65000 + +hwmon_temp.mode_0x0041_0x05=str_constant +hwmon_temp.str_cons_0x0041_0x05=-20000 + +hwmon_temp.mode_0x0041_0x09=str_constant +hwmon_temp.str_cons_0x0041_0x09=55000 + +hwmon_temp.mode_0x0041_0x0a=str_constant +hwmon_temp.str_cons_0x0041_0x0a=-5000 + +# temp66 +hwmon_temp.mode_0x0042_0x00=config +hwmon_temp.int_cons_0x0042_0x00=0 +hwmon_temp.src_0x0042_0x00=file +hwmon_temp.frmt_0x0042_0x00=buf +hwmon_temp.fpath_0x0042_0x00=/sys/bus/i2c/devices/70-0058/hwmon/ +hwmon_temp.addr_0x0042_0x00=0 +hwmon_temp.len_0x0042_0x00=8 +hwmon_temp.bit_offset_0x0042_0x00= +hwmon_temp.str_cons_0x0042_0x00=temp1_input + +hwmon_temp.mode_0x0042_0x01=str_constant +hwmon_temp.str_cons_0x0042_0x01=PSU4_TEMP + +hwmon_temp.mode_0x0042_0x02=str_constant +hwmon_temp.str_cons_0x0042_0x02=PSU + +hwmon_temp.mode_0x0042_0x03=str_constant +hwmon_temp.str_cons_0x0042_0x03=65000 + +hwmon_temp.mode_0x0042_0x05=str_constant +hwmon_temp.str_cons_0x0042_0x05=-20000 + +hwmon_temp.mode_0x0042_0x09=str_constant +hwmon_temp.str_cons_0x0042_0x09=55000 + +hwmon_temp.mode_0x0042_0x0a=str_constant +hwmon_temp.str_cons_0x0042_0x0a=-5000 + + +# sensor vol +# value : 0 +# alias : 1 +# type : 2 +# max : 3 +# hyst : 4 +# min : 5 +# crit : 6 +# range : 7 +# nominal_value : 8 +# high : 9 +# low : 10 +# vol sensor 1 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +# vol sensor 1 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0001_0x00=config +hwmon_in.src_0x0001_0x00=file +hwmon_in.int_cons_0x0001_0x00=0 +hwmon_in.frmt_0x0001_0x00=buf +hwmon_in.fpath_0x0001_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0001_0x00=0 +hwmon_in.len_0x0001_0x00=8 +hwmon_in.str_cons_0x0001_0x00=in1_input +hwmon_in.int_extra1_0x0001_0x00=0 +hwmon_in.int_extra2_0x0001_0x00=0 + +hwmon_in.mode_0x0001_0x01=str_constant +hwmon_in.str_cons_0x0001_0x01=UCD90160_01_P12V0_V + +hwmon_in.mode_0x0001_0x02=str_constant +hwmon_in.str_cons_0x0001_0x02=UCD90160_01 + +hwmon_in.mode_0x0001_0x03=constant +hwmon_in.int_cons_0x0001_0x03=13200 + +hwmon_in.mode_0x0001_0x05=constant +hwmon_in.int_cons_0x0001_0x05=10800 + +monitor_flag_hwmon_in.mode_0x0001_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0001_0x00=1 + + +# vol sensor 2 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0002_0x00=config +hwmon_in.src_0x0002_0x00=file +hwmon_in.int_cons_0x0002_0x00=0 +hwmon_in.frmt_0x0002_0x00=buf +hwmon_in.fpath_0x0002_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0002_0x00=0 +hwmon_in.len_0x0002_0x00=8 +hwmon_in.str_cons_0x0002_0x00=in2_input +hwmon_in.int_extra1_0x0002_0x00=0 +hwmon_in.int_extra2_0x0002_0x00=0 + +hwmon_in.mode_0x0002_0x01=str_constant +hwmon_in.str_cons_0x0002_0x01=UCD90160_01_P5V0_STBY_V + +hwmon_in.mode_0x0002_0x02=str_constant +hwmon_in.str_cons_0x0002_0x02=UCD90160_01 + +hwmon_in.mode_0x0002_0x03=constant +hwmon_in.int_cons_0x0002_0x03=5500 + +hwmon_in.mode_0x0002_0x05=constant +hwmon_in.int_cons_0x0002_0x05=4500 + +monitor_flag_hwmon_in.mode_0x0002_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0002_0x00=1 + + +# vol sensor 3 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0003_0x00=config +hwmon_in.src_0x0003_0x00=file +hwmon_in.int_cons_0x0003_0x00=0 +hwmon_in.frmt_0x0003_0x00=buf +hwmon_in.fpath_0x0003_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0003_0x00=0 +hwmon_in.len_0x0003_0x00=8 +hwmon_in.str_cons_0x0003_0x00=in3_input +hwmon_in.int_extra1_0x0003_0x00=0 +hwmon_in.int_extra2_0x0003_0x00=0 + +hwmon_in.mode_0x0003_0x01=str_constant +hwmon_in.str_cons_0x0003_0x01=UCD90160_01_P3V3_FR_S5 + +hwmon_in.mode_0x0003_0x02=str_constant +hwmon_in.str_cons_0x0003_0x02=UCD90160_01 + +hwmon_in.mode_0x0003_0x03=constant +hwmon_in.int_cons_0x0003_0x03=3485 + +hwmon_in.mode_0x0003_0x05=constant +hwmon_in.int_cons_0x0003_0x05=3115 + +monitor_flag_hwmon_in.mode_0x0003_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0003_0x00=1 + + +# vol sensor 4 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0004_0x00=config +hwmon_in.src_0x0004_0x00=file +hwmon_in.int_cons_0x0004_0x00=0 +hwmon_in.frmt_0x0004_0x00=buf +hwmon_in.fpath_0x0004_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0004_0x00=0 +hwmon_in.len_0x0004_0x00=8 +hwmon_in.str_cons_0x0004_0x00=in4_input +hwmon_in.int_extra1_0x0004_0x00=0 +hwmon_in.int_extra2_0x0004_0x00=0 + +hwmon_in.mode_0x0004_0x01=str_constant +hwmon_in.str_cons_0x0004_0x01=UCD90160_01_P1V8_FR_S5 + +hwmon_in.mode_0x0004_0x02=str_constant +hwmon_in.str_cons_0x0004_0x02=UCD90160_01 + +hwmon_in.mode_0x0004_0x03=constant +hwmon_in.int_cons_0x0004_0x03=1910 + +hwmon_in.mode_0x0004_0x05=constant +hwmon_in.int_cons_0x0004_0x05=1690 + +monitor_flag_hwmon_in.mode_0x0004_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0004_0x00=1 + + +# vol sensor 5 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0005_0x00=config +hwmon_in.src_0x0005_0x00=file +hwmon_in.int_cons_0x0005_0x00=0 +hwmon_in.frmt_0x0005_0x00=buf +hwmon_in.fpath_0x0005_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0005_0x00=0 +hwmon_in.len_0x0005_0x00=8 +hwmon_in.str_cons_0x0005_0x00=in5_input +hwmon_in.int_extra1_0x0005_0x00=0 +hwmon_in.int_extra2_0x0005_0x00=0 + +hwmon_in.mode_0x0005_0x01=str_constant +hwmon_in.str_cons_0x0005_0x01=UCD90160_01_P0V75_FR_MISC_S5 + +hwmon_in.mode_0x0005_0x02=str_constant +hwmon_in.str_cons_0x0005_0x02=UCD90160_01 + +hwmon_in.mode_0x0005_0x03=constant +hwmon_in.int_cons_0x0005_0x03=807 + +hwmon_in.mode_0x0005_0x05=constant +hwmon_in.int_cons_0x0005_0x05=692 + +monitor_flag_hwmon_in.mode_0x0005_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0005_0x00=1 + + +# vol sensor 6 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0006_0x00=config +hwmon_in.src_0x0006_0x00=file +hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.frmt_0x0006_0x00=buf +hwmon_in.fpath_0x0006_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0006_0x00=0 +hwmon_in.len_0x0006_0x00=8 +hwmon_in.str_cons_0x0006_0x00=in6_input +hwmon_in.int_extra1_0x0006_0x00=0 +hwmon_in.int_extra2_0x0006_0x00=0 + +hwmon_in.mode_0x0006_0x01=str_constant +hwmon_in.str_cons_0x0006_0x01=UCD90160_01_P3V3_FR_S0 + +hwmon_in.mode_0x0006_0x02=str_constant +hwmon_in.str_cons_0x0006_0x02=UCD90160_01 + +hwmon_in.mode_0x0006_0x03=constant +hwmon_in.int_cons_0x0006_0x03=3485 + +hwmon_in.mode_0x0006_0x05=constant +hwmon_in.int_cons_0x0006_0x05=3115 + +monitor_flag_hwmon_in.mode_0x0006_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0006_0x00=1 + + +# vol sensor 7 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0007_0x00=config +hwmon_in.src_0x0007_0x00=file +hwmon_in.int_cons_0x0007_0x00=0 +hwmon_in.frmt_0x0007_0x00=buf +hwmon_in.fpath_0x0007_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0007_0x00=0 +hwmon_in.len_0x0007_0x00=8 +hwmon_in.str_cons_0x0007_0x00=in7_input +hwmon_in.int_extra1_0x0007_0x00=0 +hwmon_in.int_extra2_0x0007_0x00=0 + +hwmon_in.mode_0x0007_0x01=str_constant +hwmon_in.str_cons_0x0007_0x01=UCD90160_01_P1V8_FR_S0 + +hwmon_in.mode_0x0007_0x02=str_constant +hwmon_in.str_cons_0x0007_0x02=UCD90160_01 + +hwmon_in.mode_0x0007_0x03=constant +hwmon_in.int_cons_0x0007_0x03=1910 + +hwmon_in.mode_0x0007_0x05=constant +hwmon_in.int_cons_0x0007_0x05=1690 + +monitor_flag_hwmon_in.mode_0x0007_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0007_0x00=1 + + +# vol sensor 8 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0008_0x00=config +hwmon_in.src_0x0008_0x00=file +hwmon_in.int_cons_0x0008_0x00=0 +hwmon_in.frmt_0x0008_0x00=buf +hwmon_in.fpath_0x0008_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0008_0x00=0 +hwmon_in.len_0x0008_0x00=8 +hwmon_in.str_cons_0x0008_0x00=in8_input +hwmon_in.int_extra1_0x0008_0x00=0 +hwmon_in.int_extra2_0x0008_0x00=0 + +hwmon_in.mode_0x0008_0x01=str_constant +hwmon_in.str_cons_0x0008_0x01=UCD90160_01_P1V1_NIC_AVDDH + +hwmon_in.mode_0x0008_0x02=str_constant +hwmon_in.str_cons_0x0008_0x02=UCD90160_01 + +hwmon_in.mode_0x0008_0x03=constant +hwmon_in.int_cons_0x0008_0x03=1175 + +hwmon_in.mode_0x0008_0x05=constant +hwmon_in.int_cons_0x0008_0x05=1025 + +monitor_flag_hwmon_in.mode_0x0008_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0008_0x00=1 + + +# vol sensor 9 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0009_0x00=config +hwmon_in.src_0x0009_0x00=file +hwmon_in.int_cons_0x0009_0x00=0 +hwmon_in.frmt_0x0009_0x00=buf +hwmon_in.fpath_0x0009_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0009_0x00=0 +hwmon_in.len_0x0009_0x00=8 +hwmon_in.str_cons_0x0009_0x00=in9_input +hwmon_in.int_extra1_0x0009_0x00=0 +hwmon_in.int_extra2_0x0009_0x00=0 + +hwmon_in.mode_0x0009_0x01=str_constant +hwmon_in.str_cons_0x0009_0x01=UCD90160_01_P0V9_NIC_AVDD_PCIE + +hwmon_in.mode_0x0009_0x02=str_constant +hwmon_in.str_cons_0x0009_0x02=UCD90160_01 + +hwmon_in.mode_0x0009_0x03=constant +hwmon_in.int_cons_0x0009_0x03=965 + +hwmon_in.mode_0x0009_0x05=constant +hwmon_in.int_cons_0x0009_0x05=835 + +monitor_flag_hwmon_in.mode_0x0009_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0009_0x00=1 + + +# vol sensor 10 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x000a_0x00=config +hwmon_in.src_0x000a_0x00=file +hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.frmt_0x000a_0x00=buf +hwmon_in.fpath_0x000a_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x000a_0x00=0 +hwmon_in.len_0x000a_0x00=8 +hwmon_in.str_cons_0x000a_0x00=in10_input +hwmon_in.int_extra1_0x000a_0x00=0 +hwmon_in.int_extra2_0x000a_0x00=0 + +hwmon_in.mode_0x000a_0x01=str_constant +hwmon_in.str_cons_0x000a_0x01=UCD90160_01_P0V9_NIC_AVDD_ETH + +hwmon_in.mode_0x000a_0x02=str_constant +hwmon_in.str_cons_0x000a_0x02=UCD90160_01 + +hwmon_in.mode_0x000a_0x03=constant +hwmon_in.int_cons_0x000a_0x03=965 + +hwmon_in.mode_0x000a_0x05=constant +hwmon_in.int_cons_0x000a_0x05=835 + +monitor_flag_hwmon_in.mode_0x000a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000a_0x00=1 + + +# vol sensor 11 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x000b_0x00=config +hwmon_in.src_0x000b_0x00=file +hwmon_in.int_cons_0x000b_0x00=0 +hwmon_in.frmt_0x000b_0x00=buf +hwmon_in.fpath_0x000b_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x000b_0x00=0 +hwmon_in.len_0x000b_0x00=8 +hwmon_in.str_cons_0x000b_0x00=in11_input +hwmon_in.int_extra1_0x000b_0x00=0 +hwmon_in.int_extra2_0x000b_0x00=0 + +hwmon_in.mode_0x000b_0x01=str_constant +hwmon_in.str_cons_0x000b_0x01=UCD90160_01_P0V8_NIC_VDD + +hwmon_in.mode_0x000b_0x02=str_constant +hwmon_in.str_cons_0x000b_0x02=UCD90160_01 + +hwmon_in.mode_0x000b_0x03=constant +hwmon_in.int_cons_0x000b_0x03=860 + +hwmon_in.mode_0x000b_0x05=constant +hwmon_in.int_cons_0x000b_0x05=740 + +monitor_flag_hwmon_in.mode_0x000b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000b_0x00=1 + + +# vol sensor 12 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x000c_0x00=config +hwmon_in.src_0x000c_0x00=file +hwmon_in.int_cons_0x000c_0x00=0 +hwmon_in.frmt_0x000c_0x00=buf +hwmon_in.fpath_0x000c_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x000c_0x00=0 +hwmon_in.len_0x000c_0x00=8 +hwmon_in.str_cons_0x000c_0x00=in12_input +hwmon_in.int_extra1_0x000c_0x00=0 +hwmon_in.int_extra2_0x000c_0x00=0 + +hwmon_in.mode_0x000c_0x01=str_constant +hwmon_in.str_cons_0x000c_0x01=UCD90160_01_P1V1_FR_MEM_S3 + +hwmon_in.mode_0x000c_0x02=str_constant +hwmon_in.str_cons_0x000c_0x02=UCD90160_01 + +hwmon_in.mode_0x000c_0x03=constant +hwmon_in.int_cons_0x000c_0x03=1186 + +hwmon_in.mode_0x000c_0x05=constant +hwmon_in.int_cons_0x000c_0x05=1047 + +monitor_flag_hwmon_in.mode_0x000c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000c_0x00=1 + + +# vol sensor 13 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x000d_0x00=config +hwmon_in.src_0x000d_0x00=file +hwmon_in.int_cons_0x000d_0x00=0 +hwmon_in.frmt_0x000d_0x00=buf +hwmon_in.fpath_0x000d_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x000d_0x00=0 +hwmon_in.len_0x000d_0x00=8 +hwmon_in.str_cons_0x000d_0x00=in13_input +hwmon_in.int_extra1_0x000d_0x00=0 +hwmon_in.int_extra2_0x000d_0x00=0 + +hwmon_in.mode_0x000d_0x01=str_constant +hwmon_in.str_cons_0x000d_0x01=UCD90160_01_VR_P0V8_FR_MISC_S0 + +hwmon_in.mode_0x000d_0x02=str_constant +hwmon_in.str_cons_0x000d_0x02=UCD90160_01 + +hwmon_in.mode_0x000d_0x03=constant +hwmon_in.int_cons_0x000d_0x03=1240 + +hwmon_in.mode_0x000d_0x05=constant +hwmon_in.int_cons_0x000d_0x05=560 + +monitor_flag_hwmon_in.mode_0x000d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000d_0x00=1 + + +# vol sensor 14 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x000e_0x00=config +hwmon_in.src_0x000e_0x00=file +hwmon_in.int_cons_0x000e_0x00=0 +hwmon_in.frmt_0x000e_0x00=buf +hwmon_in.fpath_0x000e_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x000e_0x00=0 +hwmon_in.len_0x000e_0x00=8 +hwmon_in.str_cons_0x000e_0x00=in14_input +hwmon_in.int_extra1_0x000e_0x00=0 +hwmon_in.int_extra2_0x000e_0x00=0 + +hwmon_in.mode_0x000e_0x01=str_constant +hwmon_in.str_cons_0x000e_0x01=UCD90160_01_VR_P0V8_FR_SOC + +hwmon_in.mode_0x000e_0x02=str_constant +hwmon_in.str_cons_0x000e_0x02=UCD90160_01 + +hwmon_in.mode_0x000e_0x03=constant +hwmon_in.int_cons_0x000e_0x03=1240 + +hwmon_in.mode_0x000e_0x05=constant +hwmon_in.int_cons_0x000e_0x05=560 + +monitor_flag_hwmon_in.mode_0x000e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000e_0x00=1 + + +# vol sensor 15 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x000f_0x00=config +hwmon_in.src_0x000f_0x00=file +hwmon_in.int_cons_0x000f_0x00=0 +hwmon_in.frmt_0x000f_0x00=buf +hwmon_in.fpath_0x000f_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x000f_0x00=0 +hwmon_in.len_0x000f_0x00=8 +hwmon_in.str_cons_0x000f_0x00=in15_input +hwmon_in.int_extra1_0x000f_0x00=0 +hwmon_in.int_extra2_0x000f_0x00=0 + +hwmon_in.mode_0x000f_0x01=str_constant +hwmon_in.str_cons_0x000f_0x01=UCD90160_01_VR_P0V8_FR_CORE + +hwmon_in.mode_0x000f_0x02=str_constant +hwmon_in.str_cons_0x000f_0x02=UCD90160_01 + +hwmon_in.mode_0x000f_0x03=constant +hwmon_in.int_cons_0x000f_0x03=1550 + +hwmon_in.mode_0x000f_0x05=constant +hwmon_in.int_cons_0x000f_0x05=560 + +monitor_flag_hwmon_in.mode_0x000f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000f_0x00=1 + + +# vol sensor 16 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0010_0x00=config +hwmon_in.src_0x0010_0x00=file +hwmon_in.int_cons_0x0010_0x00=0 +hwmon_in.frmt_0x0010_0x00=buf +hwmon_in.fpath_0x0010_0x00=/sys/bus/i2c/devices/54-005f/hwmon/ +hwmon_in.addr_0x0010_0x00=0 +hwmon_in.len_0x0010_0x00=8 +hwmon_in.str_cons_0x0010_0x00=in16_input +hwmon_in.int_extra1_0x0010_0x00=0 +hwmon_in.int_extra2_0x0010_0x00=0 + +hwmon_in.mode_0x0010_0x01=str_constant +hwmon_in.str_cons_0x0010_0x01=UCD90160_01_P1V8_STBY + +hwmon_in.mode_0x0010_0x02=str_constant +hwmon_in.str_cons_0x0010_0x02=UCD90160_01 + +hwmon_in.mode_0x0010_0x03=constant +hwmon_in.int_cons_0x0010_0x03=1910 + +hwmon_in.mode_0x0010_0x05=constant +hwmon_in.int_cons_0x0010_0x05=1690 + +monitor_flag_hwmon_in.mode_0x0010_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0010_0x00=1 + + +# vol sensor 17 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0011_0x00=config +hwmon_in.src_0x0011_0x00=file +hwmon_in.int_cons_0x0011_0x00=0 +hwmon_in.frmt_0x0011_0x00=buf +hwmon_in.fpath_0x0011_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0011_0x00=0 +hwmon_in.len_0x0011_0x00=8 +hwmon_in.str_cons_0x0011_0x00=in1_input +hwmon_in.int_extra1_0x0011_0x00=0 +hwmon_in.int_extra2_0x0011_0x00=0 + +hwmon_in.mode_0x0011_0x01=str_constant +hwmon_in.str_cons_0x0011_0x01=UCD90160_VCC_3V3_BMC + +hwmon_in.mode_0x0011_0x02=str_constant +hwmon_in.str_cons_0x0011_0x02=UCD90160 + +hwmon_in.mode_0x0011_0x03=constant +hwmon_in.int_cons_0x0011_0x03=3630 + +hwmon_in.mode_0x0011_0x05=constant +hwmon_in.int_cons_0x0011_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0011_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0011_0x00=1 + + +# vol sensor 18 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0012_0x00=config +hwmon_in.src_0x0012_0x00=file +hwmon_in.int_cons_0x0012_0x00=0 +hwmon_in.frmt_0x0012_0x00=buf +hwmon_in.fpath_0x0012_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0012_0x00=0 +hwmon_in.len_0x0012_0x00=8 +hwmon_in.str_cons_0x0012_0x00=in2_input +hwmon_in.int_extra1_0x0012_0x00=0 +hwmon_in.int_extra2_0x0012_0x00=0 + +hwmon_in.mode_0x0012_0x01=str_constant +hwmon_in.str_cons_0x0012_0x01=UCD90160_VCC_1V0 + +hwmon_in.mode_0x0012_0x02=str_constant +hwmon_in.str_cons_0x0012_0x02=UCD90160 + +hwmon_in.mode_0x0012_0x03=constant +hwmon_in.int_cons_0x0012_0x03=1100 + +hwmon_in.mode_0x0012_0x05=constant +hwmon_in.int_cons_0x0012_0x05=900 + +monitor_flag_hwmon_in.mode_0x0012_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0012_0x00=1 + + +# vol sensor 19 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0013_0x00=config +hwmon_in.src_0x0013_0x00=file +hwmon_in.int_cons_0x0013_0x00=0 +hwmon_in.frmt_0x0013_0x00=buf +hwmon_in.fpath_0x0013_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0013_0x00=0 +hwmon_in.len_0x0013_0x00=8 +hwmon_in.str_cons_0x0013_0x00=in3_input +hwmon_in.int_extra1_0x0013_0x00=0 +hwmon_in.int_extra2_0x0013_0x00=0 + +hwmon_in.mode_0x0013_0x01=str_constant +hwmon_in.str_cons_0x0013_0x01=UCD90160_VCC_1V8_BMC + +hwmon_in.mode_0x0013_0x02=str_constant +hwmon_in.str_cons_0x0013_0x02=UCD90160 + +hwmon_in.mode_0x0013_0x03=constant +hwmon_in.int_cons_0x0013_0x03=1980 + +hwmon_in.mode_0x0013_0x05=constant +hwmon_in.int_cons_0x0013_0x05=1620 + +monitor_flag_hwmon_in.mode_0x0013_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0013_0x00=1 + + +# vol sensor 20 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0014_0x00=config +hwmon_in.src_0x0014_0x00=file +hwmon_in.int_cons_0x0014_0x00=0 +hwmon_in.frmt_0x0014_0x00=buf +hwmon_in.fpath_0x0014_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0014_0x00=0 +hwmon_in.len_0x0014_0x00=8 +hwmon_in.str_cons_0x0014_0x00=in4_input +hwmon_in.int_extra1_0x0014_0x00=0 +hwmon_in.int_extra2_0x0014_0x00=0 + +hwmon_in.mode_0x0014_0x01=str_constant +hwmon_in.str_cons_0x0014_0x01=UCD90160_VCC_1V2_BMC + +hwmon_in.mode_0x0014_0x02=str_constant +hwmon_in.str_cons_0x0014_0x02=UCD90160 + +hwmon_in.mode_0x0014_0x03=constant +hwmon_in.int_cons_0x0014_0x03=1353 + +hwmon_in.mode_0x0014_0x05=constant +hwmon_in.int_cons_0x0014_0x05=1107 + +monitor_flag_hwmon_in.mode_0x0014_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0014_0x00=1 + + +# vol sensor 21 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0015_0x00=config +hwmon_in.src_0x0015_0x00=file +hwmon_in.int_cons_0x0015_0x00=0 +hwmon_in.frmt_0x0015_0x00=buf +hwmon_in.fpath_0x0015_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0015_0x00=0 +hwmon_in.len_0x0015_0x00=8 +hwmon_in.str_cons_0x0015_0x00=in5_input +hwmon_in.int_extra1_0x0015_0x00=0 +hwmon_in.int_extra2_0x0015_0x00=0 + +hwmon_in.mode_0x0015_0x01=str_constant +hwmon_in.str_cons_0x0015_0x01=UCD90160_VCC_1V1_BMC + +hwmon_in.mode_0x0015_0x02=str_constant +hwmon_in.str_cons_0x0015_0x02=UCD90160 + +hwmon_in.mode_0x0015_0x03=constant +hwmon_in.int_cons_0x0015_0x03=1265 + +hwmon_in.mode_0x0015_0x05=constant +hwmon_in.int_cons_0x0015_0x05=1035 + +monitor_flag_hwmon_in.mode_0x0015_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0015_0x00=1 + + +# vol sensor 22 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0016_0x00=config +hwmon_in.src_0x0016_0x00=file +hwmon_in.int_cons_0x0016_0x00=0 +hwmon_in.frmt_0x0016_0x00=buf +hwmon_in.fpath_0x0016_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0016_0x00=0 +hwmon_in.len_0x0016_0x00=8 +hwmon_in.str_cons_0x0016_0x00=in6_input +hwmon_in.int_extra1_0x0016_0x00=0 +hwmon_in.int_extra2_0x0016_0x00=0 + +hwmon_in.mode_0x0016_0x01=str_constant +hwmon_in.str_cons_0x0016_0x01=UCD90160_VCC_1V15_DDRVDDQ + +hwmon_in.mode_0x0016_0x02=str_constant +hwmon_in.str_cons_0x0016_0x02=UCD90160 + +hwmon_in.mode_0x0016_0x03=constant +hwmon_in.int_cons_0x0016_0x03=1265 + +hwmon_in.mode_0x0016_0x05=constant +hwmon_in.int_cons_0x0016_0x05=1035 + +monitor_flag_hwmon_in.mode_0x0016_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0016_0x00=1 + + +# vol sensor 23 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0017_0x00=config +hwmon_in.src_0x0017_0x00=file +hwmon_in.int_cons_0x0017_0x00=0 +hwmon_in.frmt_0x0017_0x00=buf +hwmon_in.fpath_0x0017_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0017_0x00=0 +hwmon_in.len_0x0017_0x00=8 +hwmon_in.str_cons_0x0017_0x00=in7_input +hwmon_in.int_extra1_0x0017_0x00=0 +hwmon_in.int_extra2_0x0017_0x00=0 + +hwmon_in.mode_0x0017_0x01=str_constant +hwmon_in.str_cons_0x0017_0x01=UCD90160_VCC_0V8_BMC + +hwmon_in.mode_0x0017_0x02=str_constant +hwmon_in.str_cons_0x0017_0x02=UCD90160 + +hwmon_in.mode_0x0017_0x03=constant +hwmon_in.int_cons_0x0017_0x03=946 + +hwmon_in.mode_0x0017_0x05=constant +hwmon_in.int_cons_0x0017_0x05=774 + +monitor_flag_hwmon_in.mode_0x0017_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0017_0x00=1 + + +# vol sensor 24 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0018_0x00=config +hwmon_in.src_0x0018_0x00=file +hwmon_in.int_cons_0x0018_0x00=0 +hwmon_in.frmt_0x0018_0x00=buf +hwmon_in.fpath_0x0018_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0018_0x00=0 +hwmon_in.len_0x0018_0x00=8 +hwmon_in.str_cons_0x0018_0x00=in8_input +hwmon_in.int_extra1_0x0018_0x00=0 +hwmon_in.int_extra2_0x0018_0x00=0 + +hwmon_in.mode_0x0018_0x01=str_constant +hwmon_in.str_cons_0x0018_0x01=UCD90160_V3P3_EMMC_OUT + +hwmon_in.mode_0x0018_0x02=str_constant +hwmon_in.str_cons_0x0018_0x02=UCD90160 + +hwmon_in.mode_0x0018_0x03=constant +hwmon_in.int_cons_0x0018_0x03=3630 + +hwmon_in.mode_0x0018_0x05=constant +hwmon_in.int_cons_0x0018_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0018_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0018_0x00=1 + + +# vol sensor 25 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0019_0x00=config +hwmon_in.src_0x0019_0x00=file +hwmon_in.int_cons_0x0019_0x00=0 +hwmon_in.frmt_0x0019_0x00=buf +hwmon_in.fpath_0x0019_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x0019_0x00=0 +hwmon_in.len_0x0019_0x00=8 +hwmon_in.str_cons_0x0019_0x00=in9_input +hwmon_in.int_extra1_0x0019_0x00=0 +hwmon_in.int_extra2_0x0019_0x00=0 + +hwmon_in.mode_0x0019_0x01=str_constant +hwmon_in.str_cons_0x0019_0x01=UCD90160_V1P80_EMMC_OUT + +hwmon_in.mode_0x0019_0x02=str_constant +hwmon_in.str_cons_0x0019_0x02=UCD90160 + +hwmon_in.mode_0x0019_0x03=constant +hwmon_in.int_cons_0x0019_0x03=1980 + +hwmon_in.mode_0x0019_0x05=constant +hwmon_in.int_cons_0x0019_0x05=1620 + +monitor_flag_hwmon_in.mode_0x0019_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0019_0x00=1 + + +# vol sensor 26 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x001a_0x00=config +hwmon_in.src_0x001a_0x00=file +hwmon_in.int_cons_0x001a_0x00=0 +hwmon_in.frmt_0x001a_0x00=buf +hwmon_in.fpath_0x001a_0x00=/sys/bus/i2c/devices/57-0068/hwmon/ +hwmon_in.addr_0x001a_0x00=0 +hwmon_in.len_0x001a_0x00=8 +hwmon_in.str_cons_0x001a_0x00=in10_input +hwmon_in.int_extra1_0x001a_0x00=0 +hwmon_in.int_extra2_0x001a_0x00=0 + +hwmon_in.mode_0x001a_0x01=str_constant +hwmon_in.str_cons_0x001a_0x01=UCD90160_VCC_3V3 + +hwmon_in.mode_0x001a_0x02=str_constant +hwmon_in.str_cons_0x001a_0x02=UCD90160 + +hwmon_in.mode_0x001a_0x03=constant +hwmon_in.int_cons_0x001a_0x03=3630 + +hwmon_in.mode_0x001a_0x05=constant +hwmon_in.int_cons_0x001a_0x05=2970 + +monitor_flag_hwmon_in.mode_0x001a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001a_0x00=1 + + +# vol sensor 27 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x001b_0x00=config +hwmon_in.src_0x001b_0x00=file +hwmon_in.int_cons_0x001b_0x00=0 +hwmon_in.frmt_0x001b_0x00=buf +hwmon_in.fpath_0x001b_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x001b_0x00=0 +hwmon_in.len_0x001b_0x00=8 +hwmon_in.str_cons_0x001b_0x00=in1_input +hwmon_in.int_extra1_0x001b_0x00=0 +hwmon_in.int_extra2_0x001b_0x00=0 + +hwmon_in.mode_0x001b_0x01=str_constant +hwmon_in.str_cons_0x001b_0x01=UCD90160_02_VDD12V_MGMT_V + +hwmon_in.mode_0x001b_0x02=str_constant +hwmon_in.str_cons_0x001b_0x02=UCD90160_02 + +hwmon_in.mode_0x001b_0x03=constant +hwmon_in.int_cons_0x001b_0x03=13200 + +hwmon_in.mode_0x001b_0x05=constant +hwmon_in.int_cons_0x001b_0x05=10800 + +monitor_flag_hwmon_in.mode_0x001b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001b_0x00=1 + + +# vol sensor 28 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x001c_0x00=config +hwmon_in.src_0x001c_0x00=file +hwmon_in.int_cons_0x001c_0x00=0 +hwmon_in.frmt_0x001c_0x00=buf +hwmon_in.fpath_0x001c_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x001c_0x00=0 +hwmon_in.len_0x001c_0x00=8 +hwmon_in.str_cons_0x001c_0x00=in2_input +hwmon_in.int_extra1_0x001c_0x00=0 +hwmon_in.int_extra2_0x001c_0x00=0 + +hwmon_in.mode_0x001c_0x01=str_constant +hwmon_in.str_cons_0x001c_0x01=UCD90160_02_VDD3V3_STBY_V + +hwmon_in.mode_0x001c_0x02=str_constant +hwmon_in.str_cons_0x001c_0x02=UCD90160_02 + +hwmon_in.mode_0x001c_0x03=constant +hwmon_in.int_cons_0x001c_0x03=3630 + +hwmon_in.mode_0x001c_0x05=constant +hwmon_in.int_cons_0x001c_0x05=2970 + +monitor_flag_hwmon_in.mode_0x001c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001c_0x00=1 + + +# vol sensor 29 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x001d_0x00=config +hwmon_in.src_0x001d_0x00=file +hwmon_in.int_cons_0x001d_0x00=0 +hwmon_in.frmt_0x001d_0x00=buf +hwmon_in.fpath_0x001d_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x001d_0x00=0 +hwmon_in.len_0x001d_0x00=8 +hwmon_in.str_cons_0x001d_0x00=in3_input +hwmon_in.int_extra1_0x001d_0x00=0 +hwmon_in.int_extra2_0x001d_0x00=0 + +hwmon_in.mode_0x001d_0x01=str_constant +hwmon_in.str_cons_0x001d_0x01=UCD90160_02_VDD5V_USB_V + +hwmon_in.mode_0x001d_0x02=str_constant +hwmon_in.str_cons_0x001d_0x02=UCD90160_02 + +hwmon_in.mode_0x001d_0x03=constant +hwmon_in.int_cons_0x001d_0x03=5500 + +hwmon_in.mode_0x001d_0x05=constant +hwmon_in.int_cons_0x001d_0x05=4500 + +monitor_flag_hwmon_in.mode_0x001d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001d_0x00=1 + + +# vol sensor 30 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x001e_0x00=config +hwmon_in.src_0x001e_0x00=file +hwmon_in.int_cons_0x001e_0x00=0 +hwmon_in.frmt_0x001e_0x00=buf +hwmon_in.fpath_0x001e_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x001e_0x00=0 +hwmon_in.len_0x001e_0x00=8 +hwmon_in.str_cons_0x001e_0x00=in4_input +hwmon_in.int_extra1_0x001e_0x00=0 +hwmon_in.int_extra2_0x001e_0x00=0 + +hwmon_in.mode_0x001e_0x01=str_constant +hwmon_in.str_cons_0x001e_0x01=UCD90160_02_PHY_VDD1V0_V + +hwmon_in.mode_0x001e_0x02=str_constant +hwmon_in.str_cons_0x001e_0x02=UCD90160_02 + +hwmon_in.mode_0x001e_0x03=constant +hwmon_in.int_cons_0x001e_0x03=1100 + +hwmon_in.mode_0x001e_0x05=constant +hwmon_in.int_cons_0x001e_0x05=900 + +monitor_flag_hwmon_in.mode_0x001e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001e_0x00=1 + + +# vol sensor 31 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x001f_0x00=config +hwmon_in.src_0x001f_0x00=file +hwmon_in.int_cons_0x001f_0x00=0 +hwmon_in.frmt_0x001f_0x00=buf +hwmon_in.fpath_0x001f_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x001f_0x00=0 +hwmon_in.len_0x001f_0x00=8 +hwmon_in.str_cons_0x001f_0x00=in5_input +hwmon_in.int_extra1_0x001f_0x00=0 +hwmon_in.int_extra2_0x001f_0x00=0 + +hwmon_in.mode_0x001f_0x01=str_constant +hwmon_in.str_cons_0x001f_0x01=UCD90160_02_VDD3V3_MGMT_V + +hwmon_in.mode_0x001f_0x02=str_constant +hwmon_in.str_cons_0x001f_0x02=UCD90160_02 + +hwmon_in.mode_0x001f_0x03=constant +hwmon_in.int_cons_0x001f_0x03=3630 + +hwmon_in.mode_0x001f_0x05=constant +hwmon_in.int_cons_0x001f_0x05=2970 + +monitor_flag_hwmon_in.mode_0x001f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001f_0x00=1 + + +# vol sensor 32 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0020_0x00=config +hwmon_in.src_0x0020_0x00=file +hwmon_in.int_cons_0x0020_0x00=0 +hwmon_in.frmt_0x0020_0x00=buf +hwmon_in.fpath_0x0020_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0020_0x00=0 +hwmon_in.len_0x0020_0x00=8 +hwmon_in.str_cons_0x0020_0x00=in6_input +hwmon_in.int_extra1_0x0020_0x00=0 +hwmon_in.int_extra2_0x0020_0x00=0 + +hwmon_in.mode_0x0020_0x01=str_constant +hwmon_in.str_cons_0x0020_0x01=UCD90160_02_VDD3V3_CLK_MGMT_V + +hwmon_in.mode_0x0020_0x02=str_constant +hwmon_in.str_cons_0x0020_0x02=UCD90160_02 + +hwmon_in.mode_0x0020_0x03=constant +hwmon_in.int_cons_0x0020_0x03=3630 + +hwmon_in.mode_0x0020_0x05=constant +hwmon_in.int_cons_0x0020_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0020_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0020_0x00=1 + + +# vol sensor 33 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0021_0x00=config +hwmon_in.src_0x0021_0x00=file +hwmon_in.int_cons_0x0021_0x00=0 +hwmon_in.frmt_0x0021_0x00=buf +hwmon_in.fpath_0x0021_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0021_0x00=0 +hwmon_in.len_0x0021_0x00=8 +hwmon_in.str_cons_0x0021_0x00=in7_input +hwmon_in.int_extra1_0x0021_0x00=0 +hwmon_in.int_extra2_0x0021_0x00=0 + +hwmon_in.mode_0x0021_0x01=str_constant +hwmon_in.str_cons_0x0021_0x01=UCD90160_02_BMC_VCC3V3_OUT_V + +hwmon_in.mode_0x0021_0x02=str_constant +hwmon_in.str_cons_0x0021_0x02=UCD90160_02 + +hwmon_in.mode_0x0021_0x03=constant +hwmon_in.int_cons_0x0021_0x03=3630 + +hwmon_in.mode_0x0021_0x05=constant +hwmon_in.int_cons_0x0021_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0021_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0021_0x00=1 + + +# vol sensor 34 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0022_0x00=config +hwmon_in.src_0x0022_0x00=file +hwmon_in.int_cons_0x0022_0x00=0 +hwmon_in.frmt_0x0022_0x00=buf +hwmon_in.fpath_0x0022_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0022_0x00=0 +hwmon_in.len_0x0022_0x00=8 +hwmon_in.str_cons_0x0022_0x00=in8_input +hwmon_in.int_extra1_0x0022_0x00=0 +hwmon_in.int_extra2_0x0022_0x00=0 + +hwmon_in.mode_0x0022_0x01=str_constant +hwmon_in.str_cons_0x0022_0x01=UCD90160_02_SSD_VDD3V3_V + +hwmon_in.mode_0x0022_0x02=str_constant +hwmon_in.str_cons_0x0022_0x02=UCD90160_02 + +hwmon_in.mode_0x0022_0x03=constant +hwmon_in.int_cons_0x0022_0x03=3630 + +hwmon_in.mode_0x0022_0x05=constant +hwmon_in.int_cons_0x0022_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0022_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0022_0x00=1 + + +# vol sensor 35 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0023_0x00=config +hwmon_in.src_0x0023_0x00=file +hwmon_in.int_cons_0x0023_0x00=0 +hwmon_in.frmt_0x0023_0x00=buf +hwmon_in.fpath_0x0023_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0023_0x00=0 +hwmon_in.len_0x0023_0x00=8 +hwmon_in.str_cons_0x0023_0x00=in9_input +hwmon_in.int_extra1_0x0023_0x00=0 +hwmon_in.int_extra2_0x0023_0x00=0 + +hwmon_in.mode_0x0023_0x01=str_constant +hwmon_in.str_cons_0x0023_0x01=UCD90160_02_VDD3V8_CLK_V + +hwmon_in.mode_0x0023_0x02=str_constant +hwmon_in.str_cons_0x0023_0x02=UCD90160_02 + +hwmon_in.mode_0x0023_0x03=constant +hwmon_in.int_cons_0x0023_0x03=3993 + +hwmon_in.mode_0x0023_0x05=constant +hwmon_in.int_cons_0x0023_0x05=3267 + +monitor_flag_hwmon_in.mode_0x0023_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0023_0x00=1 + + +# vol sensor 36 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0024_0x00=config +hwmon_in.src_0x0024_0x00=file +hwmon_in.int_cons_0x0024_0x00=0 +hwmon_in.frmt_0x0024_0x00=buf +hwmon_in.fpath_0x0024_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0024_0x00=0 +hwmon_in.len_0x0024_0x00=8 +hwmon_in.str_cons_0x0024_0x00=in10_input +hwmon_in.int_extra1_0x0024_0x00=0 +hwmon_in.int_extra2_0x0024_0x00=0 + +hwmon_in.mode_0x0024_0x01=str_constant +hwmon_in.str_cons_0x0024_0x01=UCD90160_02_AVDD0_8V + +hwmon_in.mode_0x0024_0x02=str_constant +hwmon_in.str_cons_0x0024_0x02=UCD90160_02 + +hwmon_in.mode_0x0024_0x03=constant +hwmon_in.int_cons_0x0024_0x03=880 + +hwmon_in.mode_0x0024_0x05=constant +hwmon_in.int_cons_0x0024_0x05=720 + +monitor_flag_hwmon_in.mode_0x0024_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0024_0x00=1 + + +# vol sensor 37 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0025_0x00=config +hwmon_in.src_0x0025_0x00=file +hwmon_in.int_cons_0x0025_0x00=0 +hwmon_in.frmt_0x0025_0x00=buf +hwmon_in.fpath_0x0025_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0025_0x00=0 +hwmon_in.len_0x0025_0x00=8 +hwmon_in.str_cons_0x0025_0x00=in11_input +hwmon_in.int_extra1_0x0025_0x00=0 +hwmon_in.int_extra2_0x0025_0x00=0 + +hwmon_in.mode_0x0025_0x01=str_constant +hwmon_in.str_cons_0x0025_0x01=UCD90160_02_DVDD0_8V + +hwmon_in.mode_0x0025_0x02=str_constant +hwmon_in.str_cons_0x0025_0x02=UCD90160_02 + +hwmon_in.mode_0x0025_0x03=constant +hwmon_in.int_cons_0x0025_0x03=968 + +hwmon_in.mode_0x0025_0x05=constant +hwmon_in.int_cons_0x0025_0x05=792 + +monitor_flag_hwmon_in.mode_0x0025_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0025_0x00=1 + + +# vol sensor 38 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0026_0x00=config +hwmon_in.src_0x0026_0x00=file +hwmon_in.int_cons_0x0026_0x00=0 +hwmon_in.frmt_0x0026_0x00=buf +hwmon_in.fpath_0x0026_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0026_0x00=0 +hwmon_in.len_0x0026_0x00=8 +hwmon_in.str_cons_0x0026_0x00=in12_input +hwmon_in.int_extra1_0x0026_0x00=0 +hwmon_in.int_extra2_0x0026_0x00=0 + +hwmon_in.mode_0x0026_0x01=str_constant +hwmon_in.str_cons_0x0026_0x01=UCD90160_02_PORT_VCC3.3V + +hwmon_in.mode_0x0026_0x02=str_constant +hwmon_in.str_cons_0x0026_0x02=UCD90160_02 + +hwmon_in.mode_0x0026_0x03=constant +hwmon_in.int_cons_0x0026_0x03=3630 + +hwmon_in.mode_0x0026_0x05=constant +hwmon_in.int_cons_0x0026_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0026_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0026_0x00=1 + + +# vol sensor 39 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0027_0x00=config +hwmon_in.src_0x0027_0x00=file +hwmon_in.int_cons_0x0027_0x00=0 +hwmon_in.frmt_0x0027_0x00=buf +hwmon_in.fpath_0x0027_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0027_0x00=0 +hwmon_in.len_0x0027_0x00=8 +hwmon_in.str_cons_0x0027_0x00=in13_input +hwmon_in.int_extra1_0x0027_0x00=0 +hwmon_in.int_extra2_0x0027_0x00=0 + +hwmon_in.mode_0x0027_0x01=str_constant +hwmon_in.str_cons_0x0027_0x01=UCD90160_02_VDD1.1V_HUB + +hwmon_in.mode_0x0027_0x02=str_constant +hwmon_in.str_cons_0x0027_0x02=UCD90160_02 + +hwmon_in.mode_0x0027_0x03=constant +hwmon_in.int_cons_0x0027_0x03=1210 + +hwmon_in.mode_0x0027_0x05=constant +hwmon_in.int_cons_0x0027_0x05=990 + +monitor_flag_hwmon_in.mode_0x0027_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0027_0x00=1 + + +# vol sensor 40 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0028_0x00=config +hwmon_in.src_0x0028_0x00=file +hwmon_in.int_cons_0x0028_0x00=0 +hwmon_in.frmt_0x0028_0x00=buf +hwmon_in.fpath_0x0028_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0028_0x00=0 +hwmon_in.len_0x0028_0x00=8 +hwmon_in.str_cons_0x0028_0x00=in14_input +hwmon_in.int_extra1_0x0028_0x00=0 +hwmon_in.int_extra2_0x0028_0x00=0 + +hwmon_in.mode_0x0028_0x01=str_constant +hwmon_in.str_cons_0x0028_0x01=UCD90160_02_VDD1.8V + +hwmon_in.mode_0x0028_0x02=str_constant +hwmon_in.str_cons_0x0028_0x02=UCD90160_02 + +hwmon_in.mode_0x0028_0x03=constant +hwmon_in.int_cons_0x0028_0x03=1980 + +hwmon_in.mode_0x0028_0x05=constant +hwmon_in.int_cons_0x0028_0x05=1620 + +monitor_flag_hwmon_in.mode_0x0028_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0028_0x00=1 + + +# vol sensor 41 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0029_0x00=config +hwmon_in.src_0x0029_0x00=file +hwmon_in.int_cons_0x0029_0x00=0 +hwmon_in.frmt_0x0029_0x00=buf +hwmon_in.fpath_0x0029_0x00=/sys/bus/i2c/devices/53-005b/hwmon/ +hwmon_in.addr_0x0029_0x00=0 +hwmon_in.len_0x0029_0x00=8 +hwmon_in.str_cons_0x0029_0x00=in15_input +hwmon_in.int_extra1_0x0029_0x00=0 +hwmon_in.int_extra2_0x0029_0x00=0 + +hwmon_in.mode_0x0029_0x01=str_constant +hwmon_in.str_cons_0x0029_0x01=UCD90160_02_SSD2_VDD3V3_V + +hwmon_in.mode_0x0029_0x02=str_constant +hwmon_in.str_cons_0x0029_0x02=UCD90160_02 + +hwmon_in.mode_0x0029_0x03=constant +hwmon_in.int_cons_0x0029_0x03=3630 + +hwmon_in.mode_0x0029_0x05=constant +hwmon_in.int_cons_0x0029_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0029_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0029_0x00=1 + + +# vol sensor 42 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x002a_0x00=config +hwmon_in.src_0x002a_0x00=file +hwmon_in.int_cons_0x002a_0x00=3 +hwmon_in.frmt_0x002a_0x00=buf +hwmon_in.fpath_0x002a_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x002a_0x00=0 +hwmon_in.len_0x002a_0x00=8 +hwmon_in.str_cons_0x002a_0x00=in0_input +hwmon_in.int_extra1_0x002a_0x00=1833 +hwmon_in.int_extra2_0x002a_0x00=0 + +hwmon_in.mode_0x002a_0x01=str_constant +hwmon_in.str_cons_0x002a_0x01=ADS7828E_01_VDD3.3V_NIC + +hwmon_in.mode_0x002a_0x02=str_constant +hwmon_in.str_cons_0x002a_0x02=ADS7828E_01 + +hwmon_in.mode_0x002a_0x03=constant +hwmon_in.int_cons_0x002a_0x03=3630 + +hwmon_in.mode_0x002a_0x05=constant +hwmon_in.int_cons_0x002a_0x05=2970 + +monitor_flag_hwmon_in.mode_0x002a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002a_0x00=1 + + +# vol sensor 43 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x002b_0x00=config +hwmon_in.src_0x002b_0x00=file +hwmon_in.int_cons_0x002b_0x00=0 +hwmon_in.frmt_0x002b_0x00=buf +hwmon_in.fpath_0x002b_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x002b_0x00=0 +hwmon_in.len_0x002b_0x00=8 +hwmon_in.str_cons_0x002b_0x00=in1_input +hwmon_in.int_extra1_0x002b_0x00=0 +hwmon_in.int_extra2_0x002b_0x00=0 + +hwmon_in.mode_0x002b_0x01=str_constant +hwmon_in.str_cons_0x002b_0x01=ADS7828E_01_VDD1.8V_2 + +hwmon_in.mode_0x002b_0x02=str_constant +hwmon_in.str_cons_0x002b_0x02=ADS7828E_01 + +hwmon_in.mode_0x002b_0x03=constant +hwmon_in.int_cons_0x002b_0x03=1980 + +hwmon_in.mode_0x002b_0x05=constant +hwmon_in.int_cons_0x002b_0x05=1620 + +monitor_flag_hwmon_in.mode_0x002b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002b_0x00=1 + + +# vol sensor 44 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x002c_0x00=config +hwmon_in.src_0x002c_0x00=file +hwmon_in.int_cons_0x002c_0x00=0 +hwmon_in.frmt_0x002c_0x00=buf +hwmon_in.fpath_0x002c_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x002c_0x00=0 +hwmon_in.len_0x002c_0x00=8 +hwmon_in.str_cons_0x002c_0x00=in2_input +hwmon_in.int_extra1_0x002c_0x00=0 +hwmon_in.int_extra2_0x002c_0x00=0 + +hwmon_in.mode_0x002c_0x01=str_constant +hwmon_in.str_cons_0x002c_0x01=ADS7828E_01_VDD0.85V + +hwmon_in.mode_0x002c_0x02=str_constant +hwmon_in.str_cons_0x002c_0x02=ADS7828E_01 + +hwmon_in.mode_0x002c_0x03=constant +hwmon_in.int_cons_0x002c_0x03=935 + +hwmon_in.mode_0x002c_0x05=constant +hwmon_in.int_cons_0x002c_0x05=765 + +monitor_flag_hwmon_in.mode_0x002c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002c_0x00=1 + + +# vol sensor 45 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x002d_0x00=config +hwmon_in.src_0x002d_0x00=file +hwmon_in.int_cons_0x002d_0x00=0 +hwmon_in.frmt_0x002d_0x00=buf +hwmon_in.fpath_0x002d_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x002d_0x00=0 +hwmon_in.len_0x002d_0x00=8 +hwmon_in.str_cons_0x002d_0x00=in3_input +hwmon_in.int_extra1_0x002d_0x00=0 +hwmon_in.int_extra2_0x002d_0x00=0 + +hwmon_in.mode_0x002d_0x01=str_constant +hwmon_in.str_cons_0x002d_0x01=ADS7828E_01_VDD2.3V + +hwmon_in.mode_0x002d_0x02=str_constant +hwmon_in.str_cons_0x002d_0x02=ADS7828E_01 + +hwmon_in.mode_0x002d_0x03=constant +hwmon_in.int_cons_0x002d_0x03=2530 + +hwmon_in.mode_0x002d_0x05=constant +hwmon_in.int_cons_0x002d_0x05=2070 + +monitor_flag_hwmon_in.mode_0x002d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002d_0x00=1 + + +# vol sensor 46 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x002e_0x00=config +hwmon_in.src_0x002e_0x00=file +hwmon_in.int_cons_0x002e_0x00=0 +hwmon_in.frmt_0x002e_0x00=buf +hwmon_in.fpath_0x002e_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x002e_0x00=0 +hwmon_in.len_0x002e_0x00=8 +hwmon_in.str_cons_0x002e_0x00=in4_input +hwmon_in.int_extra1_0x002e_0x00=0 +hwmon_in.int_extra2_0x002e_0x00=0 + +hwmon_in.mode_0x002e_0x01=str_constant +hwmon_in.str_cons_0x002e_0x01=ADS7828E_01_VDD0.9V + +hwmon_in.mode_0x002e_0x02=str_constant +hwmon_in.str_cons_0x002e_0x02=ADS7828E_01 + +hwmon_in.mode_0x002e_0x03=constant +hwmon_in.int_cons_0x002e_0x03=990 + +hwmon_in.mode_0x002e_0x05=constant +hwmon_in.int_cons_0x002e_0x05=810 + +monitor_flag_hwmon_in.mode_0x002e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002e_0x00=1 + + +# vol sensor 47 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x002f_0x00=config +hwmon_in.src_0x002f_0x00=file +hwmon_in.int_cons_0x002f_0x00=0 +hwmon_in.frmt_0x002f_0x00=buf +hwmon_in.fpath_0x002f_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x002f_0x00=0 +hwmon_in.len_0x002f_0x00=8 +hwmon_in.str_cons_0x002f_0x00=in5_input +hwmon_in.int_extra1_0x002f_0x00=0 +hwmon_in.int_extra2_0x002f_0x00=0 + +hwmon_in.mode_0x002f_0x01=str_constant +hwmon_in.str_cons_0x002f_0x01=ADS7828E_01_VDD0.65V + +hwmon_in.mode_0x002f_0x02=str_constant +hwmon_in.str_cons_0x002f_0x02=ADS7828E_01 + +hwmon_in.mode_0x002f_0x03=constant +hwmon_in.int_cons_0x002f_0x03=715 + +hwmon_in.mode_0x002f_0x05=constant +hwmon_in.int_cons_0x002f_0x05=585 + +monitor_flag_hwmon_in.mode_0x002f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002f_0x00=1 + + +# vol sensor 48 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0030_0x00=config +hwmon_in.src_0x0030_0x00=file +hwmon_in.int_cons_0x0030_0x00=0 +hwmon_in.frmt_0x0030_0x00=buf +hwmon_in.fpath_0x0030_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x0030_0x00=0 +hwmon_in.len_0x0030_0x00=8 +hwmon_in.str_cons_0x0030_0x00=in6_input +hwmon_in.int_extra1_0x0030_0x00=0 +hwmon_in.int_extra2_0x0030_0x00=0 + +hwmon_in.mode_0x0030_0x01=str_constant +hwmon_in.str_cons_0x0030_0x01=ADS7828E_01_VDD0.75V + +hwmon_in.mode_0x0030_0x02=str_constant +hwmon_in.str_cons_0x0030_0x02=ADS7828E_01 + +hwmon_in.mode_0x0030_0x03=constant +hwmon_in.int_cons_0x0030_0x03=825 + +hwmon_in.mode_0x0030_0x05=constant +hwmon_in.int_cons_0x0030_0x05=675 + +monitor_flag_hwmon_in.mode_0x0030_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0030_0x00=1 + + +# vol sensor 49 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0031_0x00=config +hwmon_in.src_0x0031_0x00=file +hwmon_in.int_cons_0x0031_0x00=0 +hwmon_in.frmt_0x0031_0x00=buf +hwmon_in.fpath_0x0031_0x00=/sys/bus/i2c/devices/60-0048/hwmon/ +hwmon_in.addr_0x0031_0x00=0 +hwmon_in.len_0x0031_0x00=8 +hwmon_in.str_cons_0x0031_0x00=in7_input +hwmon_in.int_extra1_0x0031_0x00=0 +hwmon_in.int_extra2_0x0031_0x00=0 + +hwmon_in.mode_0x0031_0x01=str_constant +hwmon_in.str_cons_0x0031_0x01=ADS7828E_01_VDD1.2V + +hwmon_in.mode_0x0031_0x02=str_constant +hwmon_in.str_cons_0x0031_0x02=ADS7828E_01 + +hwmon_in.mode_0x0031_0x03=constant +hwmon_in.int_cons_0x0031_0x03=1320 + +hwmon_in.mode_0x0031_0x05=constant +hwmon_in.int_cons_0x0031_0x05=1080 + +monitor_flag_hwmon_in.mode_0x0031_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0031_0x00=1 + + +# vol sensor 50 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0032_0x00=config +hwmon_in.src_0x0032_0x00=file +hwmon_in.int_cons_0x0032_0x00=0 +hwmon_in.frmt_0x0032_0x00=buf +hwmon_in.fpath_0x0032_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0032_0x00=0 +hwmon_in.len_0x0032_0x00=8 +hwmon_in.str_cons_0x0032_0x00=in1_input +hwmon_in.int_extra1_0x0032_0x00=0 +hwmon_in.int_extra2_0x0032_0x00=0 + +hwmon_in.mode_0x0032_0x01=str_constant +hwmon_in.str_cons_0x0032_0x01=UCD90160_03_VDD12V_MAC_V + +hwmon_in.mode_0x0032_0x02=str_constant +hwmon_in.str_cons_0x0032_0x02=UCD90160_03 + +hwmon_in.mode_0x0032_0x03=constant +hwmon_in.int_cons_0x0032_0x03=13200 + +hwmon_in.mode_0x0032_0x05=constant +hwmon_in.int_cons_0x0032_0x05=10800 + +monitor_flag_hwmon_in.mode_0x0032_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0032_0x00=1 + + +# vol sensor 51 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0033_0x00=config +hwmon_in.src_0x0033_0x00=file +hwmon_in.int_cons_0x0033_0x00=0 +hwmon_in.frmt_0x0033_0x00=buf +hwmon_in.fpath_0x0033_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0033_0x00=0 +hwmon_in.len_0x0033_0x00=8 +hwmon_in.str_cons_0x0033_0x00=in2_input +hwmon_in.int_extra1_0x0033_0x00=0 +hwmon_in.int_extra2_0x0033_0x00=0 + +hwmon_in.mode_0x0033_0x01=str_constant +hwmon_in.str_cons_0x0033_0x01=UCD90160_03_MAC_PLL_1V2_V + +hwmon_in.mode_0x0033_0x02=str_constant +hwmon_in.str_cons_0x0033_0x02=UCD90160_03 + +hwmon_in.mode_0x0033_0x03=constant +hwmon_in.int_cons_0x0033_0x03=1320 + +hwmon_in.mode_0x0033_0x05=constant +hwmon_in.int_cons_0x0033_0x05=1080 + +monitor_flag_hwmon_in.mode_0x0033_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0033_0x00=1 + + +# vol sensor 52 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0034_0x00=config +hwmon_in.src_0x0034_0x00=file +hwmon_in.int_cons_0x0034_0x00=0 +hwmon_in.frmt_0x0034_0x00=buf +hwmon_in.fpath_0x0034_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0034_0x00=0 +hwmon_in.len_0x0034_0x00=8 +hwmon_in.str_cons_0x0034_0x00=in3_input +hwmon_in.int_extra1_0x0034_0x00=0 +hwmon_in.int_extra2_0x0034_0x00=0 + +hwmon_in.mode_0x0034_0x01=str_constant +hwmon_in.str_cons_0x0034_0x01=UCD90160_03_MAC_PLL_1V2_1_V + +hwmon_in.mode_0x0034_0x02=str_constant +hwmon_in.str_cons_0x0034_0x02=UCD90160_03 + +hwmon_in.mode_0x0034_0x03=constant +hwmon_in.int_cons_0x0034_0x03=1320 + +hwmon_in.mode_0x0034_0x05=constant +hwmon_in.int_cons_0x0034_0x05=1080 + +monitor_flag_hwmon_in.mode_0x0034_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0034_0x00=1 + + +# vol sensor 53 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0035_0x00=config +hwmon_in.src_0x0035_0x00=file +hwmon_in.int_cons_0x0035_0x00=0 +hwmon_in.frmt_0x0035_0x00=buf +hwmon_in.fpath_0x0035_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0035_0x00=0 +hwmon_in.len_0x0035_0x00=8 +hwmon_in.str_cons_0x0035_0x00=in4_input +hwmon_in.int_extra1_0x0035_0x00=0 +hwmon_in.int_extra2_0x0035_0x00=0 + +hwmon_in.mode_0x0035_0x01=str_constant +hwmon_in.str_cons_0x0035_0x01=UCD90160_03_FPGA_VDD_1V0_V + +hwmon_in.mode_0x0035_0x02=str_constant +hwmon_in.str_cons_0x0035_0x02=UCD90160_03 + +hwmon_in.mode_0x0035_0x03=constant +hwmon_in.int_cons_0x0035_0x03=1100 + +hwmon_in.mode_0x0035_0x05=constant +hwmon_in.int_cons_0x0035_0x05=900 + +monitor_flag_hwmon_in.mode_0x0035_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0035_0x00=1 + + +# vol sensor 54 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0036_0x00=config +hwmon_in.src_0x0036_0x00=file +hwmon_in.int_cons_0x0036_0x00=0 +hwmon_in.frmt_0x0036_0x00=buf +hwmon_in.fpath_0x0036_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0036_0x00=0 +hwmon_in.len_0x0036_0x00=8 +hwmon_in.str_cons_0x0036_0x00=in5_input +hwmon_in.int_extra1_0x0036_0x00=0 +hwmon_in.int_extra2_0x0036_0x00=0 + +hwmon_in.mode_0x0036_0x01=str_constant +hwmon_in.str_cons_0x0036_0x01=UCD90160_03_FPGA_VDD_1V8_V + +hwmon_in.mode_0x0036_0x02=str_constant +hwmon_in.str_cons_0x0036_0x02=UCD90160_03 + +hwmon_in.mode_0x0036_0x03=constant +hwmon_in.int_cons_0x0036_0x03=1980 + +hwmon_in.mode_0x0036_0x05=constant +hwmon_in.int_cons_0x0036_0x05=1620 + +monitor_flag_hwmon_in.mode_0x0036_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0036_0x00=1 + + +# vol sensor 55 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0037_0x00=config +hwmon_in.src_0x0037_0x00=file +hwmon_in.int_cons_0x0037_0x00=0 +hwmon_in.frmt_0x0037_0x00=buf +hwmon_in.fpath_0x0037_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0037_0x00=0 +hwmon_in.len_0x0037_0x00=8 +hwmon_in.str_cons_0x0037_0x00=in6_input +hwmon_in.int_extra1_0x0037_0x00=0 +hwmon_in.int_extra2_0x0037_0x00=0 + +hwmon_in.mode_0x0037_0x01=str_constant +hwmon_in.str_cons_0x0037_0x01=UCD90160_03_FPGA_VDD_1V2_V + +hwmon_in.mode_0x0037_0x02=str_constant +hwmon_in.str_cons_0x0037_0x02=UCD90160_03 + +hwmon_in.mode_0x0037_0x03=constant +hwmon_in.int_cons_0x0037_0x03=1320 + +hwmon_in.mode_0x0037_0x05=constant +hwmon_in.int_cons_0x0037_0x05=1080 + +monitor_flag_hwmon_in.mode_0x0037_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0037_0x00=1 + + +# vol sensor 56 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0038_0x00=config +hwmon_in.src_0x0038_0x00=file +hwmon_in.int_cons_0x0038_0x00=0 +hwmon_in.frmt_0x0038_0x00=buf +hwmon_in.fpath_0x0038_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0038_0x00=0 +hwmon_in.len_0x0038_0x00=8 +hwmon_in.str_cons_0x0038_0x00=in7_input +hwmon_in.int_extra1_0x0038_0x00=0 +hwmon_in.int_extra2_0x0038_0x00=0 + +hwmon_in.mode_0x0038_0x01=str_constant +hwmon_in.str_cons_0x0038_0x01=UCD90160_03_VDD_3V3_V + +hwmon_in.mode_0x0038_0x02=str_constant +hwmon_in.str_cons_0x0038_0x02=UCD90160_03 + +hwmon_in.mode_0x0038_0x03=constant +hwmon_in.int_cons_0x0038_0x03=3630 + +hwmon_in.mode_0x0038_0x05=constant +hwmon_in.int_cons_0x0038_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0038_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0038_0x00=1 + + +# vol sensor 57 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0039_0x00=config +hwmon_in.src_0x0039_0x00=file +hwmon_in.int_cons_0x0039_0x00=0 +hwmon_in.frmt_0x0039_0x00=buf +hwmon_in.fpath_0x0039_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0039_0x00=0 +hwmon_in.len_0x0039_0x00=8 +hwmon_in.str_cons_0x0039_0x00=in8_input +hwmon_in.int_extra1_0x0039_0x00=0 +hwmon_in.int_extra2_0x0039_0x00=0 + +hwmon_in.mode_0x0039_0x01=str_constant +hwmon_in.str_cons_0x0039_0x01=UCD90160_03_PWR_VDD_5V0_V + +hwmon_in.mode_0x0039_0x02=str_constant +hwmon_in.str_cons_0x0039_0x02=UCD90160_03 + +hwmon_in.mode_0x0039_0x03=constant +hwmon_in.int_cons_0x0039_0x03=5500 + +hwmon_in.mode_0x0039_0x05=constant +hwmon_in.int_cons_0x0039_0x05=4500 + +monitor_flag_hwmon_in.mode_0x0039_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0039_0x00=1 + + +# vol sensor 58 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x003a_0x00=config +hwmon_in.src_0x003a_0x00=file +hwmon_in.int_cons_0x003a_0x00=0 +hwmon_in.frmt_0x003a_0x00=buf +hwmon_in.fpath_0x003a_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x003a_0x00=0 +hwmon_in.len_0x003a_0x00=8 +hwmon_in.str_cons_0x003a_0x00=in9_input +hwmon_in.int_extra1_0x003a_0x00=0 +hwmon_in.int_extra2_0x003a_0x00=0 + +hwmon_in.mode_0x003a_0x01=str_constant +hwmon_in.str_cons_0x003a_0x01=UCD90160_03_PWR_VDD_5V0_1_V + +hwmon_in.mode_0x003a_0x02=str_constant +hwmon_in.str_cons_0x003a_0x02=UCD90160_03 + +hwmon_in.mode_0x003a_0x03=constant +hwmon_in.int_cons_0x003a_0x03=5500 + +hwmon_in.mode_0x003a_0x05=constant +hwmon_in.int_cons_0x003a_0x05=4500 + +monitor_flag_hwmon_in.mode_0x003a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x003a_0x00=1 + + +# vol sensor 59 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x003b_0x00=config +hwmon_in.src_0x003b_0x00=file +hwmon_in.int_cons_0x003b_0x00=0 +hwmon_in.frmt_0x003b_0x00=buf +hwmon_in.fpath_0x003b_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x003b_0x00=0 +hwmon_in.len_0x003b_0x00=8 +hwmon_in.str_cons_0x003b_0x00=in10_input +hwmon_in.int_extra1_0x003b_0x00=0 +hwmon_in.int_extra2_0x003b_0x00=0 + +hwmon_in.mode_0x003b_0x01=str_constant +hwmon_in.str_cons_0x003b_0x01=UCD90160_03_PWR_VDD_5V0_2_V + +hwmon_in.mode_0x003b_0x02=str_constant +hwmon_in.str_cons_0x003b_0x02=UCD90160_03 + +hwmon_in.mode_0x003b_0x03=constant +hwmon_in.int_cons_0x003b_0x03=5500 + +hwmon_in.mode_0x003b_0x05=constant +hwmon_in.int_cons_0x003b_0x05=4500 + +monitor_flag_hwmon_in.mode_0x003b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x003b_0x00=1 + + +# vol sensor 60 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x003c_0x00=config +hwmon_in.src_0x003c_0x00=file +hwmon_in.int_cons_0x003c_0x00=0 +hwmon_in.frmt_0x003c_0x00=buf +hwmon_in.fpath_0x003c_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x003c_0x00=0 +hwmon_in.len_0x003c_0x00=8 +hwmon_in.str_cons_0x003c_0x00=in11_input +hwmon_in.int_extra1_0x003c_0x00=0 +hwmon_in.int_extra2_0x003c_0x00=0 + +hwmon_in.mode_0x003c_0x01=str_constant +hwmon_in.str_cons_0x003c_0x01=UCD90160_03_CLK_VDD_3V3_V + +hwmon_in.mode_0x003c_0x02=str_constant +hwmon_in.str_cons_0x003c_0x02=UCD90160_03 + +hwmon_in.mode_0x003c_0x03=constant +hwmon_in.int_cons_0x003c_0x03=3630 + +hwmon_in.mode_0x003c_0x05=constant +hwmon_in.int_cons_0x003c_0x05=2970 + +monitor_flag_hwmon_in.mode_0x003c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x003c_0x00=1 + + +# vol sensor 61 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x003d_0x00=config +hwmon_in.src_0x003d_0x00=file +hwmon_in.int_cons_0x003d_0x00=0 +hwmon_in.frmt_0x003d_0x00=buf +hwmon_in.fpath_0x003d_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x003d_0x00=0 +hwmon_in.len_0x003d_0x00=8 +hwmon_in.str_cons_0x003d_0x00=in12_input +hwmon_in.int_extra1_0x003d_0x00=0 +hwmon_in.int_extra2_0x003d_0x00=0 + +hwmon_in.mode_0x003d_0x01=str_constant +hwmon_in.str_cons_0x003d_0x01=UCD90160_03_CLK_VDD_1V8_V + +hwmon_in.mode_0x003d_0x02=str_constant +hwmon_in.str_cons_0x003d_0x02=UCD90160_03 + +hwmon_in.mode_0x003d_0x03=constant +hwmon_in.int_cons_0x003d_0x03=1980 + +hwmon_in.mode_0x003d_0x05=constant +hwmon_in.int_cons_0x003d_0x05=1620 + +monitor_flag_hwmon_in.mode_0x003d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x003d_0x00=1 + + +# vol sensor 62 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x003e_0x00=config +hwmon_in.src_0x003e_0x00=file +hwmon_in.int_cons_0x003e_0x00=0 +hwmon_in.frmt_0x003e_0x00=buf +hwmon_in.fpath_0x003e_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x003e_0x00=0 +hwmon_in.len_0x003e_0x00=8 +hwmon_in.str_cons_0x003e_0x00=in13_input +hwmon_in.int_extra1_0x003e_0x00=0 +hwmon_in.int_extra2_0x003e_0x00=0 + +hwmon_in.mode_0x003e_0x01=str_constant +hwmon_in.str_cons_0x003e_0x01=UCD90160_03_MAC_VDDO_1V2_V + +hwmon_in.mode_0x003e_0x02=str_constant +hwmon_in.str_cons_0x003e_0x02=UCD90160_03 + +hwmon_in.mode_0x003e_0x03=constant +hwmon_in.int_cons_0x003e_0x03=1320 + +hwmon_in.mode_0x003e_0x05=constant +hwmon_in.int_cons_0x003e_0x05=1080 + +monitor_flag_hwmon_in.mode_0x003e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x003e_0x00=1 + + +# vol sensor 63 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x003f_0x00=config +hwmon_in.src_0x003f_0x00=file +hwmon_in.int_cons_0x003f_0x00=0 +hwmon_in.frmt_0x003f_0x00=buf +hwmon_in.fpath_0x003f_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x003f_0x00=0 +hwmon_in.len_0x003f_0x00=8 +hwmon_in.str_cons_0x003f_0x00=in14_input +hwmon_in.int_extra1_0x003f_0x00=0 +hwmon_in.int_extra2_0x003f_0x00=0 + +hwmon_in.mode_0x003f_0x01=str_constant +hwmon_in.str_cons_0x003f_0x01=UCD90160_03_MAC_VDDO_1V8_V + +hwmon_in.mode_0x003f_0x02=str_constant +hwmon_in.str_cons_0x003f_0x02=UCD90160_03 + +hwmon_in.mode_0x003f_0x03=constant +hwmon_in.int_cons_0x003f_0x03=1980 + +hwmon_in.mode_0x003f_0x05=constant +hwmon_in.int_cons_0x003f_0x05=1620 + +monitor_flag_hwmon_in.mode_0x003f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x003f_0x00=1 + + +# vol sensor 64 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0040_0x00=config +hwmon_in.src_0x0040_0x00=file +hwmon_in.int_cons_0x0040_0x00=0 +hwmon_in.frmt_0x0040_0x00=buf +hwmon_in.fpath_0x0040_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0040_0x00=0 +hwmon_in.len_0x0040_0x00=8 +hwmon_in.str_cons_0x0040_0x00=in15_input +hwmon_in.int_extra1_0x0040_0x00=0 +hwmon_in.int_extra2_0x0040_0x00=0 + +hwmon_in.mode_0x0040_0x01=str_constant +hwmon_in.str_cons_0x0040_0x01=UCD90160_03_MAC_VDDC_0V8_V + +hwmon_in.mode_0x0040_0x02=str_constant +hwmon_in.str_cons_0x0040_0x02=UCD90160_03 + +hwmon_in.mode_0x0040_0x03=constant +hwmon_in.int_cons_0x0040_0x03=900 + +hwmon_in.mode_0x0040_0x05=constant +hwmon_in.int_cons_0x0040_0x05=600 + +monitor_flag_hwmon_in.mode_0x0040_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0040_0x00=1 + + +# vol sensor 65 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0041_0x00=config +hwmon_in.src_0x0041_0x00=file +hwmon_in.int_cons_0x0041_0x00=0 +hwmon_in.frmt_0x0041_0x00=buf +hwmon_in.fpath_0x0041_0x00=/sys/bus/i2c/devices/128-005b/hwmon/ +hwmon_in.addr_0x0041_0x00=0 +hwmon_in.len_0x0041_0x00=8 +hwmon_in.str_cons_0x0041_0x00=in16_input +hwmon_in.int_extra1_0x0041_0x00=0 +hwmon_in.int_extra2_0x0041_0x00=0 + +hwmon_in.mode_0x0041_0x01=str_constant +hwmon_in.str_cons_0x0041_0x01=UCD90160_03_MAC_VDDHTX_1V2_V + +hwmon_in.mode_0x0041_0x02=str_constant +hwmon_in.str_cons_0x0041_0x02=UCD90160_03 + +hwmon_in.mode_0x0041_0x03=constant +hwmon_in.int_cons_0x0041_0x03=1320 + +hwmon_in.mode_0x0041_0x05=constant +hwmon_in.int_cons_0x0041_0x05=1080 + +monitor_flag_hwmon_in.mode_0x0041_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0041_0x00=1 + + +# vol sensor 66 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0042_0x00=config +hwmon_in.src_0x0042_0x00=file +hwmon_in.int_cons_0x0042_0x00=0 +hwmon_in.frmt_0x0042_0x00=buf +hwmon_in.fpath_0x0042_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0042_0x00=0 +hwmon_in.len_0x0042_0x00=8 +hwmon_in.str_cons_0x0042_0x00=in1_input +hwmon_in.int_extra1_0x0042_0x00=0 +hwmon_in.int_extra2_0x0042_0x00=0 + +hwmon_in.mode_0x0042_0x01=str_constant +hwmon_in.str_cons_0x0042_0x01=UCD90160_04_MAC_PT0_VDDC_0V8_V + +hwmon_in.mode_0x0042_0x02=str_constant +hwmon_in.str_cons_0x0042_0x02=UCD90160_04 + +hwmon_in.mode_0x0042_0x03=constant +hwmon_in.int_cons_0x0042_0x03=900 + +hwmon_in.mode_0x0042_0x05=constant +hwmon_in.int_cons_0x0042_0x05=600 + +monitor_flag_hwmon_in.mode_0x0042_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0042_0x00=1 + + +# vol sensor 67 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0043_0x00=config +hwmon_in.src_0x0043_0x00=file +hwmon_in.int_cons_0x0043_0x00=0 +hwmon_in.frmt_0x0043_0x00=buf +hwmon_in.fpath_0x0043_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0043_0x00=0 +hwmon_in.len_0x0043_0x00=8 +hwmon_in.str_cons_0x0043_0x00=in2_input +hwmon_in.int_extra1_0x0043_0x00=0 +hwmon_in.int_extra2_0x0043_0x00=0 + +hwmon_in.mode_0x0043_0x01=str_constant +hwmon_in.str_cons_0x0043_0x01=UCD90160_04_MAC_PT1_VDDC_0V8_V + +hwmon_in.mode_0x0043_0x02=str_constant +hwmon_in.str_cons_0x0043_0x02=UCD90160_04 + +hwmon_in.mode_0x0043_0x03=constant +hwmon_in.int_cons_0x0043_0x03=900 + +hwmon_in.mode_0x0043_0x05=constant +hwmon_in.int_cons_0x0043_0x05=600 + +monitor_flag_hwmon_in.mode_0x0043_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0043_0x00=1 + + +# vol sensor 68 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0044_0x00=config +hwmon_in.src_0x0044_0x00=file +hwmon_in.int_cons_0x0044_0x00=0 +hwmon_in.frmt_0x0044_0x00=buf +hwmon_in.fpath_0x0044_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0044_0x00=0 +hwmon_in.len_0x0044_0x00=8 +hwmon_in.str_cons_0x0044_0x00=in3_input +hwmon_in.int_extra1_0x0044_0x00=0 +hwmon_in.int_extra2_0x0044_0x00=0 + +hwmon_in.mode_0x0044_0x01=str_constant +hwmon_in.str_cons_0x0044_0x01=UCD90160_04_MAC_PT2_VDDC_0V8_V + +hwmon_in.mode_0x0044_0x02=str_constant +hwmon_in.str_cons_0x0044_0x02=UCD90160_04 + +hwmon_in.mode_0x0044_0x03=constant +hwmon_in.int_cons_0x0044_0x03=900 + +hwmon_in.mode_0x0044_0x05=constant +hwmon_in.int_cons_0x0044_0x05=600 + +monitor_flag_hwmon_in.mode_0x0044_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0044_0x00=1 + + +# vol sensor 69 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0045_0x00=config +hwmon_in.src_0x0045_0x00=file +hwmon_in.int_cons_0x0045_0x00=0 +hwmon_in.frmt_0x0045_0x00=buf +hwmon_in.fpath_0x0045_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0045_0x00=0 +hwmon_in.len_0x0045_0x00=8 +hwmon_in.str_cons_0x0045_0x00=in4_input +hwmon_in.int_extra1_0x0045_0x00=0 +hwmon_in.int_extra2_0x0045_0x00=0 + +hwmon_in.mode_0x0045_0x01=str_constant +hwmon_in.str_cons_0x0045_0x01=UCD90160_04_MAC_PT3_VDDC_0V8_V + +hwmon_in.mode_0x0045_0x02=str_constant +hwmon_in.str_cons_0x0045_0x02=UCD90160_04 + +hwmon_in.mode_0x0045_0x03=constant +hwmon_in.int_cons_0x0045_0x03=900 + +hwmon_in.mode_0x0045_0x05=constant +hwmon_in.int_cons_0x0045_0x05=600 + +monitor_flag_hwmon_in.mode_0x0045_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0045_0x00=1 + + +# vol sensor 70 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0046_0x00=config +hwmon_in.src_0x0046_0x00=file +hwmon_in.int_cons_0x0046_0x00=0 +hwmon_in.frmt_0x0046_0x00=buf +hwmon_in.fpath_0x0046_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0046_0x00=0 +hwmon_in.len_0x0046_0x00=8 +hwmon_in.str_cons_0x0046_0x00=in5_input +hwmon_in.int_extra1_0x0046_0x00=0 +hwmon_in.int_extra2_0x0046_0x00=0 + +hwmon_in.mode_0x0046_0x01=str_constant +hwmon_in.str_cons_0x0046_0x01=UCD90160_04_MAC_PT4_VDDC_0V8_V + +hwmon_in.mode_0x0046_0x02=str_constant +hwmon_in.str_cons_0x0046_0x02=UCD90160_04 + +hwmon_in.mode_0x0046_0x03=constant +hwmon_in.int_cons_0x0046_0x03=900 + +hwmon_in.mode_0x0046_0x05=constant +hwmon_in.int_cons_0x0046_0x05=600 + +monitor_flag_hwmon_in.mode_0x0046_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0046_0x00=1 + + +# vol sensor 71 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0047_0x00=config +hwmon_in.src_0x0047_0x00=file +hwmon_in.int_cons_0x0047_0x00=0 +hwmon_in.frmt_0x0047_0x00=buf +hwmon_in.fpath_0x0047_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0047_0x00=0 +hwmon_in.len_0x0047_0x00=8 +hwmon_in.str_cons_0x0047_0x00=in6_input +hwmon_in.int_extra1_0x0047_0x00=0 +hwmon_in.int_extra2_0x0047_0x00=0 + +hwmon_in.mode_0x0047_0x01=str_constant +hwmon_in.str_cons_0x0047_0x01=UCD90160_04_MAC_PT5_VDDC_0V8_V + +hwmon_in.mode_0x0047_0x02=str_constant +hwmon_in.str_cons_0x0047_0x02=UCD90160_04 + +hwmon_in.mode_0x0047_0x03=constant +hwmon_in.int_cons_0x0047_0x03=900 + +hwmon_in.mode_0x0047_0x05=constant +hwmon_in.int_cons_0x0047_0x05=600 + +monitor_flag_hwmon_in.mode_0x0047_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0047_0x00=1 + + +# vol sensor 72 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0048_0x00=config +hwmon_in.src_0x0048_0x00=file +hwmon_in.int_cons_0x0048_0x00=0 +hwmon_in.frmt_0x0048_0x00=buf +hwmon_in.fpath_0x0048_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0048_0x00=0 +hwmon_in.len_0x0048_0x00=8 +hwmon_in.str_cons_0x0048_0x00=in7_input +hwmon_in.int_extra1_0x0048_0x00=0 +hwmon_in.int_extra2_0x0048_0x00=0 + +hwmon_in.mode_0x0048_0x01=str_constant +hwmon_in.str_cons_0x0048_0x01=UCD90160_04_MAC_PT6_VDDC_0V8_V + +hwmon_in.mode_0x0048_0x02=str_constant +hwmon_in.str_cons_0x0048_0x02=UCD90160_04 + +hwmon_in.mode_0x0048_0x03=constant +hwmon_in.int_cons_0x0048_0x03=900 + +hwmon_in.mode_0x0048_0x05=constant +hwmon_in.int_cons_0x0048_0x05=600 + +monitor_flag_hwmon_in.mode_0x0048_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0048_0x00=1 + + +# vol sensor 73 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0049_0x00=config +hwmon_in.src_0x0049_0x00=file +hwmon_in.int_cons_0x0049_0x00=0 +hwmon_in.frmt_0x0049_0x00=buf +hwmon_in.fpath_0x0049_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0049_0x00=0 +hwmon_in.len_0x0049_0x00=8 +hwmon_in.str_cons_0x0049_0x00=in8_input +hwmon_in.int_extra1_0x0049_0x00=0 +hwmon_in.int_extra2_0x0049_0x00=0 + +hwmon_in.mode_0x0049_0x01=str_constant +hwmon_in.str_cons_0x0049_0x01=UCD90160_04_MAC_PT7_VDDC_0V8_V + +hwmon_in.mode_0x0049_0x02=str_constant +hwmon_in.str_cons_0x0049_0x02=UCD90160_04 + +hwmon_in.mode_0x0049_0x03=constant +hwmon_in.int_cons_0x0049_0x03=900 + +hwmon_in.mode_0x0049_0x05=constant +hwmon_in.int_cons_0x0049_0x05=600 + +monitor_flag_hwmon_in.mode_0x0049_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0049_0x00=1 + + +# vol sensor 74 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x004a_0x00=config +hwmon_in.src_0x004a_0x00=file +hwmon_in.int_cons_0x004a_0x00=0 +hwmon_in.frmt_0x004a_0x00=buf +hwmon_in.fpath_0x004a_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x004a_0x00=0 +hwmon_in.len_0x004a_0x00=8 +hwmon_in.str_cons_0x004a_0x00=in9_input +hwmon_in.int_extra1_0x004a_0x00=0 +hwmon_in.int_extra2_0x004a_0x00=0 + +hwmon_in.mode_0x004a_0x01=str_constant +hwmon_in.str_cons_0x004a_0x01=UCD90160_04_MAC_PB0_PB7_TRVDD_0V72_V + +hwmon_in.mode_0x004a_0x02=str_constant +hwmon_in.str_cons_0x004a_0x02=UCD90160_04 + +hwmon_in.mode_0x004a_0x03=constant +hwmon_in.int_cons_0x004a_0x03=880 + +hwmon_in.mode_0x004a_0x05=constant +hwmon_in.int_cons_0x004a_0x05=650 + +monitor_flag_hwmon_in.mode_0x004a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x004a_0x00=1 + + +# vol sensor 75 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x004b_0x00=config +hwmon_in.src_0x004b_0x00=file +hwmon_in.int_cons_0x004b_0x00=0 +hwmon_in.frmt_0x004b_0x00=buf +hwmon_in.fpath_0x004b_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x004b_0x00=0 +hwmon_in.len_0x004b_0x00=8 +hwmon_in.str_cons_0x004b_0x00=in10_input +hwmon_in.int_extra1_0x004b_0x00=0 +hwmon_in.int_extra2_0x004b_0x00=0 + +hwmon_in.mode_0x004b_0x01=str_constant +hwmon_in.str_cons_0x004b_0x01=UCD90160_04_MAC_PB1_PB2_TRVDD_0V72_V + +hwmon_in.mode_0x004b_0x02=str_constant +hwmon_in.str_cons_0x004b_0x02=UCD90160_04 + +hwmon_in.mode_0x004b_0x03=constant +hwmon_in.int_cons_0x004b_0x03=880 + +hwmon_in.mode_0x004b_0x05=constant +hwmon_in.int_cons_0x004b_0x05=650 + +monitor_flag_hwmon_in.mode_0x004b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x004b_0x00=1 + + +# vol sensor 76 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x004c_0x00=config +hwmon_in.src_0x004c_0x00=file +hwmon_in.int_cons_0x004c_0x00=0 +hwmon_in.frmt_0x004c_0x00=buf +hwmon_in.fpath_0x004c_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x004c_0x00=0 +hwmon_in.len_0x004c_0x00=8 +hwmon_in.str_cons_0x004c_0x00=in11_input +hwmon_in.int_extra1_0x004c_0x00=0 +hwmon_in.int_extra2_0x004c_0x00=0 + +hwmon_in.mode_0x004c_0x01=str_constant +hwmon_in.str_cons_0x004c_0x01=UCD90160_04_MAC_PB3_PB4_TRVDD_0V72_V + +hwmon_in.mode_0x004c_0x02=str_constant +hwmon_in.str_cons_0x004c_0x02=UCD90160_04 + +hwmon_in.mode_0x004c_0x03=constant +hwmon_in.int_cons_0x004c_0x03=880 + +hwmon_in.mode_0x004c_0x05=constant +hwmon_in.int_cons_0x004c_0x05=650 + +monitor_flag_hwmon_in.mode_0x004c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x004c_0x00=1 + + +# vol sensor 77 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x004d_0x00=config +hwmon_in.src_0x004d_0x00=file +hwmon_in.int_cons_0x004d_0x00=0 +hwmon_in.frmt_0x004d_0x00=buf +hwmon_in.fpath_0x004d_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x004d_0x00=0 +hwmon_in.len_0x004d_0x00=8 +hwmon_in.str_cons_0x004d_0x00=in12_input +hwmon_in.int_extra1_0x004d_0x00=0 +hwmon_in.int_extra2_0x004d_0x00=0 + +hwmon_in.mode_0x004d_0x01=str_constant +hwmon_in.str_cons_0x004d_0x01=UCD90160_04_MAC_PB5_PB6_TRVDD_0V72_V + +hwmon_in.mode_0x004d_0x02=str_constant +hwmon_in.str_cons_0x004d_0x02=UCD90160_04 + +hwmon_in.mode_0x004d_0x03=constant +hwmon_in.int_cons_0x004d_0x03=880 + +hwmon_in.mode_0x004d_0x05=constant +hwmon_in.int_cons_0x004d_0x05=650 + +monitor_flag_hwmon_in.mode_0x004d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x004d_0x00=1 + + +# vol sensor 78 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x004e_0x00=config +hwmon_in.src_0x004e_0x00=file +hwmon_in.int_cons_0x004e_0x00=0 +hwmon_in.frmt_0x004e_0x00=buf +hwmon_in.fpath_0x004e_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x004e_0x00=0 +hwmon_in.len_0x004e_0x00=8 +hwmon_in.str_cons_0x004e_0x00=in13_input +hwmon_in.int_extra1_0x004e_0x00=0 +hwmon_in.int_extra2_0x004e_0x00=0 + +hwmon_in.mode_0x004e_0x01=str_constant +hwmon_in.str_cons_0x004e_0x01=UCD90160_04_MAC_TRVDD0_0V75_V + +hwmon_in.mode_0x004e_0x02=str_constant +hwmon_in.str_cons_0x004e_0x02=UCD90160_04 + +hwmon_in.mode_0x004e_0x03=constant +hwmon_in.int_cons_0x004e_0x03=825 + +hwmon_in.mode_0x004e_0x05=constant +hwmon_in.int_cons_0x004e_0x05=675 + +monitor_flag_hwmon_in.mode_0x004e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x004e_0x00=1 + + +# vol sensor 79 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x004f_0x00=config +hwmon_in.src_0x004f_0x00=file +hwmon_in.int_cons_0x004f_0x00=0 +hwmon_in.frmt_0x004f_0x00=buf +hwmon_in.fpath_0x004f_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x004f_0x00=0 +hwmon_in.len_0x004f_0x00=8 +hwmon_in.str_cons_0x004f_0x00=in14_input +hwmon_in.int_extra1_0x004f_0x00=0 +hwmon_in.int_extra2_0x004f_0x00=0 + +hwmon_in.mode_0x004f_0x01=str_constant +hwmon_in.str_cons_0x004f_0x01=UCD90160_04_MAC_TRVDD1_0V75_V + +hwmon_in.mode_0x004f_0x02=str_constant +hwmon_in.str_cons_0x004f_0x02=UCD90160_04 + +hwmon_in.mode_0x004f_0x03=constant +hwmon_in.int_cons_0x004f_0x03=825 + +hwmon_in.mode_0x004f_0x05=constant +hwmon_in.int_cons_0x004f_0x05=675 + +monitor_flag_hwmon_in.mode_0x004f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x004f_0x00=1 + + +# vol sensor 80 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0050_0x00=config +hwmon_in.src_0x0050_0x00=file +hwmon_in.int_cons_0x0050_0x00=0 +hwmon_in.frmt_0x0050_0x00=buf +hwmon_in.fpath_0x0050_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0050_0x00=0 +hwmon_in.len_0x0050_0x00=8 +hwmon_in.str_cons_0x0050_0x00=in15_input +hwmon_in.int_extra1_0x0050_0x00=0 +hwmon_in.int_extra2_0x0050_0x00=0 + +hwmon_in.mode_0x0050_0x01=str_constant +hwmon_in.str_cons_0x0050_0x01=UCD90160_04_MAC_TRVDD0_0V9_V + +hwmon_in.mode_0x0050_0x02=str_constant +hwmon_in.str_cons_0x0050_0x02=UCD90160_04 + +hwmon_in.mode_0x0050_0x03=constant +hwmon_in.int_cons_0x0050_0x03=990 + +hwmon_in.mode_0x0050_0x05=constant +hwmon_in.int_cons_0x0050_0x05=810 + +monitor_flag_hwmon_in.mode_0x0050_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0050_0x00=1 + + +# vol sensor 81 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0051_0x00=config +hwmon_in.src_0x0051_0x00=file +hwmon_in.int_cons_0x0051_0x00=0 +hwmon_in.frmt_0x0051_0x00=buf +hwmon_in.fpath_0x0051_0x00=/sys/bus/i2c/devices/129-005b/hwmon/ +hwmon_in.addr_0x0051_0x00=0 +hwmon_in.len_0x0051_0x00=8 +hwmon_in.str_cons_0x0051_0x00=in16_input +hwmon_in.int_extra1_0x0051_0x00=0 +hwmon_in.int_extra2_0x0051_0x00=0 + +hwmon_in.mode_0x0051_0x01=str_constant +hwmon_in.str_cons_0x0051_0x01=UCD90160_04_MAC_TRVDD1_0V9_V + +hwmon_in.mode_0x0051_0x02=str_constant +hwmon_in.str_cons_0x0051_0x02=UCD90160_04 + +hwmon_in.mode_0x0051_0x03=constant +hwmon_in.int_cons_0x0051_0x03=990 + +hwmon_in.mode_0x0051_0x05=constant +hwmon_in.int_cons_0x0051_0x05=810 + +monitor_flag_hwmon_in.mode_0x0051_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0051_0x00=1 + + +# vol sensor 82 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0052_0x00=config +hwmon_in.src_0x0052_0x00=file +hwmon_in.int_cons_0x0052_0x00=0 +hwmon_in.frmt_0x0052_0x00=buf +hwmon_in.fpath_0x0052_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0052_0x00=0 +hwmon_in.len_0x0052_0x00=8 +hwmon_in.str_cons_0x0052_0x00=in1_input +hwmon_in.int_extra1_0x0052_0x00=0 +hwmon_in.int_extra2_0x0052_0x00=0 + +hwmon_in.mode_0x0052_0x01=str_constant +hwmon_in.str_cons_0x0052_0x01=UCD90160_05_MAC_TSC15_0_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0052_0x02=str_constant +hwmon_in.str_cons_0x0052_0x02=UCD90160_05 + +hwmon_in.mode_0x0052_0x03=constant +hwmon_in.int_cons_0x0052_0x03=990 + +hwmon_in.mode_0x0052_0x05=constant +hwmon_in.int_cons_0x0052_0x05=810 + +monitor_flag_hwmon_in.mode_0x0052_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0052_0x00=1 + + +# vol sensor 83 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0053_0x00=config +hwmon_in.src_0x0053_0x00=file +hwmon_in.int_cons_0x0053_0x00=0 +hwmon_in.frmt_0x0053_0x00=buf +hwmon_in.fpath_0x0053_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0053_0x00=0 +hwmon_in.len_0x0053_0x00=8 +hwmon_in.str_cons_0x0053_0x00=in2_input +hwmon_in.int_extra1_0x0053_0x00=0 +hwmon_in.int_extra2_0x0053_0x00=0 + +hwmon_in.mode_0x0053_0x01=str_constant +hwmon_in.str_cons_0x0053_0x01=UCD90160_05_MAC_TSC31_16_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0053_0x02=str_constant +hwmon_in.str_cons_0x0053_0x02=UCD90160_05 + +hwmon_in.mode_0x0053_0x03=constant +hwmon_in.int_cons_0x0053_0x03=990 + +hwmon_in.mode_0x0053_0x05=constant +hwmon_in.int_cons_0x0053_0x05=810 + +monitor_flag_hwmon_in.mode_0x0053_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0053_0x00=1 + + +# vol sensor 84 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0054_0x00=config +hwmon_in.src_0x0054_0x00=file +hwmon_in.int_cons_0x0054_0x00=0 +hwmon_in.frmt_0x0054_0x00=buf +hwmon_in.fpath_0x0054_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0054_0x00=0 +hwmon_in.len_0x0054_0x00=8 +hwmon_in.str_cons_0x0054_0x00=in3_input +hwmon_in.int_extra1_0x0054_0x00=0 +hwmon_in.int_extra2_0x0054_0x00=0 + +hwmon_in.mode_0x0054_0x01=str_constant +hwmon_in.str_cons_0x0054_0x01=UCD90160_05_MAC_TSC47_32_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0054_0x02=str_constant +hwmon_in.str_cons_0x0054_0x02=UCD90160_05 + +hwmon_in.mode_0x0054_0x03=constant +hwmon_in.int_cons_0x0054_0x03=990 + +hwmon_in.mode_0x0054_0x05=constant +hwmon_in.int_cons_0x0054_0x05=810 + +monitor_flag_hwmon_in.mode_0x0054_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0054_0x00=1 + + +# vol sensor 85 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0055_0x00=config +hwmon_in.src_0x0055_0x00=file +hwmon_in.int_cons_0x0055_0x00=0 +hwmon_in.frmt_0x0055_0x00=buf +hwmon_in.fpath_0x0055_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0055_0x00=0 +hwmon_in.len_0x0055_0x00=8 +hwmon_in.str_cons_0x0055_0x00=in4_input +hwmon_in.int_extra1_0x0055_0x00=0 +hwmon_in.int_extra2_0x0055_0x00=0 + +hwmon_in.mode_0x0055_0x01=str_constant +hwmon_in.str_cons_0x0055_0x01=UCD90160_05_MAC_TSC63_48_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0055_0x02=str_constant +hwmon_in.str_cons_0x0055_0x02=UCD90160_05 + +hwmon_in.mode_0x0055_0x03=constant +hwmon_in.int_cons_0x0055_0x03=990 + +hwmon_in.mode_0x0055_0x05=constant +hwmon_in.int_cons_0x0055_0x05=810 + +monitor_flag_hwmon_in.mode_0x0055_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0055_0x00=1 + + +# vol sensor 86 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0056_0x00=config +hwmon_in.src_0x0056_0x00=file +hwmon_in.int_cons_0x0056_0x00=0 +hwmon_in.frmt_0x0056_0x00=buf +hwmon_in.fpath_0x0056_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0056_0x00=0 +hwmon_in.len_0x0056_0x00=8 +hwmon_in.str_cons_0x0056_0x00=in5_input +hwmon_in.int_extra1_0x0056_0x00=0 +hwmon_in.int_extra2_0x0056_0x00=0 + +hwmon_in.mode_0x0056_0x01=str_constant +hwmon_in.str_cons_0x0056_0x01=UCD90160_05_MAC_TSC79_64_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0056_0x02=str_constant +hwmon_in.str_cons_0x0056_0x02=UCD90160_05 + +hwmon_in.mode_0x0056_0x03=constant +hwmon_in.int_cons_0x0056_0x03=990 + +hwmon_in.mode_0x0056_0x05=constant +hwmon_in.int_cons_0x0056_0x05=810 + +monitor_flag_hwmon_in.mode_0x0056_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0056_0x00=1 + + +# vol sensor 87 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0057_0x00=config +hwmon_in.src_0x0057_0x00=file +hwmon_in.int_cons_0x0057_0x00=0 +hwmon_in.frmt_0x0057_0x00=buf +hwmon_in.fpath_0x0057_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0057_0x00=0 +hwmon_in.len_0x0057_0x00=8 +hwmon_in.str_cons_0x0057_0x00=in6_input +hwmon_in.int_extra1_0x0057_0x00=0 +hwmon_in.int_extra2_0x0057_0x00=0 + +hwmon_in.mode_0x0057_0x01=str_constant +hwmon_in.str_cons_0x0057_0x01=UCD90160_05_MAC_TSC95_80_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0057_0x02=str_constant +hwmon_in.str_cons_0x0057_0x02=UCD90160_05 + +hwmon_in.mode_0x0057_0x03=constant +hwmon_in.int_cons_0x0057_0x03=990 + +hwmon_in.mode_0x0057_0x05=constant +hwmon_in.int_cons_0x0057_0x05=810 + +monitor_flag_hwmon_in.mode_0x0057_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0057_0x00=1 + + +# vol sensor 88 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0058_0x00=config +hwmon_in.src_0x0058_0x00=file +hwmon_in.int_cons_0x0058_0x00=0 +hwmon_in.frmt_0x0058_0x00=buf +hwmon_in.fpath_0x0058_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0058_0x00=0 +hwmon_in.len_0x0058_0x00=8 +hwmon_in.str_cons_0x0058_0x00=in7_input +hwmon_in.int_extra1_0x0058_0x00=0 +hwmon_in.int_extra2_0x0058_0x00=0 + +hwmon_in.mode_0x0058_0x01=str_constant +hwmon_in.str_cons_0x0058_0x01=UCD90160_05_MAC_TSC111_96_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0058_0x02=str_constant +hwmon_in.str_cons_0x0058_0x02=UCD90160_05 + +hwmon_in.mode_0x0058_0x03=constant +hwmon_in.int_cons_0x0058_0x03=990 + +hwmon_in.mode_0x0058_0x05=constant +hwmon_in.int_cons_0x0058_0x05=810 + +monitor_flag_hwmon_in.mode_0x0058_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0058_0x00=1 + + +# vol sensor 89 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0059_0x00=config +hwmon_in.src_0x0059_0x00=file +hwmon_in.int_cons_0x0059_0x00=0 +hwmon_in.frmt_0x0059_0x00=buf +hwmon_in.fpath_0x0059_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0059_0x00=0 +hwmon_in.len_0x0059_0x00=8 +hwmon_in.str_cons_0x0059_0x00=in8_input +hwmon_in.int_extra1_0x0059_0x00=0 +hwmon_in.int_extra2_0x0059_0x00=0 + +hwmon_in.mode_0x0059_0x01=str_constant +hwmon_in.str_cons_0x0059_0x01=UCD90160_05_MAC_TSC127_112_PLL0_PVDD_0V9_V + +hwmon_in.mode_0x0059_0x02=str_constant +hwmon_in.str_cons_0x0059_0x02=UCD90160_05 + +hwmon_in.mode_0x0059_0x03=constant +hwmon_in.int_cons_0x0059_0x03=990 + +hwmon_in.mode_0x0059_0x05=constant +hwmon_in.int_cons_0x0059_0x05=810 + +monitor_flag_hwmon_in.mode_0x0059_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0059_0x00=1 + + +# vol sensor 90 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x005a_0x00=config +hwmon_in.src_0x005a_0x00=file +hwmon_in.int_cons_0x005a_0x00=0 +hwmon_in.frmt_0x005a_0x00=buf +hwmon_in.fpath_0x005a_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x005a_0x00=0 +hwmon_in.len_0x005a_0x00=8 +hwmon_in.str_cons_0x005a_0x00=in9_input +hwmon_in.int_extra1_0x005a_0x00=0 +hwmon_in.int_extra2_0x005a_0x00=0 + +hwmon_in.mode_0x005a_0x01=str_constant +hwmon_in.str_cons_0x005a_0x01=UCD90160_05_MAC_TSC63_0_PLL0_PVDD_1V5_V + +hwmon_in.mode_0x005a_0x02=str_constant +hwmon_in.str_cons_0x005a_0x02=UCD90160_05 + +hwmon_in.mode_0x005a_0x03=constant +hwmon_in.int_cons_0x005a_0x03=1650 + +hwmon_in.mode_0x005a_0x05=constant +hwmon_in.int_cons_0x005a_0x05=1350 + +monitor_flag_hwmon_in.mode_0x005a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x005a_0x00=1 + + +# vol sensor 91 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x005b_0x00=config +hwmon_in.src_0x005b_0x00=file +hwmon_in.int_cons_0x005b_0x00=0 +hwmon_in.frmt_0x005b_0x00=buf +hwmon_in.fpath_0x005b_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x005b_0x00=0 +hwmon_in.len_0x005b_0x00=8 +hwmon_in.str_cons_0x005b_0x00=in10_input +hwmon_in.int_extra1_0x005b_0x00=0 +hwmon_in.int_extra2_0x005b_0x00=0 + +hwmon_in.mode_0x005b_0x01=str_constant +hwmon_in.str_cons_0x005b_0x01=UCD90160_05_MAC_TSC127_64_PLL0_PVDD_1V5_V + +hwmon_in.mode_0x005b_0x02=str_constant +hwmon_in.str_cons_0x005b_0x02=UCD90160_05 + +hwmon_in.mode_0x005b_0x03=constant +hwmon_in.int_cons_0x005b_0x03=1650 + +hwmon_in.mode_0x005b_0x05=constant +hwmon_in.int_cons_0x005b_0x05=1350 + +monitor_flag_hwmon_in.mode_0x005b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x005b_0x00=1 + + +# vol sensor 92 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x005c_0x00=config +hwmon_in.src_0x005c_0x00=file +hwmon_in.int_cons_0x005c_0x00=0 +hwmon_in.frmt_0x005c_0x00=buf +hwmon_in.fpath_0x005c_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x005c_0x00=0 +hwmon_in.len_0x005c_0x00=8 +hwmon_in.str_cons_0x005c_0x00=in11_input +hwmon_in.int_extra1_0x005c_0x00=0 +hwmon_in.int_extra2_0x005c_0x00=0 + +hwmon_in.mode_0x005c_0x01=str_constant +hwmon_in.str_cons_0x005c_0x01=UCD90160_05_MAC_AVDD_1V5_V + +hwmon_in.mode_0x005c_0x02=str_constant +hwmon_in.str_cons_0x005c_0x02=UCD90160_05 + +hwmon_in.mode_0x005c_0x03=constant +hwmon_in.int_cons_0x005c_0x03=1650 + +hwmon_in.mode_0x005c_0x05=constant +hwmon_in.int_cons_0x005c_0x05=1350 + +monitor_flag_hwmon_in.mode_0x005c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x005c_0x00=1 + + +# vol sensor 93 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x005d_0x00=config +hwmon_in.src_0x005d_0x00=file +hwmon_in.int_cons_0x005d_0x00=0 +hwmon_in.frmt_0x005d_0x00=buf +hwmon_in.fpath_0x005d_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x005d_0x00=0 +hwmon_in.len_0x005d_0x00=8 +hwmon_in.str_cons_0x005d_0x00=in12_input +hwmon_in.int_extra1_0x005d_0x00=0 +hwmon_in.int_extra2_0x005d_0x00=0 + +hwmon_in.mode_0x005d_0x01=str_constant +hwmon_in.str_cons_0x005d_0x01=UCD90160_05_MAC_PB0_PB1_AVDD_1V45_V + +hwmon_in.mode_0x005d_0x02=str_constant +hwmon_in.str_cons_0x005d_0x02=UCD90160_05 + +hwmon_in.mode_0x005d_0x03=constant +hwmon_in.int_cons_0x005d_0x03=1650 + +hwmon_in.mode_0x005d_0x05=constant +hwmon_in.int_cons_0x005d_0x05=1300 + +monitor_flag_hwmon_in.mode_0x005d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x005d_0x00=1 + + +# vol sensor 94 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x005e_0x00=config +hwmon_in.src_0x005e_0x00=file +hwmon_in.int_cons_0x005e_0x00=0 +hwmon_in.frmt_0x005e_0x00=buf +hwmon_in.fpath_0x005e_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x005e_0x00=0 +hwmon_in.len_0x005e_0x00=8 +hwmon_in.str_cons_0x005e_0x00=in13_input +hwmon_in.int_extra1_0x005e_0x00=0 +hwmon_in.int_extra2_0x005e_0x00=0 + +hwmon_in.mode_0x005e_0x01=str_constant +hwmon_in.str_cons_0x005e_0x01=UCD90160_05_MAC_PB2_PB3_AVDD_1V45_V + +hwmon_in.mode_0x005e_0x02=str_constant +hwmon_in.str_cons_0x005e_0x02=UCD90160_05 + +hwmon_in.mode_0x005e_0x03=constant +hwmon_in.int_cons_0x005e_0x03=1650 + +hwmon_in.mode_0x005e_0x05=constant +hwmon_in.int_cons_0x005e_0x05=1300 + +monitor_flag_hwmon_in.mode_0x005e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x005e_0x00=1 + + +# vol sensor 95 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x005f_0x00=config +hwmon_in.src_0x005f_0x00=file +hwmon_in.int_cons_0x005f_0x00=0 +hwmon_in.frmt_0x005f_0x00=buf +hwmon_in.fpath_0x005f_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x005f_0x00=0 +hwmon_in.len_0x005f_0x00=8 +hwmon_in.str_cons_0x005f_0x00=in14_input +hwmon_in.int_extra1_0x005f_0x00=0 +hwmon_in.int_extra2_0x005f_0x00=0 + +hwmon_in.mode_0x005f_0x01=str_constant +hwmon_in.str_cons_0x005f_0x01=UCD90160_05_MAC_PB4_PB5_AVDD_1V45_V + +hwmon_in.mode_0x005f_0x02=str_constant +hwmon_in.str_cons_0x005f_0x02=UCD90160_05 + +hwmon_in.mode_0x005f_0x03=constant +hwmon_in.int_cons_0x005f_0x03=1650 + +hwmon_in.mode_0x005f_0x05=constant +hwmon_in.int_cons_0x005f_0x05=1300 + +monitor_flag_hwmon_in.mode_0x005f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x005f_0x00=1 + + +# vol sensor 96 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0060_0x00=config +hwmon_in.src_0x0060_0x00=file +hwmon_in.int_cons_0x0060_0x00=0 +hwmon_in.frmt_0x0060_0x00=buf +hwmon_in.fpath_0x0060_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0060_0x00=0 +hwmon_in.len_0x0060_0x00=8 +hwmon_in.str_cons_0x0060_0x00=in15_input +hwmon_in.int_extra1_0x0060_0x00=0 +hwmon_in.int_extra2_0x0060_0x00=0 + +hwmon_in.mode_0x0060_0x01=str_constant +hwmon_in.str_cons_0x0060_0x01=UCD90160_05_MAC_PB6_PB7_AVDD_1V45_V + +hwmon_in.mode_0x0060_0x02=str_constant +hwmon_in.str_cons_0x0060_0x02=UCD90160_05 + +hwmon_in.mode_0x0060_0x03=constant +hwmon_in.int_cons_0x0060_0x03=1650 + +hwmon_in.mode_0x0060_0x05=constant +hwmon_in.int_cons_0x0060_0x05=1300 + +monitor_flag_hwmon_in.mode_0x0060_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0060_0x00=1 + + +# vol sensor 97 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0061_0x00=config +hwmon_in.src_0x0061_0x00=file +hwmon_in.int_cons_0x0061_0x00=0 +hwmon_in.frmt_0x0061_0x00=buf +hwmon_in.fpath_0x0061_0x00=/sys/bus/i2c/devices/130-005b/hwmon/ +hwmon_in.addr_0x0061_0x00=0 +hwmon_in.len_0x0061_0x00=8 +hwmon_in.str_cons_0x0061_0x00=in16_input +hwmon_in.int_extra1_0x0061_0x00=0 +hwmon_in.int_extra2_0x0061_0x00=0 + +hwmon_in.mode_0x0061_0x01=str_constant +hwmon_in.str_cons_0x0061_0x01=UCD90160_05_MAC_AVDD_0V8_V + +hwmon_in.mode_0x0061_0x02=str_constant +hwmon_in.str_cons_0x0061_0x02=UCD90160_05 + +hwmon_in.mode_0x0061_0x03=constant +hwmon_in.int_cons_0x0061_0x03=880 + +hwmon_in.mode_0x0061_0x05=constant +hwmon_in.int_cons_0x0061_0x05=720 + +monitor_flag_hwmon_in.mode_0x0061_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0061_0x00=1 + + +# vol sensor 98 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0062_0x00=config +hwmon_in.src_0x0062_0x00=file +hwmon_in.int_cons_0x0062_0x00=0 +hwmon_in.frmt_0x0062_0x00=buf +hwmon_in.fpath_0x0062_0x00=/sys/bus/i2c/devices/136-0060/hwmon/ +hwmon_in.addr_0x0062_0x00=0 +hwmon_in.len_0x0062_0x00=8 +hwmon_in.str_cons_0x0062_0x00=in3_input +hwmon_in.int_extra1_0x0062_0x00=0 +hwmon_in.int_extra2_0x0062_0x00=0 + +hwmon_in.mode_0x0062_0x01=str_constant +hwmon_in.str_cons_0x0062_0x01=XDPE1A2G5B_01_MAC_VDDC_0V8_V + +hwmon_in.mode_0x0062_0x02=str_constant +hwmon_in.str_cons_0x0062_0x02=XDPE1A2G5B_01 + +hwmon_in.mode_0x0062_0x03=constant +hwmon_in.int_cons_0x0062_0x03=900 + +hwmon_in.mode_0x0062_0x05=constant +hwmon_in.int_cons_0x0062_0x05=600 + +monitor_flag_hwmon_in.mode_0x0062_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0062_0x00=1 + + +# vol sensor 99 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0063_0x00=config +hwmon_in.src_0x0063_0x00=file +hwmon_in.int_cons_0x0063_0x00=0 +hwmon_in.frmt_0x0063_0x00=buf +hwmon_in.fpath_0x0063_0x00=/sys/bus/i2c/devices/107-0060/hwmon/ +hwmon_in.addr_0x0063_0x00=0 +hwmon_in.len_0x0063_0x00=8 +hwmon_in.str_cons_0x0063_0x00=in3_input +hwmon_in.int_extra1_0x0063_0x00=0 +hwmon_in.int_extra2_0x0063_0x00=0 + +hwmon_in.mode_0x0063_0x01=str_constant +hwmon_in.str_cons_0x0063_0x01=XDPE12284C_05_MAC_PT0_VDDC_0V8_V + +hwmon_in.mode_0x0063_0x02=str_constant +hwmon_in.str_cons_0x0063_0x02=XDPE12284C_05 + +hwmon_in.mode_0x0063_0x03=constant +hwmon_in.int_cons_0x0063_0x03=900 + +hwmon_in.mode_0x0063_0x05=constant +hwmon_in.int_cons_0x0063_0x05=600 + +monitor_flag_hwmon_in.mode_0x0063_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0063_0x00=1 + + +# vol sensor 100 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0064_0x00=config +hwmon_in.src_0x0064_0x00=file +hwmon_in.int_cons_0x0064_0x00=0 +hwmon_in.frmt_0x0064_0x00=buf +hwmon_in.fpath_0x0064_0x00=/sys/bus/i2c/devices/107-0060/hwmon/ +hwmon_in.addr_0x0064_0x00=0 +hwmon_in.len_0x0064_0x00=8 +hwmon_in.str_cons_0x0064_0x00=in4_input +hwmon_in.int_extra1_0x0064_0x00=0 +hwmon_in.int_extra2_0x0064_0x00=0 + +hwmon_in.mode_0x0064_0x01=str_constant +hwmon_in.str_cons_0x0064_0x01=XDPE12284C_05_MAC_PT1_VDDC_0V8_V + +hwmon_in.mode_0x0064_0x02=str_constant +hwmon_in.str_cons_0x0064_0x02=XDPE12284C_05 + +hwmon_in.mode_0x0064_0x03=constant +hwmon_in.int_cons_0x0064_0x03=900 + +hwmon_in.mode_0x0064_0x05=constant +hwmon_in.int_cons_0x0064_0x05=600 + +monitor_flag_hwmon_in.mode_0x0064_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0064_0x00=1 + + +# vol sensor 101 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0065_0x00=config +hwmon_in.src_0x0065_0x00=file +hwmon_in.int_cons_0x0065_0x00=0 +hwmon_in.frmt_0x0065_0x00=buf +hwmon_in.fpath_0x0065_0x00=/sys/bus/i2c/devices/108-0060/hwmon/ +hwmon_in.addr_0x0065_0x00=0 +hwmon_in.len_0x0065_0x00=8 +hwmon_in.str_cons_0x0065_0x00=in3_input +hwmon_in.int_extra1_0x0065_0x00=0 +hwmon_in.int_extra2_0x0065_0x00=0 + +hwmon_in.mode_0x0065_0x01=str_constant +hwmon_in.str_cons_0x0065_0x01=XDPE12284C_06_MAC_PT2_VDDC_0V8_V + +hwmon_in.mode_0x0065_0x02=str_constant +hwmon_in.str_cons_0x0065_0x02=XDPE12284C_06 + +hwmon_in.mode_0x0065_0x03=constant +hwmon_in.int_cons_0x0065_0x03=900 + +hwmon_in.mode_0x0065_0x05=constant +hwmon_in.int_cons_0x0065_0x05=600 + +monitor_flag_hwmon_in.mode_0x0065_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0065_0x00=1 + + +# vol sensor 102 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0066_0x00=config +hwmon_in.src_0x0066_0x00=file +hwmon_in.int_cons_0x0066_0x00=0 +hwmon_in.frmt_0x0066_0x00=buf +hwmon_in.fpath_0x0066_0x00=/sys/bus/i2c/devices/108-0060/hwmon/ +hwmon_in.addr_0x0066_0x00=0 +hwmon_in.len_0x0066_0x00=8 +hwmon_in.str_cons_0x0066_0x00=in4_input +hwmon_in.int_extra1_0x0066_0x00=0 +hwmon_in.int_extra2_0x0066_0x00=0 + +hwmon_in.mode_0x0066_0x01=str_constant +hwmon_in.str_cons_0x0066_0x01=XDPE12284C_06_MAC_PT3_VDDC_0V8_V + +hwmon_in.mode_0x0066_0x02=str_constant +hwmon_in.str_cons_0x0066_0x02=XDPE12284C_06 + +hwmon_in.mode_0x0066_0x03=constant +hwmon_in.int_cons_0x0066_0x03=900 + +hwmon_in.mode_0x0066_0x05=constant +hwmon_in.int_cons_0x0066_0x05=600 + +monitor_flag_hwmon_in.mode_0x0066_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0066_0x00=1 + + +# vol sensor 103 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0067_0x00=config +hwmon_in.src_0x0067_0x00=file +hwmon_in.int_cons_0x0067_0x00=0 +hwmon_in.frmt_0x0067_0x00=buf +hwmon_in.fpath_0x0067_0x00=/sys/bus/i2c/devices/109-0060/hwmon/ +hwmon_in.addr_0x0067_0x00=0 +hwmon_in.len_0x0067_0x00=8 +hwmon_in.str_cons_0x0067_0x00=in3_input +hwmon_in.int_extra1_0x0067_0x00=0 +hwmon_in.int_extra2_0x0067_0x00=0 + +hwmon_in.mode_0x0067_0x01=str_constant +hwmon_in.str_cons_0x0067_0x01=XDPE12284C_07_MAC_PT4_VDDC_0V8_V + +hwmon_in.mode_0x0067_0x02=str_constant +hwmon_in.str_cons_0x0067_0x02=XDPE12284C_07 + +hwmon_in.mode_0x0067_0x03=constant +hwmon_in.int_cons_0x0067_0x03=900 + +hwmon_in.mode_0x0067_0x05=constant +hwmon_in.int_cons_0x0067_0x05=600 + +monitor_flag_hwmon_in.mode_0x0067_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0067_0x00=1 + + +# vol sensor 104 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0068_0x00=config +hwmon_in.src_0x0068_0x00=file +hwmon_in.int_cons_0x0068_0x00=0 +hwmon_in.frmt_0x0068_0x00=buf +hwmon_in.fpath_0x0068_0x00=/sys/bus/i2c/devices/109-0060/hwmon/ +hwmon_in.addr_0x0068_0x00=0 +hwmon_in.len_0x0068_0x00=8 +hwmon_in.str_cons_0x0068_0x00=in4_input +hwmon_in.int_extra1_0x0068_0x00=0 +hwmon_in.int_extra2_0x0068_0x00=0 + +hwmon_in.mode_0x0068_0x01=str_constant +hwmon_in.str_cons_0x0068_0x01=XDPE12284C_07_MAC_PT5_VDDC_0V8_V + +hwmon_in.mode_0x0068_0x02=str_constant +hwmon_in.str_cons_0x0068_0x02=XDPE12284C_07 + +hwmon_in.mode_0x0068_0x03=constant +hwmon_in.int_cons_0x0068_0x03=900 + +hwmon_in.mode_0x0068_0x05=constant +hwmon_in.int_cons_0x0068_0x05=600 + +monitor_flag_hwmon_in.mode_0x0068_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0068_0x00=1 + + +# vol sensor 105 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0069_0x00=config +hwmon_in.src_0x0069_0x00=file +hwmon_in.int_cons_0x0069_0x00=0 +hwmon_in.frmt_0x0069_0x00=buf +hwmon_in.fpath_0x0069_0x00=/sys/bus/i2c/devices/110-0060/hwmon/ +hwmon_in.addr_0x0069_0x00=0 +hwmon_in.len_0x0069_0x00=8 +hwmon_in.str_cons_0x0069_0x00=in3_input +hwmon_in.int_extra1_0x0069_0x00=0 +hwmon_in.int_extra2_0x0069_0x00=0 + +hwmon_in.mode_0x0069_0x01=str_constant +hwmon_in.str_cons_0x0069_0x01=XDPE12284C_08_MAC_PT6_VDDC_0V8_V + +hwmon_in.mode_0x0069_0x02=str_constant +hwmon_in.str_cons_0x0069_0x02=XDPE12284C_08 + +hwmon_in.mode_0x0069_0x03=constant +hwmon_in.int_cons_0x0069_0x03=900 + +hwmon_in.mode_0x0069_0x05=constant +hwmon_in.int_cons_0x0069_0x05=600 + +monitor_flag_hwmon_in.mode_0x0069_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0069_0x00=1 + + +# vol sensor 106 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x006a_0x00=config +hwmon_in.src_0x006a_0x00=file +hwmon_in.int_cons_0x006a_0x00=0 +hwmon_in.frmt_0x006a_0x00=buf +hwmon_in.fpath_0x006a_0x00=/sys/bus/i2c/devices/110-0060/hwmon/ +hwmon_in.addr_0x006a_0x00=0 +hwmon_in.len_0x006a_0x00=8 +hwmon_in.str_cons_0x006a_0x00=in4_input +hwmon_in.int_extra1_0x006a_0x00=0 +hwmon_in.int_extra2_0x006a_0x00=0 + +hwmon_in.mode_0x006a_0x01=str_constant +hwmon_in.str_cons_0x006a_0x01=XDPE12284C_08_MAC_PT7_VDDC_0V8_V + +hwmon_in.mode_0x006a_0x02=str_constant +hwmon_in.str_cons_0x006a_0x02=XDPE12284C_08 + +hwmon_in.mode_0x006a_0x03=constant +hwmon_in.int_cons_0x006a_0x03=900 + +hwmon_in.mode_0x006a_0x05=constant +hwmon_in.int_cons_0x006a_0x05=600 + +monitor_flag_hwmon_in.mode_0x006a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x006a_0x00=1 + + +# vol sensor 107 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x006b_0x00=config +hwmon_in.src_0x006b_0x00=file +hwmon_in.int_cons_0x006b_0x00=0 +hwmon_in.frmt_0x006b_0x00=buf +hwmon_in.fpath_0x006b_0x00=/sys/bus/i2c/devices/111-0060/hwmon/ +hwmon_in.addr_0x006b_0x00=0 +hwmon_in.len_0x006b_0x00=8 +hwmon_in.str_cons_0x006b_0x00=in3_input +hwmon_in.int_extra1_0x006b_0x00=0 +hwmon_in.int_extra2_0x006b_0x00=0 + +hwmon_in.mode_0x006b_0x01=str_constant +hwmon_in.str_cons_0x006b_0x01=XDPE12284C_09_MAC_PB0_PB7_TRVDD_V + +hwmon_in.mode_0x006b_0x02=str_constant +hwmon_in.str_cons_0x006b_0x02=XDPE12284C_09 + +hwmon_in.mode_0x006b_0x03=constant +hwmon_in.int_cons_0x006b_0x03=880 + +hwmon_in.mode_0x006b_0x05=constant +hwmon_in.int_cons_0x006b_0x05=650 + +monitor_flag_hwmon_in.mode_0x006b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x006b_0x00=1 + + +# vol sensor 108 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x006c_0x00=config +hwmon_in.src_0x006c_0x00=file +hwmon_in.int_cons_0x006c_0x00=0 +hwmon_in.frmt_0x006c_0x00=buf +hwmon_in.fpath_0x006c_0x00=/sys/bus/i2c/devices/111-0060/hwmon/ +hwmon_in.addr_0x006c_0x00=0 +hwmon_in.len_0x006c_0x00=8 +hwmon_in.str_cons_0x006c_0x00=in4_input +hwmon_in.int_extra1_0x006c_0x00=0 +hwmon_in.int_extra2_0x006c_0x00=0 + +hwmon_in.mode_0x006c_0x01=str_constant +hwmon_in.str_cons_0x006c_0x01=XDPE12284C_09_MAC_PB1_PB2_TRVDD_V + +hwmon_in.mode_0x006c_0x02=str_constant +hwmon_in.str_cons_0x006c_0x02=XDPE12284C_09 + +hwmon_in.mode_0x006c_0x03=constant +hwmon_in.int_cons_0x006c_0x03=880 + +hwmon_in.mode_0x006c_0x05=constant +hwmon_in.int_cons_0x006c_0x05=650 + +monitor_flag_hwmon_in.mode_0x006c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x006c_0x00=1 + + +# vol sensor 109 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x006d_0x00=config +hwmon_in.src_0x006d_0x00=file +hwmon_in.int_cons_0x006d_0x00=0 +hwmon_in.frmt_0x006d_0x00=buf +hwmon_in.fpath_0x006d_0x00=/sys/bus/i2c/devices/112-0060/hwmon/ +hwmon_in.addr_0x006d_0x00=0 +hwmon_in.len_0x006d_0x00=8 +hwmon_in.str_cons_0x006d_0x00=in3_input +hwmon_in.int_extra1_0x006d_0x00=0 +hwmon_in.int_extra2_0x006d_0x00=0 + +hwmon_in.mode_0x006d_0x01=str_constant +hwmon_in.str_cons_0x006d_0x01=XDPE12284C_10_MAC_PB3_PB4_TRVDD_V + +hwmon_in.mode_0x006d_0x02=str_constant +hwmon_in.str_cons_0x006d_0x02=XDPE12284C_10 + +hwmon_in.mode_0x006d_0x03=constant +hwmon_in.int_cons_0x006d_0x03=880 + +hwmon_in.mode_0x006d_0x05=constant +hwmon_in.int_cons_0x006d_0x05=650 + +monitor_flag_hwmon_in.mode_0x006d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x006d_0x00=1 + + +# vol sensor 110 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x006e_0x00=config +hwmon_in.src_0x006e_0x00=file +hwmon_in.int_cons_0x006e_0x00=0 +hwmon_in.frmt_0x006e_0x00=buf +hwmon_in.fpath_0x006e_0x00=/sys/bus/i2c/devices/112-0060/hwmon/ +hwmon_in.addr_0x006e_0x00=0 +hwmon_in.len_0x006e_0x00=8 +hwmon_in.str_cons_0x006e_0x00=in4_input +hwmon_in.int_extra1_0x006e_0x00=0 +hwmon_in.int_extra2_0x006e_0x00=0 + +hwmon_in.mode_0x006e_0x01=str_constant +hwmon_in.str_cons_0x006e_0x01=XDPE12284C_10_MAC_PB5_PB6_TRVDD_V + +hwmon_in.mode_0x006e_0x02=str_constant +hwmon_in.str_cons_0x006e_0x02=XDPE12284C_10 + +hwmon_in.mode_0x006e_0x03=constant +hwmon_in.int_cons_0x006e_0x03=880 + +hwmon_in.mode_0x006e_0x05=constant +hwmon_in.int_cons_0x006e_0x05=650 + +monitor_flag_hwmon_in.mode_0x006e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x006e_0x00=1 + + +# vol sensor 111 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x006f_0x00=config +hwmon_in.src_0x006f_0x00=file +hwmon_in.int_cons_0x006f_0x00=0 +hwmon_in.frmt_0x006f_0x00=buf +hwmon_in.fpath_0x006f_0x00=/sys/bus/i2c/devices/113-0060/hwmon/ +hwmon_in.addr_0x006f_0x00=0 +hwmon_in.len_0x006f_0x00=8 +hwmon_in.str_cons_0x006f_0x00=in3_input +hwmon_in.int_extra1_0x006f_0x00=0 +hwmon_in.int_extra2_0x006f_0x00=0 + +hwmon_in.mode_0x006f_0x01=str_constant +hwmon_in.str_cons_0x006f_0x01=XDPE12284C_11_MAC_TRVDD0_0V9_V + +hwmon_in.mode_0x006f_0x02=str_constant +hwmon_in.str_cons_0x006f_0x02=XDPE12284C_11 + +hwmon_in.mode_0x006f_0x03=constant +hwmon_in.int_cons_0x006f_0x03=990 + +hwmon_in.mode_0x006f_0x05=constant +hwmon_in.int_cons_0x006f_0x05=810 + +monitor_flag_hwmon_in.mode_0x006f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x006f_0x00=1 + + +# vol sensor 112 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0070_0x00=config +hwmon_in.src_0x0070_0x00=file +hwmon_in.int_cons_0x0070_0x00=0 +hwmon_in.frmt_0x0070_0x00=buf +hwmon_in.fpath_0x0070_0x00=/sys/bus/i2c/devices/113-0060/hwmon/ +hwmon_in.addr_0x0070_0x00=0 +hwmon_in.len_0x0070_0x00=8 +hwmon_in.str_cons_0x0070_0x00=in4_input +hwmon_in.int_extra1_0x0070_0x00=0 +hwmon_in.int_extra2_0x0070_0x00=0 + +hwmon_in.mode_0x0070_0x01=str_constant +hwmon_in.str_cons_0x0070_0x01=XDPE12284C_11_MAC_TRVDD0_0V75_V + +hwmon_in.mode_0x0070_0x02=str_constant +hwmon_in.str_cons_0x0070_0x02=XDPE12284C_11 + +hwmon_in.mode_0x0070_0x03=constant +hwmon_in.int_cons_0x0070_0x03=825 + +hwmon_in.mode_0x0070_0x05=constant +hwmon_in.int_cons_0x0070_0x05=675 + +monitor_flag_hwmon_in.mode_0x0070_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0070_0x00=1 + + +# vol sensor 113 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0071_0x00=config +hwmon_in.src_0x0071_0x00=file +hwmon_in.int_cons_0x0071_0x00=0 +hwmon_in.frmt_0x0071_0x00=buf +hwmon_in.fpath_0x0071_0x00=/sys/bus/i2c/devices/114-0060/hwmon/ +hwmon_in.addr_0x0071_0x00=0 +hwmon_in.len_0x0071_0x00=8 +hwmon_in.str_cons_0x0071_0x00=in3_input +hwmon_in.int_extra1_0x0071_0x00=0 +hwmon_in.int_extra2_0x0071_0x00=0 + +hwmon_in.mode_0x0071_0x01=str_constant +hwmon_in.str_cons_0x0071_0x01=XDPE12284C_12_MAC_TRVDD1_0V9_V + +hwmon_in.mode_0x0071_0x02=str_constant +hwmon_in.str_cons_0x0071_0x02=XDPE12284C_12 + +hwmon_in.mode_0x0071_0x03=constant +hwmon_in.int_cons_0x0071_0x03=990 + +hwmon_in.mode_0x0071_0x05=constant +hwmon_in.int_cons_0x0071_0x05=810 + +monitor_flag_hwmon_in.mode_0x0071_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0071_0x00=1 + + +# vol sensor 114 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0072_0x00=config +hwmon_in.src_0x0072_0x00=file +hwmon_in.int_cons_0x0072_0x00=0 +hwmon_in.frmt_0x0072_0x00=buf +hwmon_in.fpath_0x0072_0x00=/sys/bus/i2c/devices/114-0060/hwmon/ +hwmon_in.addr_0x0072_0x00=0 +hwmon_in.len_0x0072_0x00=8 +hwmon_in.str_cons_0x0072_0x00=in4_input +hwmon_in.int_extra1_0x0072_0x00=0 +hwmon_in.int_extra2_0x0072_0x00=0 + +hwmon_in.mode_0x0072_0x01=str_constant +hwmon_in.str_cons_0x0072_0x01=XDPE12284C_12_MAC_TRVDD1_0V75_V + +hwmon_in.mode_0x0072_0x02=str_constant +hwmon_in.str_cons_0x0072_0x02=XDPE12284C_12 + +hwmon_in.mode_0x0072_0x03=constant +hwmon_in.int_cons_0x0072_0x03=825 + +hwmon_in.mode_0x0072_0x05=constant +hwmon_in.int_cons_0x0072_0x05=675 + +monitor_flag_hwmon_in.mode_0x0072_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0072_0x00=1 + + +# vol sensor 115 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0073_0x00=config +hwmon_in.src_0x0073_0x00=file +hwmon_in.int_cons_0x0073_0x00=3 +hwmon_in.frmt_0x0073_0x00=buf +hwmon_in.fpath_0x0073_0x00=/sys/bus/i2c/devices/115-0060/hwmon/ +hwmon_in.addr_0x0073_0x00=0 +hwmon_in.len_0x0073_0x00=8 +hwmon_in.str_cons_0x0073_0x00=in3_input +hwmon_in.int_extra1_0x0073_0x00=1500 +hwmon_in.int_extra2_0x0073_0x00=0 + +hwmon_in.mode_0x0073_0x01=str_constant +hwmon_in.str_cons_0x0073_0x01=XDPE12284C_13_OSFP_VDD3V3_A1_V + +hwmon_in.mode_0x0073_0x02=str_constant +hwmon_in.str_cons_0x0073_0x02=XDPE12284C_13 + +hwmon_in.mode_0x0073_0x03=constant +hwmon_in.int_cons_0x0073_0x03=3630 + +hwmon_in.mode_0x0073_0x05=constant +hwmon_in.int_cons_0x0073_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0073_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0073_0x00=1 + + +# vol sensor 116 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0074_0x00=config +hwmon_in.src_0x0074_0x00=file +hwmon_in.int_cons_0x0074_0x00=3 +hwmon_in.frmt_0x0074_0x00=buf +hwmon_in.fpath_0x0074_0x00=/sys/bus/i2c/devices/115-0060/hwmon/ +hwmon_in.addr_0x0074_0x00=0 +hwmon_in.len_0x0074_0x00=8 +hwmon_in.str_cons_0x0074_0x00=in4_input +hwmon_in.int_extra1_0x0074_0x00=1500 +hwmon_in.int_extra2_0x0074_0x00=0 + +hwmon_in.mode_0x0074_0x01=str_constant +hwmon_in.str_cons_0x0074_0x01=XDPE12284C_13_OSFP_VDD3V3_B1_V + +hwmon_in.mode_0x0074_0x02=str_constant +hwmon_in.str_cons_0x0074_0x02=XDPE12284C_13 + +hwmon_in.mode_0x0074_0x03=constant +hwmon_in.int_cons_0x0074_0x03=3630 + +hwmon_in.mode_0x0074_0x05=constant +hwmon_in.int_cons_0x0074_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0074_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0074_0x00=1 + + +# vol sensor 117 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0075_0x00=config +hwmon_in.src_0x0075_0x00=file +hwmon_in.int_cons_0x0075_0x00=3 +hwmon_in.frmt_0x0075_0x00=buf +hwmon_in.fpath_0x0075_0x00=/sys/bus/i2c/devices/116-0060/hwmon/ +hwmon_in.addr_0x0075_0x00=0 +hwmon_in.len_0x0075_0x00=8 +hwmon_in.str_cons_0x0075_0x00=in3_input +hwmon_in.int_extra1_0x0075_0x00=1500 +hwmon_in.int_extra2_0x0075_0x00=0 + +hwmon_in.mode_0x0075_0x01=str_constant +hwmon_in.str_cons_0x0075_0x01=XDPE12284C_14_OSFP_VDD3V3_A2_V + +hwmon_in.mode_0x0075_0x02=str_constant +hwmon_in.str_cons_0x0075_0x02=XDPE12284C_14 + +hwmon_in.mode_0x0075_0x03=constant +hwmon_in.int_cons_0x0075_0x03=3630 + +hwmon_in.mode_0x0075_0x05=constant +hwmon_in.int_cons_0x0075_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0075_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0075_0x00=1 + + +# vol sensor 118 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0076_0x00=config +hwmon_in.src_0x0076_0x00=file +hwmon_in.int_cons_0x0076_0x00=3 +hwmon_in.frmt_0x0076_0x00=buf +hwmon_in.fpath_0x0076_0x00=/sys/bus/i2c/devices/116-0060/hwmon/ +hwmon_in.addr_0x0076_0x00=0 +hwmon_in.len_0x0076_0x00=8 +hwmon_in.str_cons_0x0076_0x00=in4_input +hwmon_in.int_extra1_0x0076_0x00=1500 +hwmon_in.int_extra2_0x0076_0x00=0 + +hwmon_in.mode_0x0076_0x01=str_constant +hwmon_in.str_cons_0x0076_0x01=XDPE12284C_14_OSFP_VDD3V3_B2_V + +hwmon_in.mode_0x0076_0x02=str_constant +hwmon_in.str_cons_0x0076_0x02=XDPE12284C_14 + +hwmon_in.mode_0x0076_0x03=constant +hwmon_in.int_cons_0x0076_0x03=3630 + +hwmon_in.mode_0x0076_0x05=constant +hwmon_in.int_cons_0x0076_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0076_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0076_0x00=1 + + +# vol sensor 119 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0077_0x00=config +hwmon_in.src_0x0077_0x00=file +hwmon_in.int_cons_0x0077_0x00=3 +hwmon_in.frmt_0x0077_0x00=buf +hwmon_in.fpath_0x0077_0x00=/sys/bus/i2c/devices/117-0060/hwmon/ +hwmon_in.addr_0x0077_0x00=0 +hwmon_in.len_0x0077_0x00=8 +hwmon_in.str_cons_0x0077_0x00=in3_input +hwmon_in.int_extra1_0x0077_0x00=1500 +hwmon_in.int_extra2_0x0077_0x00=0 + +hwmon_in.mode_0x0077_0x01=str_constant +hwmon_in.str_cons_0x0077_0x01=XDPE12284C_15_OSFP_VDD3V3_A3_V + +hwmon_in.mode_0x0077_0x02=str_constant +hwmon_in.str_cons_0x0077_0x02=XDPE12284C_15 + +hwmon_in.mode_0x0077_0x03=constant +hwmon_in.int_cons_0x0077_0x03=3630 + +hwmon_in.mode_0x0077_0x05=constant +hwmon_in.int_cons_0x0077_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0077_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0077_0x00=1 + + +# vol sensor 120 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0078_0x00=config +hwmon_in.src_0x0078_0x00=file +hwmon_in.int_cons_0x0078_0x00=3 +hwmon_in.frmt_0x0078_0x00=buf +hwmon_in.fpath_0x0078_0x00=/sys/bus/i2c/devices/117-0060/hwmon/ +hwmon_in.addr_0x0078_0x00=0 +hwmon_in.len_0x0078_0x00=8 +hwmon_in.str_cons_0x0078_0x00=in4_input +hwmon_in.int_extra1_0x0078_0x00=1500 +hwmon_in.int_extra2_0x0078_0x00=0 + +hwmon_in.mode_0x0078_0x01=str_constant +hwmon_in.str_cons_0x0078_0x01=XDPE12284C_15_OSFP_VDD3V3_B3_V + +hwmon_in.mode_0x0078_0x02=str_constant +hwmon_in.str_cons_0x0078_0x02=XDPE12284C_15 + +hwmon_in.mode_0x0078_0x03=constant +hwmon_in.int_cons_0x0078_0x03=3630 + +hwmon_in.mode_0x0078_0x05=constant +hwmon_in.int_cons_0x0078_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0078_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0078_0x00=1 + + +# vol sensor 121 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0079_0x00=config +hwmon_in.src_0x0079_0x00=file +hwmon_in.int_cons_0x0079_0x00=3 +hwmon_in.frmt_0x0079_0x00=buf +hwmon_in.fpath_0x0079_0x00=/sys/bus/i2c/devices/118-0060/hwmon/ +hwmon_in.addr_0x0079_0x00=0 +hwmon_in.len_0x0079_0x00=8 +hwmon_in.str_cons_0x0079_0x00=in3_input +hwmon_in.int_extra1_0x0079_0x00=1500 +hwmon_in.int_extra2_0x0079_0x00=0 + +hwmon_in.mode_0x0079_0x01=str_constant +hwmon_in.str_cons_0x0079_0x01=XDPE12284C_16_OSFP_VDD3V3_A4_V + +hwmon_in.mode_0x0079_0x02=str_constant +hwmon_in.str_cons_0x0079_0x02=XDPE12284C_16 + +hwmon_in.mode_0x0079_0x03=constant +hwmon_in.int_cons_0x0079_0x03=3630 + +hwmon_in.mode_0x0079_0x05=constant +hwmon_in.int_cons_0x0079_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0079_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0079_0x00=1 + + +# vol sensor 122 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x007a_0x00=config +hwmon_in.src_0x007a_0x00=file +hwmon_in.int_cons_0x007a_0x00=3 +hwmon_in.frmt_0x007a_0x00=buf +hwmon_in.fpath_0x007a_0x00=/sys/bus/i2c/devices/118-0060/hwmon/ +hwmon_in.addr_0x007a_0x00=0 +hwmon_in.len_0x007a_0x00=8 +hwmon_in.str_cons_0x007a_0x00=in4_input +hwmon_in.int_extra1_0x007a_0x00=1500 +hwmon_in.int_extra2_0x007a_0x00=0 + +hwmon_in.mode_0x007a_0x01=str_constant +hwmon_in.str_cons_0x007a_0x01=XDPE12284C_16_OSFP_VDD3V3_B4_V + +hwmon_in.mode_0x007a_0x02=str_constant +hwmon_in.str_cons_0x007a_0x02=XDPE12284C_16 + +hwmon_in.mode_0x007a_0x03=constant +hwmon_in.int_cons_0x007a_0x03=3630 + +hwmon_in.mode_0x007a_0x05=constant +hwmon_in.int_cons_0x007a_0x05=2970 + +monitor_flag_hwmon_in.mode_0x007a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x007a_0x00=1 + + +# vol sensor 123 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x007b_0x00=config +hwmon_in.src_0x007b_0x00=file +hwmon_in.int_cons_0x007b_0x00=3 +hwmon_in.frmt_0x007b_0x00=buf +hwmon_in.fpath_0x007b_0x00=/sys/bus/i2c/devices/119-0060/hwmon/ +hwmon_in.addr_0x007b_0x00=0 +hwmon_in.len_0x007b_0x00=8 +hwmon_in.str_cons_0x007b_0x00=in3_input +hwmon_in.int_extra1_0x007b_0x00=1500 +hwmon_in.int_extra2_0x007b_0x00=0 + +hwmon_in.mode_0x007b_0x01=str_constant +hwmon_in.str_cons_0x007b_0x01=XDPE12284C_17_OSFP_VDD3V3_A5_V + +hwmon_in.mode_0x007b_0x02=str_constant +hwmon_in.str_cons_0x007b_0x02=XDPE12284C_17 + +hwmon_in.mode_0x007b_0x03=constant +hwmon_in.int_cons_0x007b_0x03=3630 + +hwmon_in.mode_0x007b_0x05=constant +hwmon_in.int_cons_0x007b_0x05=2970 + +monitor_flag_hwmon_in.mode_0x007b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x007b_0x00=1 + + +# vol sensor 124 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x007c_0x00=config +hwmon_in.src_0x007c_0x00=file +hwmon_in.int_cons_0x007c_0x00=3 +hwmon_in.frmt_0x007c_0x00=buf +hwmon_in.fpath_0x007c_0x00=/sys/bus/i2c/devices/119-0060/hwmon/ +hwmon_in.addr_0x007c_0x00=0 +hwmon_in.len_0x007c_0x00=8 +hwmon_in.str_cons_0x007c_0x00=in4_input +hwmon_in.int_extra1_0x007c_0x00=1500 +hwmon_in.int_extra2_0x007c_0x00=0 + +hwmon_in.mode_0x007c_0x01=str_constant +hwmon_in.str_cons_0x007c_0x01=XDPE12284C_17_OSFP_VDD3V3_B5_V + +hwmon_in.mode_0x007c_0x02=str_constant +hwmon_in.str_cons_0x007c_0x02=XDPE12284C_17 + +hwmon_in.mode_0x007c_0x03=constant +hwmon_in.int_cons_0x007c_0x03=3630 + +hwmon_in.mode_0x007c_0x05=constant +hwmon_in.int_cons_0x007c_0x05=2970 + +monitor_flag_hwmon_in.mode_0x007c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x007c_0x00=1 + + +# vol sensor 125 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x007d_0x00=config +hwmon_in.src_0x007d_0x00=file +hwmon_in.int_cons_0x007d_0x00=3 +hwmon_in.frmt_0x007d_0x00=buf +hwmon_in.fpath_0x007d_0x00=/sys/bus/i2c/devices/120-0060/hwmon/ +hwmon_in.addr_0x007d_0x00=0 +hwmon_in.len_0x007d_0x00=8 +hwmon_in.str_cons_0x007d_0x00=in3_input +hwmon_in.int_extra1_0x007d_0x00=1500 +hwmon_in.int_extra2_0x007d_0x00=0 + +hwmon_in.mode_0x007d_0x01=str_constant +hwmon_in.str_cons_0x007d_0x01=XDPE12284C_18_OSFP_VDD3V3_A6_V + +hwmon_in.mode_0x007d_0x02=str_constant +hwmon_in.str_cons_0x007d_0x02=XDPE12284C_18 + +hwmon_in.mode_0x007d_0x03=constant +hwmon_in.int_cons_0x007d_0x03=3630 + +hwmon_in.mode_0x007d_0x05=constant +hwmon_in.int_cons_0x007d_0x05=2970 + +monitor_flag_hwmon_in.mode_0x007d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x007d_0x00=1 + + +# vol sensor 126 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x007e_0x00=config +hwmon_in.src_0x007e_0x00=file +hwmon_in.int_cons_0x007e_0x00=3 +hwmon_in.frmt_0x007e_0x00=buf +hwmon_in.fpath_0x007e_0x00=/sys/bus/i2c/devices/120-0060/hwmon/ +hwmon_in.addr_0x007e_0x00=0 +hwmon_in.len_0x007e_0x00=8 +hwmon_in.str_cons_0x007e_0x00=in4_input +hwmon_in.int_extra1_0x007e_0x00=1500 +hwmon_in.int_extra2_0x007e_0x00=0 + +hwmon_in.mode_0x007e_0x01=str_constant +hwmon_in.str_cons_0x007e_0x01=XDPE12284C_18_OSFP_VDD3V3_B6_V + +hwmon_in.mode_0x007e_0x02=str_constant +hwmon_in.str_cons_0x007e_0x02=XDPE12284C_18 + +hwmon_in.mode_0x007e_0x03=constant +hwmon_in.int_cons_0x007e_0x03=3630 + +hwmon_in.mode_0x007e_0x05=constant +hwmon_in.int_cons_0x007e_0x05=2970 + +monitor_flag_hwmon_in.mode_0x007e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x007e_0x00=1 + + +# vol sensor 127 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x007f_0x00=config +hwmon_in.src_0x007f_0x00=file +hwmon_in.int_cons_0x007f_0x00=3 +hwmon_in.frmt_0x007f_0x00=buf +hwmon_in.fpath_0x007f_0x00=/sys/bus/i2c/devices/121-0060/hwmon/ +hwmon_in.addr_0x007f_0x00=0 +hwmon_in.len_0x007f_0x00=8 +hwmon_in.str_cons_0x007f_0x00=in3_input +hwmon_in.int_extra1_0x007f_0x00=1500 +hwmon_in.int_extra2_0x007f_0x00=0 + +hwmon_in.mode_0x007f_0x01=str_constant +hwmon_in.str_cons_0x007f_0x01=XDPE12284C_19_OSFP_VDD3V3_A7_V + +hwmon_in.mode_0x007f_0x02=str_constant +hwmon_in.str_cons_0x007f_0x02=XDPE12284C_19 + +hwmon_in.mode_0x007f_0x03=constant +hwmon_in.int_cons_0x007f_0x03=3630 + +hwmon_in.mode_0x007f_0x05=constant +hwmon_in.int_cons_0x007f_0x05=2970 + +monitor_flag_hwmon_in.mode_0x007f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x007f_0x00=1 + + +# vol sensor 128 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0080_0x00=config +hwmon_in.src_0x0080_0x00=file +hwmon_in.int_cons_0x0080_0x00=3 +hwmon_in.frmt_0x0080_0x00=buf +hwmon_in.fpath_0x0080_0x00=/sys/bus/i2c/devices/121-0060/hwmon/ +hwmon_in.addr_0x0080_0x00=0 +hwmon_in.len_0x0080_0x00=8 +hwmon_in.str_cons_0x0080_0x00=in4_input +hwmon_in.int_extra1_0x0080_0x00=1500 +hwmon_in.int_extra2_0x0080_0x00=0 + +hwmon_in.mode_0x0080_0x01=str_constant +hwmon_in.str_cons_0x0080_0x01=XDPE12284C_19_OSFP_VDD3V3_B7_V + +hwmon_in.mode_0x0080_0x02=str_constant +hwmon_in.str_cons_0x0080_0x02=XDPE12284C_19 + +hwmon_in.mode_0x0080_0x03=constant +hwmon_in.int_cons_0x0080_0x03=3630 + +hwmon_in.mode_0x0080_0x05=constant +hwmon_in.int_cons_0x0080_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0080_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0080_0x00=1 + + +# vol sensor 129 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0081_0x00=config +hwmon_in.src_0x0081_0x00=file +hwmon_in.int_cons_0x0081_0x00=3 +hwmon_in.frmt_0x0081_0x00=buf +hwmon_in.fpath_0x0081_0x00=/sys/bus/i2c/devices/122-0060/hwmon/ +hwmon_in.addr_0x0081_0x00=0 +hwmon_in.len_0x0081_0x00=8 +hwmon_in.str_cons_0x0081_0x00=in3_input +hwmon_in.int_extra1_0x0081_0x00=1500 +hwmon_in.int_extra2_0x0081_0x00=0 + +hwmon_in.mode_0x0081_0x01=str_constant +hwmon_in.str_cons_0x0081_0x01=XDPE12284C_20_OSFP_VDD3V3_A8_V + +hwmon_in.mode_0x0081_0x02=str_constant +hwmon_in.str_cons_0x0081_0x02=XDPE12284C_20 + +hwmon_in.mode_0x0081_0x03=constant +hwmon_in.int_cons_0x0081_0x03=3630 + +hwmon_in.mode_0x0081_0x05=constant +hwmon_in.int_cons_0x0081_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0081_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0081_0x00=1 + + +# vol sensor 130 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0082_0x00=config +hwmon_in.src_0x0082_0x00=file +hwmon_in.int_cons_0x0082_0x00=3 +hwmon_in.frmt_0x0082_0x00=buf +hwmon_in.fpath_0x0082_0x00=/sys/bus/i2c/devices/122-0060/hwmon/ +hwmon_in.addr_0x0082_0x00=0 +hwmon_in.len_0x0082_0x00=8 +hwmon_in.str_cons_0x0082_0x00=in4_input +hwmon_in.int_extra1_0x0082_0x00=1500 +hwmon_in.int_extra2_0x0082_0x00=0 + +hwmon_in.mode_0x0082_0x01=str_constant +hwmon_in.str_cons_0x0082_0x01=XDPE12284C_20_OSFP_VDD3V3_B8_V + +hwmon_in.mode_0x0082_0x02=str_constant +hwmon_in.str_cons_0x0082_0x02=XDPE12284C_20 + +hwmon_in.mode_0x0082_0x03=constant +hwmon_in.int_cons_0x0082_0x03=3630 + +hwmon_in.mode_0x0082_0x05=constant +hwmon_in.int_cons_0x0082_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0082_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0082_0x00=1 + + +# vol sensor 131 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0083_0x00=config +hwmon_in.src_0x0083_0x00=logic_file +hwmon_in.int_cons_0x0083_0x00=0 +hwmon_in.frmt_0x0083_0x00=num_bytes +hwmon_in.fpath_0x0083_0x00=/dev/cpld4 +hwmon_in.addr_0x0083_0x00=0xe2 +hwmon_in.len_0x0083_0x00=2 +hwmon_in.int_extra1_0x0083_0x00=0 +hwmon_in.int_extra2_0x0083_0x00=2000 +hwmon_in.int_extra3_0x0083_0x00=1 + +hwmon_in.mode_0x0083_0x01=str_constant +hwmon_in.str_cons_0x0083_0x01=CPLD_01_VDD_STB_3V3_V + +hwmon_in.mode_0x0083_0x02=str_constant +hwmon_in.str_cons_0x0083_0x02=CPLD_01 + +hwmon_in.mode_0x0083_0x03=constant +hwmon_in.int_cons_0x0083_0x03=3630 + +hwmon_in.mode_0x0083_0x05=constant +hwmon_in.int_cons_0x0083_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0083_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0083_0x00=1 + + +# vol sensor 132 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0084_0x00=config +hwmon_in.src_0x0084_0x00=logic_file +hwmon_in.int_cons_0x0084_0x00=0 +hwmon_in.frmt_0x0084_0x00=num_bytes +hwmon_in.fpath_0x0084_0x00=/dev/cpld4 +hwmon_in.addr_0x0084_0x00=0xe4 +hwmon_in.len_0x0084_0x00=2 +hwmon_in.int_extra1_0x0084_0x00=0 +hwmon_in.int_extra2_0x0084_0x00=1000 +hwmon_in.int_extra3_0x0084_0x00=1 + +hwmon_in.mode_0x0084_0x01=str_constant +hwmon_in.str_cons_0x0084_0x01=CPLD_01_PB_VDD_V + +hwmon_in.mode_0x0084_0x02=str_constant +hwmon_in.str_cons_0x0084_0x02=CPLD_01 + +hwmon_in.mode_0x0084_0x03=constant +hwmon_in.int_cons_0x0084_0x03=2290 + +hwmon_in.mode_0x0084_0x05=constant +hwmon_in.int_cons_0x0084_0x05=1860 + +monitor_flag_hwmon_in.mode_0x0084_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0084_0x00=1 + + +# vol sensor 133 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0085_0x00=config +hwmon_in.src_0x0085_0x00=logic_file +hwmon_in.int_cons_0x0085_0x00=0 +hwmon_in.frmt_0x0085_0x00=num_bytes +hwmon_in.fpath_0x0085_0x00=/dev/cpld4 +hwmon_in.addr_0x0085_0x00=0xc4 +hwmon_in.len_0x0085_0x00=2 +hwmon_in.int_extra1_0x0085_0x00=0 +hwmon_in.int_extra2_0x0085_0x00=2000 +hwmon_in.int_extra3_0x0085_0x00=1 + +hwmon_in.mode_0x0085_0x01=str_constant +hwmon_in.str_cons_0x0085_0x01=CPLD_01_CLK_VDD_3V8V + +hwmon_in.mode_0x0085_0x02=str_constant +hwmon_in.str_cons_0x0085_0x02=CPLD_01 + +hwmon_in.mode_0x0085_0x03=constant +hwmon_in.int_cons_0x0085_0x03=4180 + +hwmon_in.mode_0x0085_0x05=constant +hwmon_in.int_cons_0x0085_0x05=3420 + +monitor_flag_hwmon_in.mode_0x0085_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0085_0x00=1 + + +# vol sensor 134 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0086_0x00=config +hwmon_in.src_0x0086_0x00=logic_file +hwmon_in.int_cons_0x0086_0x00=0 +hwmon_in.frmt_0x0086_0x00=num_bytes +hwmon_in.fpath_0x0086_0x00=/dev/cpld4 +hwmon_in.addr_0x0086_0x00=0xc6 +hwmon_in.len_0x0086_0x00=2 +hwmon_in.int_extra1_0x0086_0x00=0 +hwmon_in.int_extra2_0x0086_0x00=2000 +hwmon_in.int_extra3_0x0086_0x00=1 + +hwmon_in.mode_0x0086_0x01=str_constant +hwmon_in.str_cons_0x0086_0x01=CPLD_01_CLK_VDD_2V3_V + +hwmon_in.mode_0x0086_0x02=str_constant +hwmon_in.str_cons_0x0086_0x02=CPLD_01 + +hwmon_in.mode_0x0086_0x03=constant +hwmon_in.int_cons_0x0086_0x03=2530 + +hwmon_in.mode_0x0086_0x05=constant +hwmon_in.int_cons_0x0086_0x05=2070 + +monitor_flag_hwmon_in.mode_0x0086_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0086_0x00=1 + + +# vol sensor 135 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0087_0x00=config +hwmon_in.src_0x0087_0x00=logic_file +hwmon_in.int_cons_0x0087_0x00=0 +hwmon_in.frmt_0x0087_0x00=num_bytes +hwmon_in.fpath_0x0087_0x00=/dev/cpld4 +hwmon_in.addr_0x0087_0x00=0x60 +hwmon_in.len_0x0087_0x00=2 +hwmon_in.int_extra1_0x0087_0x00=0 +hwmon_in.int_extra2_0x0087_0x00=2000 +hwmon_in.int_extra3_0x0087_0x00=1 + +hwmon_in.mode_0x0087_0x01=str_constant +hwmon_in.str_cons_0x0087_0x01=CPLD_01_OSFP_VDD3V3_A1_V + +hwmon_in.mode_0x0087_0x02=str_constant +hwmon_in.str_cons_0x0087_0x02=CPLD_01 + +hwmon_in.mode_0x0087_0x03=constant +hwmon_in.int_cons_0x0087_0x03=3630 + +hwmon_in.mode_0x0087_0x05=constant +hwmon_in.int_cons_0x0087_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0087_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0087_0x00=1 + + +# vol sensor 136 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0088_0x00=config +hwmon_in.src_0x0088_0x00=logic_file +hwmon_in.int_cons_0x0088_0x00=0 +hwmon_in.frmt_0x0088_0x00=num_bytes +hwmon_in.fpath_0x0088_0x00=/dev/cpld4 +hwmon_in.addr_0x0088_0x00=0x62 +hwmon_in.len_0x0088_0x00=2 +hwmon_in.int_extra1_0x0088_0x00=0 +hwmon_in.int_extra2_0x0088_0x00=2000 +hwmon_in.int_extra3_0x0088_0x00=1 + +hwmon_in.mode_0x0088_0x01=str_constant +hwmon_in.str_cons_0x0088_0x01=CPLD_01_OSFP_VDD3V3_B1_V + +hwmon_in.mode_0x0088_0x02=str_constant +hwmon_in.str_cons_0x0088_0x02=CPLD_01 + +hwmon_in.mode_0x0088_0x03=constant +hwmon_in.int_cons_0x0088_0x03=3630 + +hwmon_in.mode_0x0088_0x05=constant +hwmon_in.int_cons_0x0088_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0088_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0088_0x00=1 + + +# vol sensor 137 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0089_0x00=config +hwmon_in.src_0x0089_0x00=logic_file +hwmon_in.int_cons_0x0089_0x00=0 +hwmon_in.frmt_0x0089_0x00=num_bytes +hwmon_in.fpath_0x0089_0x00=/dev/cpld4 +hwmon_in.addr_0x0089_0x00=0x64 +hwmon_in.len_0x0089_0x00=2 +hwmon_in.int_extra1_0x0089_0x00=0 +hwmon_in.int_extra2_0x0089_0x00=2000 +hwmon_in.int_extra3_0x0089_0x00=1 + +hwmon_in.mode_0x0089_0x01=str_constant +hwmon_in.str_cons_0x0089_0x01=CPLD_01_OSFP_VDD3V3_A2_V + +hwmon_in.mode_0x0089_0x02=str_constant +hwmon_in.str_cons_0x0089_0x02=CPLD_01 + +hwmon_in.mode_0x0089_0x03=constant +hwmon_in.int_cons_0x0089_0x03=3630 + +hwmon_in.mode_0x0089_0x05=constant +hwmon_in.int_cons_0x0089_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0089_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0089_0x00=1 + + +# vol sensor 138 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x008a_0x00=config +hwmon_in.src_0x008a_0x00=logic_file +hwmon_in.int_cons_0x008a_0x00=0 +hwmon_in.frmt_0x008a_0x00=num_bytes +hwmon_in.fpath_0x008a_0x00=/dev/cpld4 +hwmon_in.addr_0x008a_0x00=0x66 +hwmon_in.len_0x008a_0x00=2 +hwmon_in.int_extra1_0x008a_0x00=0 +hwmon_in.int_extra2_0x008a_0x00=2000 +hwmon_in.int_extra3_0x008a_0x00=1 + +hwmon_in.mode_0x008a_0x01=str_constant +hwmon_in.str_cons_0x008a_0x01=CPLD_01_OSFP_VDD3V3_B2_V + +hwmon_in.mode_0x008a_0x02=str_constant +hwmon_in.str_cons_0x008a_0x02=CPLD_01 + +hwmon_in.mode_0x008a_0x03=constant +hwmon_in.int_cons_0x008a_0x03=3630 + +hwmon_in.mode_0x008a_0x05=constant +hwmon_in.int_cons_0x008a_0x05=2970 + +monitor_flag_hwmon_in.mode_0x008a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x008a_0x00=1 + + +# vol sensor 139 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x008b_0x00=config +hwmon_in.src_0x008b_0x00=logic_file +hwmon_in.int_cons_0x008b_0x00=0 +hwmon_in.frmt_0x008b_0x00=num_bytes +hwmon_in.fpath_0x008b_0x00=/dev/cpld4 +hwmon_in.addr_0x008b_0x00=0x68 +hwmon_in.len_0x008b_0x00=2 +hwmon_in.int_extra1_0x008b_0x00=0 +hwmon_in.int_extra2_0x008b_0x00=2000 +hwmon_in.int_extra3_0x008b_0x00=1 + +hwmon_in.mode_0x008b_0x01=str_constant +hwmon_in.str_cons_0x008b_0x01=CPLD_01_OSFP_VDD3V3_A3_V + +hwmon_in.mode_0x008b_0x02=str_constant +hwmon_in.str_cons_0x008b_0x02=CPLD_01 + +hwmon_in.mode_0x008b_0x03=constant +hwmon_in.int_cons_0x008b_0x03=3630 + +hwmon_in.mode_0x008b_0x05=constant +hwmon_in.int_cons_0x008b_0x05=2970 + +monitor_flag_hwmon_in.mode_0x008b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x008b_0x00=1 + + +# vol sensor 140 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x008c_0x00=config +hwmon_in.src_0x008c_0x00=logic_file +hwmon_in.int_cons_0x008c_0x00=0 +hwmon_in.frmt_0x008c_0x00=num_bytes +hwmon_in.fpath_0x008c_0x00=/dev/cpld4 +hwmon_in.addr_0x008c_0x00=0x6a +hwmon_in.len_0x008c_0x00=2 +hwmon_in.int_extra1_0x008c_0x00=0 +hwmon_in.int_extra2_0x008c_0x00=2000 +hwmon_in.int_extra3_0x008c_0x00=1 + +hwmon_in.mode_0x008c_0x01=str_constant +hwmon_in.str_cons_0x008c_0x01=CPLD_01_OSFP_VDD3V3_B3_V + +hwmon_in.mode_0x008c_0x02=str_constant +hwmon_in.str_cons_0x008c_0x02=CPLD_01 + +hwmon_in.mode_0x008c_0x03=constant +hwmon_in.int_cons_0x008c_0x03=3630 + +hwmon_in.mode_0x008c_0x05=constant +hwmon_in.int_cons_0x008c_0x05=2970 + +monitor_flag_hwmon_in.mode_0x008c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x008c_0x00=1 + + +# vol sensor 141 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x008d_0x00=config +hwmon_in.src_0x008d_0x00=logic_file +hwmon_in.int_cons_0x008d_0x00=0 +hwmon_in.frmt_0x008d_0x00=num_bytes +hwmon_in.fpath_0x008d_0x00=/dev/cpld4 +hwmon_in.addr_0x008d_0x00=0x6c +hwmon_in.len_0x008d_0x00=2 +hwmon_in.int_extra1_0x008d_0x00=0 +hwmon_in.int_extra2_0x008d_0x00=2000 +hwmon_in.int_extra3_0x008d_0x00=1 + +hwmon_in.mode_0x008d_0x01=str_constant +hwmon_in.str_cons_0x008d_0x01=CPLD_01_OSFP_VDD3V3_A4_V + +hwmon_in.mode_0x008d_0x02=str_constant +hwmon_in.str_cons_0x008d_0x02=CPLD_01 + +hwmon_in.mode_0x008d_0x03=constant +hwmon_in.int_cons_0x008d_0x03=3630 + +hwmon_in.mode_0x008d_0x05=constant +hwmon_in.int_cons_0x008d_0x05=2970 + +monitor_flag_hwmon_in.mode_0x008d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x008d_0x00=1 + + +# vol sensor 142 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x008e_0x00=config +hwmon_in.src_0x008e_0x00=logic_file +hwmon_in.int_cons_0x008e_0x00=0 +hwmon_in.frmt_0x008e_0x00=num_bytes +hwmon_in.fpath_0x008e_0x00=/dev/cpld4 +hwmon_in.addr_0x008e_0x00=0x6e +hwmon_in.len_0x008e_0x00=2 +hwmon_in.int_extra1_0x008e_0x00=0 +hwmon_in.int_extra2_0x008e_0x00=2000 +hwmon_in.int_extra3_0x008e_0x00=1 + +hwmon_in.mode_0x008e_0x01=str_constant +hwmon_in.str_cons_0x008e_0x01=CPLD_01_OSFP_VDD3V3_B4_V + +hwmon_in.mode_0x008e_0x02=str_constant +hwmon_in.str_cons_0x008e_0x02=CPLD_01 + +hwmon_in.mode_0x008e_0x03=constant +hwmon_in.int_cons_0x008e_0x03=3630 + +hwmon_in.mode_0x008e_0x05=constant +hwmon_in.int_cons_0x008e_0x05=2970 + +monitor_flag_hwmon_in.mode_0x008e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x008e_0x00=1 + + +# vol sensor 143 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x008f_0x00=config +hwmon_in.src_0x008f_0x00=logic_file +hwmon_in.int_cons_0x008f_0x00=0 +hwmon_in.frmt_0x008f_0x00=num_bytes +hwmon_in.fpath_0x008f_0x00=/dev/cpld4 +hwmon_in.addr_0x008f_0x00=0x70 +hwmon_in.len_0x008f_0x00=2 +hwmon_in.int_extra1_0x008f_0x00=0 +hwmon_in.int_extra2_0x008f_0x00=2000 +hwmon_in.int_extra3_0x008f_0x00=1 + +hwmon_in.mode_0x008f_0x01=str_constant +hwmon_in.str_cons_0x008f_0x01=CPLD_01_OSFP_VDD3V3_A5_V + +hwmon_in.mode_0x008f_0x02=str_constant +hwmon_in.str_cons_0x008f_0x02=CPLD_01 + +hwmon_in.mode_0x008f_0x03=constant +hwmon_in.int_cons_0x008f_0x03=3630 + +hwmon_in.mode_0x008f_0x05=constant +hwmon_in.int_cons_0x008f_0x05=2970 + +monitor_flag_hwmon_in.mode_0x008f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x008f_0x00=1 + + +# vol sensor 144 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0090_0x00=config +hwmon_in.src_0x0090_0x00=logic_file +hwmon_in.int_cons_0x0090_0x00=0 +hwmon_in.frmt_0x0090_0x00=num_bytes +hwmon_in.fpath_0x0090_0x00=/dev/cpld4 +hwmon_in.addr_0x0090_0x00=0x72 +hwmon_in.len_0x0090_0x00=2 +hwmon_in.int_extra1_0x0090_0x00=0 +hwmon_in.int_extra2_0x0090_0x00=2000 +hwmon_in.int_extra3_0x0090_0x00=1 + +hwmon_in.mode_0x0090_0x01=str_constant +hwmon_in.str_cons_0x0090_0x01=CPLD_01_OSFP_VDD3V3_B5_V + +hwmon_in.mode_0x0090_0x02=str_constant +hwmon_in.str_cons_0x0090_0x02=CPLD_01 + +hwmon_in.mode_0x0090_0x03=constant +hwmon_in.int_cons_0x0090_0x03=3630 + +hwmon_in.mode_0x0090_0x05=constant +hwmon_in.int_cons_0x0090_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0090_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0090_0x00=1 + + +# vol sensor 145 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0091_0x00=config +hwmon_in.src_0x0091_0x00=logic_file +hwmon_in.int_cons_0x0091_0x00=0 +hwmon_in.frmt_0x0091_0x00=num_bytes +hwmon_in.fpath_0x0091_0x00=/dev/cpld4 +hwmon_in.addr_0x0091_0x00=0x74 +hwmon_in.len_0x0091_0x00=2 +hwmon_in.int_extra1_0x0091_0x00=0 +hwmon_in.int_extra2_0x0091_0x00=2000 +hwmon_in.int_extra3_0x0091_0x00=1 + +hwmon_in.mode_0x0091_0x01=str_constant +hwmon_in.str_cons_0x0091_0x01=CPLD_01_OSFP_VDD3V3_A6_V + +hwmon_in.mode_0x0091_0x02=str_constant +hwmon_in.str_cons_0x0091_0x02=CPLD_01 + +hwmon_in.mode_0x0091_0x03=constant +hwmon_in.int_cons_0x0091_0x03=3630 + +hwmon_in.mode_0x0091_0x05=constant +hwmon_in.int_cons_0x0091_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0091_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0091_0x00=1 + + +# vol sensor 146 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0092_0x00=config +hwmon_in.src_0x0092_0x00=logic_file +hwmon_in.int_cons_0x0092_0x00=0 +hwmon_in.frmt_0x0092_0x00=num_bytes +hwmon_in.fpath_0x0092_0x00=/dev/cpld4 +hwmon_in.addr_0x0092_0x00=0x76 +hwmon_in.len_0x0092_0x00=2 +hwmon_in.int_extra1_0x0092_0x00=0 +hwmon_in.int_extra2_0x0092_0x00=2000 +hwmon_in.int_extra3_0x0092_0x00=1 + +hwmon_in.mode_0x0092_0x01=str_constant +hwmon_in.str_cons_0x0092_0x01=CPLD_01_OSFP_VDD3V3_B6_V + +hwmon_in.mode_0x0092_0x02=str_constant +hwmon_in.str_cons_0x0092_0x02=CPLD_01 + +hwmon_in.mode_0x0092_0x03=constant +hwmon_in.int_cons_0x0092_0x03=3630 + +hwmon_in.mode_0x0092_0x05=constant +hwmon_in.int_cons_0x0092_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0092_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0092_0x00=1 + + +# vol sensor 147 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0093_0x00=config +hwmon_in.src_0x0093_0x00=logic_file +hwmon_in.int_cons_0x0093_0x00=0 +hwmon_in.frmt_0x0093_0x00=num_bytes +hwmon_in.fpath_0x0093_0x00=/dev/cpld4 +hwmon_in.addr_0x0093_0x00=0x78 +hwmon_in.len_0x0093_0x00=2 +hwmon_in.int_extra1_0x0093_0x00=0 +hwmon_in.int_extra2_0x0093_0x00=2000 +hwmon_in.int_extra3_0x0093_0x00=1 + +hwmon_in.mode_0x0093_0x01=str_constant +hwmon_in.str_cons_0x0093_0x01=CPLD_01_OSFP_VDD3V3_A7_V + +hwmon_in.mode_0x0093_0x02=str_constant +hwmon_in.str_cons_0x0093_0x02=CPLD_01 + +hwmon_in.mode_0x0093_0x03=constant +hwmon_in.int_cons_0x0093_0x03=3630 + +hwmon_in.mode_0x0093_0x05=constant +hwmon_in.int_cons_0x0093_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0093_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0093_0x00=1 + + +# vol sensor 148 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0094_0x00=config +hwmon_in.src_0x0094_0x00=logic_file +hwmon_in.int_cons_0x0094_0x00=0 +hwmon_in.frmt_0x0094_0x00=num_bytes +hwmon_in.fpath_0x0094_0x00=/dev/cpld4 +hwmon_in.addr_0x0094_0x00=0x7a +hwmon_in.len_0x0094_0x00=2 +hwmon_in.int_extra1_0x0094_0x00=0 +hwmon_in.int_extra2_0x0094_0x00=2000 +hwmon_in.int_extra3_0x0094_0x00=1 + +hwmon_in.mode_0x0094_0x01=str_constant +hwmon_in.str_cons_0x0094_0x01=CPLD_01_OSFP_VDD3V3_B7_V + +hwmon_in.mode_0x0094_0x02=str_constant +hwmon_in.str_cons_0x0094_0x02=CPLD_01 + +hwmon_in.mode_0x0094_0x03=constant +hwmon_in.int_cons_0x0094_0x03=3630 + +hwmon_in.mode_0x0094_0x05=constant +hwmon_in.int_cons_0x0094_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0094_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0094_0x00=1 + + +# vol sensor 149 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0095_0x00=config +hwmon_in.src_0x0095_0x00=logic_file +hwmon_in.int_cons_0x0095_0x00=0 +hwmon_in.frmt_0x0095_0x00=num_bytes +hwmon_in.fpath_0x0095_0x00=/dev/cpld4 +hwmon_in.addr_0x0095_0x00=0x7c +hwmon_in.len_0x0095_0x00=2 +hwmon_in.int_extra1_0x0095_0x00=0 +hwmon_in.int_extra2_0x0095_0x00=2000 +hwmon_in.int_extra3_0x0095_0x00=1 + +hwmon_in.mode_0x0095_0x01=str_constant +hwmon_in.str_cons_0x0095_0x01=CPLD_01_OSFP_VDD3V3_A8_V + +hwmon_in.mode_0x0095_0x02=str_constant +hwmon_in.str_cons_0x0095_0x02=CPLD_01 + +hwmon_in.mode_0x0095_0x03=constant +hwmon_in.int_cons_0x0095_0x03=3630 + +hwmon_in.mode_0x0095_0x05=constant +hwmon_in.int_cons_0x0095_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0095_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0095_0x00=1 + + +# vol sensor 150 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0096_0x00=config +hwmon_in.src_0x0096_0x00=logic_file +hwmon_in.int_cons_0x0096_0x00=0 +hwmon_in.frmt_0x0096_0x00=num_bytes +hwmon_in.fpath_0x0096_0x00=/dev/cpld4 +hwmon_in.addr_0x0096_0x00=0x7e +hwmon_in.len_0x0096_0x00=2 +hwmon_in.int_extra1_0x0096_0x00=0 +hwmon_in.int_extra2_0x0096_0x00=2000 +hwmon_in.int_extra3_0x0096_0x00=1 + +hwmon_in.mode_0x0096_0x01=str_constant +hwmon_in.str_cons_0x0096_0x01=CPLD_01_OSFP_VDD3V3_B8_V + +hwmon_in.mode_0x0096_0x02=str_constant +hwmon_in.str_cons_0x0096_0x02=CPLD_01 + +hwmon_in.mode_0x0096_0x03=constant +hwmon_in.int_cons_0x0096_0x03=3630 + +hwmon_in.mode_0x0096_0x05=constant +hwmon_in.int_cons_0x0096_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0096_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0096_0x00=1 + + +# vol sensor 151 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0097_0x00=config +hwmon_in.src_0x0097_0x00=file +hwmon_in.int_cons_0x0097_0x00=0 +hwmon_in.frmt_0x0097_0x00=buf +hwmon_in.fpath_0x0097_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x0097_0x00=0 +hwmon_in.len_0x0097_0x00=8 +hwmon_in.str_cons_0x0097_0x00=in15_input +hwmon_in.int_extra1_0x0097_0x00=0 +hwmon_in.int_extra2_0x0097_0x00=0 + +hwmon_in.mode_0x0097_0x01=str_constant +hwmon_in.str_cons_0x0097_0x01=UCD90160_06_VDD12V_UPORT_V + +hwmon_in.mode_0x0097_0x02=str_constant +hwmon_in.str_cons_0x0097_0x02=UCD90160_06 + +hwmon_in.mode_0x0097_0x03=constant +hwmon_in.int_cons_0x0097_0x03=13200 + +hwmon_in.mode_0x0097_0x05=constant +hwmon_in.int_cons_0x0097_0x05=10800 + +monitor_flag_hwmon_in.mode_0x0097_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0097_0x00=1 + + +# vol sensor 152 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0098_0x00=config +hwmon_in.src_0x0098_0x00=file +hwmon_in.int_cons_0x0098_0x00=0 +hwmon_in.frmt_0x0098_0x00=buf +hwmon_in.fpath_0x0098_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x0098_0x00=0 +hwmon_in.len_0x0098_0x00=8 +hwmon_in.str_cons_0x0098_0x00=in14_input +hwmon_in.int_extra1_0x0098_0x00=0 +hwmon_in.int_extra2_0x0098_0x00=0 + +hwmon_in.mode_0x0098_0x01=str_constant +hwmon_in.str_cons_0x0098_0x01=UCD90160_06_VDD3V3_STANDBY_V + +hwmon_in.mode_0x0098_0x02=str_constant +hwmon_in.str_cons_0x0098_0x02=UCD90160_06 + +hwmon_in.mode_0x0098_0x03=constant +hwmon_in.int_cons_0x0098_0x03=3630 + +hwmon_in.mode_0x0098_0x05=constant +hwmon_in.int_cons_0x0098_0x05=2970 + +monitor_flag_hwmon_in.mode_0x0098_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0098_0x00=1 + + +# vol sensor 153 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x0099_0x00=config +hwmon_in.src_0x0099_0x00=file +hwmon_in.int_cons_0x0099_0x00=0 +hwmon_in.frmt_0x0099_0x00=buf +hwmon_in.fpath_0x0099_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x0099_0x00=0 +hwmon_in.len_0x0099_0x00=8 +hwmon_in.str_cons_0x0099_0x00=in1_input +hwmon_in.int_extra1_0x0099_0x00=0 +hwmon_in.int_extra2_0x0099_0x00=0 + +hwmon_in.mode_0x0099_0x01=str_constant +hwmon_in.str_cons_0x0099_0x01=UCD90160_06_FPGA_VDD_1V0_V + +hwmon_in.mode_0x0099_0x02=str_constant +hwmon_in.str_cons_0x0099_0x02=UCD90160_06 + +hwmon_in.mode_0x0099_0x03=constant +hwmon_in.int_cons_0x0099_0x03=1100 + +hwmon_in.mode_0x0099_0x05=constant +hwmon_in.int_cons_0x0099_0x05=900 + +monitor_flag_hwmon_in.mode_0x0099_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0099_0x00=1 + + +# vol sensor 154 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x009a_0x00=config +hwmon_in.src_0x009a_0x00=file +hwmon_in.int_cons_0x009a_0x00=0 +hwmon_in.frmt_0x009a_0x00=buf +hwmon_in.fpath_0x009a_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x009a_0x00=0 +hwmon_in.len_0x009a_0x00=8 +hwmon_in.str_cons_0x009a_0x00=in2_input +hwmon_in.int_extra1_0x009a_0x00=0 +hwmon_in.int_extra2_0x009a_0x00=0 + +hwmon_in.mode_0x009a_0x01=str_constant +hwmon_in.str_cons_0x009a_0x01=UCD90160_06_FPGA_VDD_1V8_V + +hwmon_in.mode_0x009a_0x02=str_constant +hwmon_in.str_cons_0x009a_0x02=UCD90160_06 + +hwmon_in.mode_0x009a_0x03=constant +hwmon_in.int_cons_0x009a_0x03=1980 + +hwmon_in.mode_0x009a_0x05=constant +hwmon_in.int_cons_0x009a_0x05=1620 + +monitor_flag_hwmon_in.mode_0x009a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x009a_0x00=1 + + +# vol sensor 155 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x009b_0x00=config +hwmon_in.src_0x009b_0x00=file +hwmon_in.int_cons_0x009b_0x00=0 +hwmon_in.frmt_0x009b_0x00=buf +hwmon_in.fpath_0x009b_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x009b_0x00=0 +hwmon_in.len_0x009b_0x00=8 +hwmon_in.str_cons_0x009b_0x00=in3_input +hwmon_in.int_extra1_0x009b_0x00=0 +hwmon_in.int_extra2_0x009b_0x00=0 + +hwmon_in.mode_0x009b_0x01=str_constant +hwmon_in.str_cons_0x009b_0x01=UCD90160_06_FPGA_VDD_1V2_V + +hwmon_in.mode_0x009b_0x02=str_constant +hwmon_in.str_cons_0x009b_0x02=UCD90160_06 + +hwmon_in.mode_0x009b_0x03=constant +hwmon_in.int_cons_0x009b_0x03=1320 + +hwmon_in.mode_0x009b_0x05=constant +hwmon_in.int_cons_0x009b_0x05=1080 + +monitor_flag_hwmon_in.mode_0x009b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x009b_0x00=1 + + +# vol sensor 156 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x009c_0x00=config +hwmon_in.src_0x009c_0x00=file +hwmon_in.int_cons_0x009c_0x00=0 +hwmon_in.frmt_0x009c_0x00=buf +hwmon_in.fpath_0x009c_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x009c_0x00=0 +hwmon_in.len_0x009c_0x00=8 +hwmon_in.str_cons_0x009c_0x00=in4_input +hwmon_in.int_extra1_0x009c_0x00=0 +hwmon_in.int_extra2_0x009c_0x00=0 + +hwmon_in.mode_0x009c_0x01=str_constant +hwmon_in.str_cons_0x009c_0x01=UCD90160_06_VDD_3V3_V + +hwmon_in.mode_0x009c_0x02=str_constant +hwmon_in.str_cons_0x009c_0x02=UCD90160_06 + +hwmon_in.mode_0x009c_0x03=constant +hwmon_in.int_cons_0x009c_0x03=3630 + +hwmon_in.mode_0x009c_0x05=constant +hwmon_in.int_cons_0x009c_0x05=2970 + +monitor_flag_hwmon_in.mode_0x009c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x009c_0x00=1 + + +# vol sensor 157 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x009d_0x00=config +hwmon_in.src_0x009d_0x00=file +hwmon_in.int_cons_0x009d_0x00=0 +hwmon_in.frmt_0x009d_0x00=buf +hwmon_in.fpath_0x009d_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x009d_0x00=0 +hwmon_in.len_0x009d_0x00=8 +hwmon_in.str_cons_0x009d_0x00=in5_input +hwmon_in.int_extra1_0x009d_0x00=0 +hwmon_in.int_extra2_0x009d_0x00=0 + +hwmon_in.mode_0x009d_0x01=str_constant +hwmon_in.str_cons_0x009d_0x01=UCD90160_06_PWR_VDD_5V0_V + +hwmon_in.mode_0x009d_0x02=str_constant +hwmon_in.str_cons_0x009d_0x02=UCD90160_06 + +hwmon_in.mode_0x009d_0x03=constant +hwmon_in.int_cons_0x009d_0x03=5500 + +hwmon_in.mode_0x009d_0x05=constant +hwmon_in.int_cons_0x009d_0x05=4500 + +monitor_flag_hwmon_in.mode_0x009d_0x00=constant +monitor_flag_hwmon_in.int_cons_0x009d_0x00=1 + + +# vol sensor 158 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x009e_0x00=config +hwmon_in.src_0x009e_0x00=file +hwmon_in.int_cons_0x009e_0x00=0 +hwmon_in.frmt_0x009e_0x00=buf +hwmon_in.fpath_0x009e_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x009e_0x00=0 +hwmon_in.len_0x009e_0x00=8 +hwmon_in.str_cons_0x009e_0x00=in6_input +hwmon_in.int_extra1_0x009e_0x00=0 +hwmon_in.int_extra2_0x009e_0x00=0 + +hwmon_in.mode_0x009e_0x01=str_constant +hwmon_in.str_cons_0x009e_0x01=UCD90160_06_OSFP_VDD3V3_A1_V + +hwmon_in.mode_0x009e_0x02=str_constant +hwmon_in.str_cons_0x009e_0x02=UCD90160_06 + +hwmon_in.mode_0x009e_0x03=constant +hwmon_in.int_cons_0x009e_0x03=3630 + +hwmon_in.mode_0x009e_0x05=constant +hwmon_in.int_cons_0x009e_0x05=2970 + +monitor_flag_hwmon_in.mode_0x009e_0x00=constant +monitor_flag_hwmon_in.int_cons_0x009e_0x00=1 + + +# vol sensor 159 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x009f_0x00=config +hwmon_in.src_0x009f_0x00=file +hwmon_in.int_cons_0x009f_0x00=0 +hwmon_in.frmt_0x009f_0x00=buf +hwmon_in.fpath_0x009f_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x009f_0x00=0 +hwmon_in.len_0x009f_0x00=8 +hwmon_in.str_cons_0x009f_0x00=in7_input +hwmon_in.int_extra1_0x009f_0x00=0 +hwmon_in.int_extra2_0x009f_0x00=0 + +hwmon_in.mode_0x009f_0x01=str_constant +hwmon_in.str_cons_0x009f_0x01=UCD90160_06_OSFP_VDD3V3_B1_V + +hwmon_in.mode_0x009f_0x02=str_constant +hwmon_in.str_cons_0x009f_0x02=UCD90160_06 + +hwmon_in.mode_0x009f_0x03=constant +hwmon_in.int_cons_0x009f_0x03=3630 + +hwmon_in.mode_0x009f_0x05=constant +hwmon_in.int_cons_0x009f_0x05=2970 + +monitor_flag_hwmon_in.mode_0x009f_0x00=constant +monitor_flag_hwmon_in.int_cons_0x009f_0x00=1 + + +# vol sensor 160 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a0_0x00=config +hwmon_in.src_0x00a0_0x00=file +hwmon_in.int_cons_0x00a0_0x00=0 +hwmon_in.frmt_0x00a0_0x00=buf +hwmon_in.fpath_0x00a0_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x00a0_0x00=0 +hwmon_in.len_0x00a0_0x00=8 +hwmon_in.str_cons_0x00a0_0x00=in8_input +hwmon_in.int_extra1_0x00a0_0x00=0 +hwmon_in.int_extra2_0x00a0_0x00=0 + +hwmon_in.mode_0x00a0_0x01=str_constant +hwmon_in.str_cons_0x00a0_0x01=UCD90160_06_OSFP_VDD3V3_A2_V + +hwmon_in.mode_0x00a0_0x02=str_constant +hwmon_in.str_cons_0x00a0_0x02=UCD90160_06 + +hwmon_in.mode_0x00a0_0x03=constant +hwmon_in.int_cons_0x00a0_0x03=3630 + +hwmon_in.mode_0x00a0_0x05=constant +hwmon_in.int_cons_0x00a0_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a0_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a0_0x00=1 + + +# vol sensor 161 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a1_0x00=config +hwmon_in.src_0x00a1_0x00=file +hwmon_in.int_cons_0x00a1_0x00=0 +hwmon_in.frmt_0x00a1_0x00=buf +hwmon_in.fpath_0x00a1_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x00a1_0x00=0 +hwmon_in.len_0x00a1_0x00=8 +hwmon_in.str_cons_0x00a1_0x00=in9_input +hwmon_in.int_extra1_0x00a1_0x00=0 +hwmon_in.int_extra2_0x00a1_0x00=0 + +hwmon_in.mode_0x00a1_0x01=str_constant +hwmon_in.str_cons_0x00a1_0x01=UCD90160_06_OSFP_VDD3V3_B2_V + +hwmon_in.mode_0x00a1_0x02=str_constant +hwmon_in.str_cons_0x00a1_0x02=UCD90160_06 + +hwmon_in.mode_0x00a1_0x03=constant +hwmon_in.int_cons_0x00a1_0x03=3630 + +hwmon_in.mode_0x00a1_0x05=constant +hwmon_in.int_cons_0x00a1_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a1_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a1_0x00=1 + + +# vol sensor 162 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a2_0x00=config +hwmon_in.src_0x00a2_0x00=file +hwmon_in.int_cons_0x00a2_0x00=0 +hwmon_in.frmt_0x00a2_0x00=buf +hwmon_in.fpath_0x00a2_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x00a2_0x00=0 +hwmon_in.len_0x00a2_0x00=8 +hwmon_in.str_cons_0x00a2_0x00=in10_input +hwmon_in.int_extra1_0x00a2_0x00=0 +hwmon_in.int_extra2_0x00a2_0x00=0 + +hwmon_in.mode_0x00a2_0x01=str_constant +hwmon_in.str_cons_0x00a2_0x01=UCD90160_06_OSFP_VDD3V3_A3_V + +hwmon_in.mode_0x00a2_0x02=str_constant +hwmon_in.str_cons_0x00a2_0x02=UCD90160_06 + +hwmon_in.mode_0x00a2_0x03=constant +hwmon_in.int_cons_0x00a2_0x03=3630 + +hwmon_in.mode_0x00a2_0x05=constant +hwmon_in.int_cons_0x00a2_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a2_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a2_0x00=1 + + +# vol sensor 163 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a3_0x00=config +hwmon_in.src_0x00a3_0x00=file +hwmon_in.int_cons_0x00a3_0x00=0 +hwmon_in.frmt_0x00a3_0x00=buf +hwmon_in.fpath_0x00a3_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x00a3_0x00=0 +hwmon_in.len_0x00a3_0x00=8 +hwmon_in.str_cons_0x00a3_0x00=in11_input +hwmon_in.int_extra1_0x00a3_0x00=0 +hwmon_in.int_extra2_0x00a3_0x00=0 + +hwmon_in.mode_0x00a3_0x01=str_constant +hwmon_in.str_cons_0x00a3_0x01=UCD90160_06_OSFP_VDD3V3_B3_V + +hwmon_in.mode_0x00a3_0x02=str_constant +hwmon_in.str_cons_0x00a3_0x02=UCD90160_06 + +hwmon_in.mode_0x00a3_0x03=constant +hwmon_in.int_cons_0x00a3_0x03=3630 + +hwmon_in.mode_0x00a3_0x05=constant +hwmon_in.int_cons_0x00a3_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a3_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a3_0x00=1 + + +# vol sensor 164 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a4_0x00=config +hwmon_in.src_0x00a4_0x00=file +hwmon_in.int_cons_0x00a4_0x00=0 +hwmon_in.frmt_0x00a4_0x00=buf +hwmon_in.fpath_0x00a4_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x00a4_0x00=0 +hwmon_in.len_0x00a4_0x00=8 +hwmon_in.str_cons_0x00a4_0x00=in12_input +hwmon_in.int_extra1_0x00a4_0x00=0 +hwmon_in.int_extra2_0x00a4_0x00=0 + +hwmon_in.mode_0x00a4_0x01=str_constant +hwmon_in.str_cons_0x00a4_0x01=UCD90160_06_OSFP_VDD3V3_A4_V + +hwmon_in.mode_0x00a4_0x02=str_constant +hwmon_in.str_cons_0x00a4_0x02=UCD90160_06 + +hwmon_in.mode_0x00a4_0x03=constant +hwmon_in.int_cons_0x00a4_0x03=3630 + +hwmon_in.mode_0x00a4_0x05=constant +hwmon_in.int_cons_0x00a4_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a4_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a4_0x00=1 + + +# vol sensor 165 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a5_0x00=config +hwmon_in.src_0x00a5_0x00=file +hwmon_in.int_cons_0x00a5_0x00=0 +hwmon_in.frmt_0x00a5_0x00=buf +hwmon_in.fpath_0x00a5_0x00=/sys/bus/i2c/devices/92-005b/hwmon/ +hwmon_in.addr_0x00a5_0x00=0 +hwmon_in.len_0x00a5_0x00=8 +hwmon_in.str_cons_0x00a5_0x00=in13_input +hwmon_in.int_extra1_0x00a5_0x00=0 +hwmon_in.int_extra2_0x00a5_0x00=0 + +hwmon_in.mode_0x00a5_0x01=str_constant +hwmon_in.str_cons_0x00a5_0x01=UCD90160_06_OSFP_VDD3V3_B4_V + +hwmon_in.mode_0x00a5_0x02=str_constant +hwmon_in.str_cons_0x00a5_0x02=UCD90160_06 + +hwmon_in.mode_0x00a5_0x03=constant +hwmon_in.int_cons_0x00a5_0x03=3630 + +hwmon_in.mode_0x00a5_0x05=constant +hwmon_in.int_cons_0x00a5_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a5_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a5_0x00=1 + + +# vol sensor 166 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a6_0x00=config +hwmon_in.src_0x00a6_0x00=file +hwmon_in.int_cons_0x00a6_0x00=3 +hwmon_in.frmt_0x00a6_0x00=buf +hwmon_in.fpath_0x00a6_0x00=/sys/bus/i2c/devices/94-0060/hwmon/ +hwmon_in.addr_0x00a6_0x00=0 +hwmon_in.len_0x00a6_0x00=8 +hwmon_in.str_cons_0x00a6_0x00=in3_input +hwmon_in.int_extra1_0x00a6_0x00=1500 +hwmon_in.int_extra2_0x00a6_0x00=0 + +hwmon_in.mode_0x00a6_0x01=str_constant +hwmon_in.str_cons_0x00a6_0x01=XDPE12284C_21_OSFP_VDD3V3_A1_V + +hwmon_in.mode_0x00a6_0x02=str_constant +hwmon_in.str_cons_0x00a6_0x02=XDPE12284C_21 + +hwmon_in.mode_0x00a6_0x03=constant +hwmon_in.int_cons_0x00a6_0x03=3630 + +hwmon_in.mode_0x00a6_0x05=constant +hwmon_in.int_cons_0x00a6_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a6_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a6_0x00=1 + + +# vol sensor 167 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a7_0x00=config +hwmon_in.src_0x00a7_0x00=file +hwmon_in.int_cons_0x00a7_0x00=3 +hwmon_in.frmt_0x00a7_0x00=buf +hwmon_in.fpath_0x00a7_0x00=/sys/bus/i2c/devices/94-0060/hwmon/ +hwmon_in.addr_0x00a7_0x00=0 +hwmon_in.len_0x00a7_0x00=8 +hwmon_in.str_cons_0x00a7_0x00=in4_input +hwmon_in.int_extra1_0x00a7_0x00=1500 +hwmon_in.int_extra2_0x00a7_0x00=0 + +hwmon_in.mode_0x00a7_0x01=str_constant +hwmon_in.str_cons_0x00a7_0x01=XDPE12284C_21_OSFP_VDD3V3_B1_V + +hwmon_in.mode_0x00a7_0x02=str_constant +hwmon_in.str_cons_0x00a7_0x02=XDPE12284C_21 + +hwmon_in.mode_0x00a7_0x03=constant +hwmon_in.int_cons_0x00a7_0x03=3630 + +hwmon_in.mode_0x00a7_0x05=constant +hwmon_in.int_cons_0x00a7_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a7_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a7_0x00=1 + + +# vol sensor 168 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a8_0x00=config +hwmon_in.src_0x00a8_0x00=file +hwmon_in.int_cons_0x00a8_0x00=3 +hwmon_in.frmt_0x00a8_0x00=buf +hwmon_in.fpath_0x00a8_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_in.addr_0x00a8_0x00=0 +hwmon_in.len_0x00a8_0x00=8 +hwmon_in.str_cons_0x00a8_0x00=in3_input +hwmon_in.int_extra1_0x00a8_0x00=1500 +hwmon_in.int_extra2_0x00a8_0x00=0 + +hwmon_in.mode_0x00a8_0x01=str_constant +hwmon_in.str_cons_0x00a8_0x01=XDPE12284C_22_OSFP_VDD3V3_A2_V + +hwmon_in.mode_0x00a8_0x02=str_constant +hwmon_in.str_cons_0x00a8_0x02=XDPE12284C_22 + +hwmon_in.mode_0x00a8_0x03=constant +hwmon_in.int_cons_0x00a8_0x03=3630 + +hwmon_in.mode_0x00a8_0x05=constant +hwmon_in.int_cons_0x00a8_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a8_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a8_0x00=1 + + +# vol sensor 169 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00a9_0x00=config +hwmon_in.src_0x00a9_0x00=file +hwmon_in.int_cons_0x00a9_0x00=3 +hwmon_in.frmt_0x00a9_0x00=buf +hwmon_in.fpath_0x00a9_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_in.addr_0x00a9_0x00=0 +hwmon_in.len_0x00a9_0x00=8 +hwmon_in.str_cons_0x00a9_0x00=in4_input +hwmon_in.int_extra1_0x00a9_0x00=1500 +hwmon_in.int_extra2_0x00a9_0x00=0 + +hwmon_in.mode_0x00a9_0x01=str_constant +hwmon_in.str_cons_0x00a9_0x01=XDPE12284C_22_OSFP_VDD3V3_B2_V + +hwmon_in.mode_0x00a9_0x02=str_constant +hwmon_in.str_cons_0x00a9_0x02=XDPE12284C_22 + +hwmon_in.mode_0x00a9_0x03=constant +hwmon_in.int_cons_0x00a9_0x03=3630 + +hwmon_in.mode_0x00a9_0x05=constant +hwmon_in.int_cons_0x00a9_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00a9_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00a9_0x00=1 + + +# vol sensor 170 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00aa_0x00=config +hwmon_in.src_0x00aa_0x00=file +hwmon_in.int_cons_0x00aa_0x00=3 +hwmon_in.frmt_0x00aa_0x00=buf +hwmon_in.fpath_0x00aa_0x00=/sys/bus/i2c/devices/96-0060/hwmon/ +hwmon_in.addr_0x00aa_0x00=0 +hwmon_in.len_0x00aa_0x00=8 +hwmon_in.str_cons_0x00aa_0x00=in3_input +hwmon_in.int_extra1_0x00aa_0x00=1500 +hwmon_in.int_extra2_0x00aa_0x00=0 + +hwmon_in.mode_0x00aa_0x01=str_constant +hwmon_in.str_cons_0x00aa_0x01=XDPE12284C_23_OSFP_VDD3V3_A3_V + +hwmon_in.mode_0x00aa_0x02=str_constant +hwmon_in.str_cons_0x00aa_0x02=XDPE12284C_23 + +hwmon_in.mode_0x00aa_0x03=constant +hwmon_in.int_cons_0x00aa_0x03=3630 + +hwmon_in.mode_0x00aa_0x05=constant +hwmon_in.int_cons_0x00aa_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00aa_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00aa_0x00=1 + + +# vol sensor 171 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ab_0x00=config +hwmon_in.src_0x00ab_0x00=file +hwmon_in.int_cons_0x00ab_0x00=3 +hwmon_in.frmt_0x00ab_0x00=buf +hwmon_in.fpath_0x00ab_0x00=/sys/bus/i2c/devices/96-0060/hwmon/ +hwmon_in.addr_0x00ab_0x00=0 +hwmon_in.len_0x00ab_0x00=8 +hwmon_in.str_cons_0x00ab_0x00=in4_input +hwmon_in.int_extra1_0x00ab_0x00=1500 +hwmon_in.int_extra2_0x00ab_0x00=0 + +hwmon_in.mode_0x00ab_0x01=str_constant +hwmon_in.str_cons_0x00ab_0x01=XDPE12284C_23_OSFP_VDD3V3_B3_V + +hwmon_in.mode_0x00ab_0x02=str_constant +hwmon_in.str_cons_0x00ab_0x02=XDPE12284C_23 + +hwmon_in.mode_0x00ab_0x03=constant +hwmon_in.int_cons_0x00ab_0x03=3630 + +hwmon_in.mode_0x00ab_0x05=constant +hwmon_in.int_cons_0x00ab_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00ab_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ab_0x00=1 + + +# vol sensor 172 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ac_0x00=config +hwmon_in.src_0x00ac_0x00=file +hwmon_in.int_cons_0x00ac_0x00=3 +hwmon_in.frmt_0x00ac_0x00=buf +hwmon_in.fpath_0x00ac_0x00=/sys/bus/i2c/devices/97-0060/hwmon/ +hwmon_in.addr_0x00ac_0x00=0 +hwmon_in.len_0x00ac_0x00=8 +hwmon_in.str_cons_0x00ac_0x00=in3_input +hwmon_in.int_extra1_0x00ac_0x00=1500 +hwmon_in.int_extra2_0x00ac_0x00=0 + +hwmon_in.mode_0x00ac_0x01=str_constant +hwmon_in.str_cons_0x00ac_0x01=XDPE12284C_24_OSFP_VDD3V3_A4_V + +hwmon_in.mode_0x00ac_0x02=str_constant +hwmon_in.str_cons_0x00ac_0x02=XDPE12284C_24 + +hwmon_in.mode_0x00ac_0x03=constant +hwmon_in.int_cons_0x00ac_0x03=3630 + +hwmon_in.mode_0x00ac_0x05=constant +hwmon_in.int_cons_0x00ac_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00ac_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ac_0x00=1 + + +# vol sensor 173 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ad_0x00=config +hwmon_in.src_0x00ad_0x00=file +hwmon_in.int_cons_0x00ad_0x00=3 +hwmon_in.frmt_0x00ad_0x00=buf +hwmon_in.fpath_0x00ad_0x00=/sys/bus/i2c/devices/97-0060/hwmon/ +hwmon_in.addr_0x00ad_0x00=0 +hwmon_in.len_0x00ad_0x00=8 +hwmon_in.str_cons_0x00ad_0x00=in4_input +hwmon_in.int_extra1_0x00ad_0x00=1500 +hwmon_in.int_extra2_0x00ad_0x00=0 + +hwmon_in.mode_0x00ad_0x01=str_constant +hwmon_in.str_cons_0x00ad_0x01=XDPE12284C_24_OSFP_VDD3V3_B4_V + +hwmon_in.mode_0x00ad_0x02=str_constant +hwmon_in.str_cons_0x00ad_0x02=XDPE12284C_24 + +hwmon_in.mode_0x00ad_0x03=constant +hwmon_in.int_cons_0x00ad_0x03=3630 + +hwmon_in.mode_0x00ad_0x05=constant +hwmon_in.int_cons_0x00ad_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00ad_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ad_0x00=1 + + +# vol sensor 174 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ae_0x00=config +hwmon_in.src_0x00ae_0x00=file +hwmon_in.int_cons_0x00ae_0x00=0 +hwmon_in.frmt_0x00ae_0x00=buf +hwmon_in.fpath_0x00ae_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00ae_0x00=0 +hwmon_in.len_0x00ae_0x00=8 +hwmon_in.str_cons_0x00ae_0x00=in15_input +hwmon_in.int_extra1_0x00ae_0x00=0 +hwmon_in.int_extra2_0x00ae_0x00=0 + +hwmon_in.mode_0x00ae_0x01=str_constant +hwmon_in.str_cons_0x00ae_0x01=UCD90160_07_VDD12V_DPORT_V + +hwmon_in.mode_0x00ae_0x02=str_constant +hwmon_in.str_cons_0x00ae_0x02=UCD90160_07 + +hwmon_in.mode_0x00ae_0x03=constant +hwmon_in.int_cons_0x00ae_0x03=13200 + +hwmon_in.mode_0x00ae_0x05=constant +hwmon_in.int_cons_0x00ae_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00ae_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ae_0x00=1 + + +# vol sensor 175 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00af_0x00=config +hwmon_in.src_0x00af_0x00=file +hwmon_in.int_cons_0x00af_0x00=0 +hwmon_in.frmt_0x00af_0x00=buf +hwmon_in.fpath_0x00af_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00af_0x00=0 +hwmon_in.len_0x00af_0x00=8 +hwmon_in.str_cons_0x00af_0x00=in14_input +hwmon_in.int_extra1_0x00af_0x00=0 +hwmon_in.int_extra2_0x00af_0x00=0 + +hwmon_in.mode_0x00af_0x01=str_constant +hwmon_in.str_cons_0x00af_0x01=UCD90160_07_VDD3V3_STANDBY_V + +hwmon_in.mode_0x00af_0x02=str_constant +hwmon_in.str_cons_0x00af_0x02=UCD90160_07 + +hwmon_in.mode_0x00af_0x03=constant +hwmon_in.int_cons_0x00af_0x03=3630 + +hwmon_in.mode_0x00af_0x05=constant +hwmon_in.int_cons_0x00af_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00af_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00af_0x00=1 + + +# vol sensor 176 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b0_0x00=config +hwmon_in.src_0x00b0_0x00=file +hwmon_in.int_cons_0x00b0_0x00=0 +hwmon_in.frmt_0x00b0_0x00=buf +hwmon_in.fpath_0x00b0_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b0_0x00=0 +hwmon_in.len_0x00b0_0x00=8 +hwmon_in.str_cons_0x00b0_0x00=in1_input +hwmon_in.int_extra1_0x00b0_0x00=0 +hwmon_in.int_extra2_0x00b0_0x00=0 + +hwmon_in.mode_0x00b0_0x01=str_constant +hwmon_in.str_cons_0x00b0_0x01=UCD90160_07_FPGA_VDD_1V0_V + +hwmon_in.mode_0x00b0_0x02=str_constant +hwmon_in.str_cons_0x00b0_0x02=UCD90160_07 + +hwmon_in.mode_0x00b0_0x03=constant +hwmon_in.int_cons_0x00b0_0x03=1100 + +hwmon_in.mode_0x00b0_0x05=constant +hwmon_in.int_cons_0x00b0_0x05=900 + +monitor_flag_hwmon_in.mode_0x00b0_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b0_0x00=1 + + +# vol sensor 177 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b1_0x00=config +hwmon_in.src_0x00b1_0x00=file +hwmon_in.int_cons_0x00b1_0x00=0 +hwmon_in.frmt_0x00b1_0x00=buf +hwmon_in.fpath_0x00b1_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b1_0x00=0 +hwmon_in.len_0x00b1_0x00=8 +hwmon_in.str_cons_0x00b1_0x00=in2_input +hwmon_in.int_extra1_0x00b1_0x00=0 +hwmon_in.int_extra2_0x00b1_0x00=0 + +hwmon_in.mode_0x00b1_0x01=str_constant +hwmon_in.str_cons_0x00b1_0x01=UCD90160_07_FPGA_VDD_1V8_V + +hwmon_in.mode_0x00b1_0x02=str_constant +hwmon_in.str_cons_0x00b1_0x02=UCD90160_07 + +hwmon_in.mode_0x00b1_0x03=constant +hwmon_in.int_cons_0x00b1_0x03=1980 + +hwmon_in.mode_0x00b1_0x05=constant +hwmon_in.int_cons_0x00b1_0x05=1620 + +monitor_flag_hwmon_in.mode_0x00b1_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b1_0x00=1 + + +# vol sensor 178 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b2_0x00=config +hwmon_in.src_0x00b2_0x00=file +hwmon_in.int_cons_0x00b2_0x00=0 +hwmon_in.frmt_0x00b2_0x00=buf +hwmon_in.fpath_0x00b2_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b2_0x00=0 +hwmon_in.len_0x00b2_0x00=8 +hwmon_in.str_cons_0x00b2_0x00=in3_input +hwmon_in.int_extra1_0x00b2_0x00=0 +hwmon_in.int_extra2_0x00b2_0x00=0 + +hwmon_in.mode_0x00b2_0x01=str_constant +hwmon_in.str_cons_0x00b2_0x01=UCD90160_07_FPGA_VDD_1V2_V + +hwmon_in.mode_0x00b2_0x02=str_constant +hwmon_in.str_cons_0x00b2_0x02=UCD90160_07 + +hwmon_in.mode_0x00b2_0x03=constant +hwmon_in.int_cons_0x00b2_0x03=1320 + +hwmon_in.mode_0x00b2_0x05=constant +hwmon_in.int_cons_0x00b2_0x05=1080 + +monitor_flag_hwmon_in.mode_0x00b2_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b2_0x00=1 + + +# vol sensor 179 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b3_0x00=config +hwmon_in.src_0x00b3_0x00=file +hwmon_in.int_cons_0x00b3_0x00=0 +hwmon_in.frmt_0x00b3_0x00=buf +hwmon_in.fpath_0x00b3_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b3_0x00=0 +hwmon_in.len_0x00b3_0x00=8 +hwmon_in.str_cons_0x00b3_0x00=in4_input +hwmon_in.int_extra1_0x00b3_0x00=0 +hwmon_in.int_extra2_0x00b3_0x00=0 + +hwmon_in.mode_0x00b3_0x01=str_constant +hwmon_in.str_cons_0x00b3_0x01=UCD90160_07_VDD_3V3_V + +hwmon_in.mode_0x00b3_0x02=str_constant +hwmon_in.str_cons_0x00b3_0x02=UCD90160_07 + +hwmon_in.mode_0x00b3_0x03=constant +hwmon_in.int_cons_0x00b3_0x03=3630 + +hwmon_in.mode_0x00b3_0x05=constant +hwmon_in.int_cons_0x00b3_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00b3_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b3_0x00=1 + + +# vol sensor 180 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b4_0x00=config +hwmon_in.src_0x00b4_0x00=file +hwmon_in.int_cons_0x00b4_0x00=0 +hwmon_in.frmt_0x00b4_0x00=buf +hwmon_in.fpath_0x00b4_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b4_0x00=0 +hwmon_in.len_0x00b4_0x00=8 +hwmon_in.str_cons_0x00b4_0x00=in5_input +hwmon_in.int_extra1_0x00b4_0x00=0 +hwmon_in.int_extra2_0x00b4_0x00=0 + +hwmon_in.mode_0x00b4_0x01=str_constant +hwmon_in.str_cons_0x00b4_0x01=UCD90160_07_PWR_VDD_5V0_V + +hwmon_in.mode_0x00b4_0x02=str_constant +hwmon_in.str_cons_0x00b4_0x02=UCD90160_07 + +hwmon_in.mode_0x00b4_0x03=constant +hwmon_in.int_cons_0x00b4_0x03=5500 + +hwmon_in.mode_0x00b4_0x05=constant +hwmon_in.int_cons_0x00b4_0x05=4500 + +monitor_flag_hwmon_in.mode_0x00b4_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b4_0x00=1 + + +# vol sensor 181 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b5_0x00=config +hwmon_in.src_0x00b5_0x00=file +hwmon_in.int_cons_0x00b5_0x00=0 +hwmon_in.frmt_0x00b5_0x00=buf +hwmon_in.fpath_0x00b5_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b5_0x00=0 +hwmon_in.len_0x00b5_0x00=8 +hwmon_in.str_cons_0x00b5_0x00=in6_input +hwmon_in.int_extra1_0x00b5_0x00=0 +hwmon_in.int_extra2_0x00b5_0x00=0 + +hwmon_in.mode_0x00b5_0x01=str_constant +hwmon_in.str_cons_0x00b5_0x01=UCD90160_07_OSFP_VDD3V3_A1_V + +hwmon_in.mode_0x00b5_0x02=str_constant +hwmon_in.str_cons_0x00b5_0x02=UCD90160_07 + +hwmon_in.mode_0x00b5_0x03=constant +hwmon_in.int_cons_0x00b5_0x03=3630 + +hwmon_in.mode_0x00b5_0x05=constant +hwmon_in.int_cons_0x00b5_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00b5_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b5_0x00=1 + + +# vol sensor 182 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b6_0x00=config +hwmon_in.src_0x00b6_0x00=file +hwmon_in.int_cons_0x00b6_0x00=0 +hwmon_in.frmt_0x00b6_0x00=buf +hwmon_in.fpath_0x00b6_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b6_0x00=0 +hwmon_in.len_0x00b6_0x00=8 +hwmon_in.str_cons_0x00b6_0x00=in7_input +hwmon_in.int_extra1_0x00b6_0x00=0 +hwmon_in.int_extra2_0x00b6_0x00=0 + +hwmon_in.mode_0x00b6_0x01=str_constant +hwmon_in.str_cons_0x00b6_0x01=UCD90160_07_OSFP_VDD3V3_B1_V + +hwmon_in.mode_0x00b6_0x02=str_constant +hwmon_in.str_cons_0x00b6_0x02=UCD90160_07 + +hwmon_in.mode_0x00b6_0x03=constant +hwmon_in.int_cons_0x00b6_0x03=3630 + +hwmon_in.mode_0x00b6_0x05=constant +hwmon_in.int_cons_0x00b6_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00b6_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b6_0x00=1 + + +# vol sensor 183 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b7_0x00=config +hwmon_in.src_0x00b7_0x00=file +hwmon_in.int_cons_0x00b7_0x00=0 +hwmon_in.frmt_0x00b7_0x00=buf +hwmon_in.fpath_0x00b7_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b7_0x00=0 +hwmon_in.len_0x00b7_0x00=8 +hwmon_in.str_cons_0x00b7_0x00=in8_input +hwmon_in.int_extra1_0x00b7_0x00=0 +hwmon_in.int_extra2_0x00b7_0x00=0 + +hwmon_in.mode_0x00b7_0x01=str_constant +hwmon_in.str_cons_0x00b7_0x01=UCD90160_07_OSFP_VDD3V3_A2_V + +hwmon_in.mode_0x00b7_0x02=str_constant +hwmon_in.str_cons_0x00b7_0x02=UCD90160_07 + +hwmon_in.mode_0x00b7_0x03=constant +hwmon_in.int_cons_0x00b7_0x03=3630 + +hwmon_in.mode_0x00b7_0x05=constant +hwmon_in.int_cons_0x00b7_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00b7_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b7_0x00=1 + + +# vol sensor 184 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b8_0x00=config +hwmon_in.src_0x00b8_0x00=file +hwmon_in.int_cons_0x00b8_0x00=0 +hwmon_in.frmt_0x00b8_0x00=buf +hwmon_in.fpath_0x00b8_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b8_0x00=0 +hwmon_in.len_0x00b8_0x00=8 +hwmon_in.str_cons_0x00b8_0x00=in9_input +hwmon_in.int_extra1_0x00b8_0x00=0 +hwmon_in.int_extra2_0x00b8_0x00=0 + +hwmon_in.mode_0x00b8_0x01=str_constant +hwmon_in.str_cons_0x00b8_0x01=UCD90160_07_OSFP_VDD3V3_B2_V + +hwmon_in.mode_0x00b8_0x02=str_constant +hwmon_in.str_cons_0x00b8_0x02=UCD90160_07 + +hwmon_in.mode_0x00b8_0x03=constant +hwmon_in.int_cons_0x00b8_0x03=3630 + +hwmon_in.mode_0x00b8_0x05=constant +hwmon_in.int_cons_0x00b8_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00b8_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b8_0x00=1 + + +# vol sensor 185 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00b9_0x00=config +hwmon_in.src_0x00b9_0x00=file +hwmon_in.int_cons_0x00b9_0x00=0 +hwmon_in.frmt_0x00b9_0x00=buf +hwmon_in.fpath_0x00b9_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00b9_0x00=0 +hwmon_in.len_0x00b9_0x00=8 +hwmon_in.str_cons_0x00b9_0x00=in10_input +hwmon_in.int_extra1_0x00b9_0x00=0 +hwmon_in.int_extra2_0x00b9_0x00=0 + +hwmon_in.mode_0x00b9_0x01=str_constant +hwmon_in.str_cons_0x00b9_0x01=UCD90160_07_OSFP_VDD3V3_A3_V + +hwmon_in.mode_0x00b9_0x02=str_constant +hwmon_in.str_cons_0x00b9_0x02=UCD90160_07 + +hwmon_in.mode_0x00b9_0x03=constant +hwmon_in.int_cons_0x00b9_0x03=3630 + +hwmon_in.mode_0x00b9_0x05=constant +hwmon_in.int_cons_0x00b9_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00b9_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00b9_0x00=1 + + +# vol sensor 186 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ba_0x00=config +hwmon_in.src_0x00ba_0x00=file +hwmon_in.int_cons_0x00ba_0x00=0 +hwmon_in.frmt_0x00ba_0x00=buf +hwmon_in.fpath_0x00ba_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00ba_0x00=0 +hwmon_in.len_0x00ba_0x00=8 +hwmon_in.str_cons_0x00ba_0x00=in11_input +hwmon_in.int_extra1_0x00ba_0x00=0 +hwmon_in.int_extra2_0x00ba_0x00=0 + +hwmon_in.mode_0x00ba_0x01=str_constant +hwmon_in.str_cons_0x00ba_0x01=UCD90160_07_OSFP_VDD3V3_B3_V + +hwmon_in.mode_0x00ba_0x02=str_constant +hwmon_in.str_cons_0x00ba_0x02=UCD90160_07 + +hwmon_in.mode_0x00ba_0x03=constant +hwmon_in.int_cons_0x00ba_0x03=3630 + +hwmon_in.mode_0x00ba_0x05=constant +hwmon_in.int_cons_0x00ba_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00ba_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ba_0x00=1 + + +# vol sensor 187 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00bb_0x00=config +hwmon_in.src_0x00bb_0x00=file +hwmon_in.int_cons_0x00bb_0x00=0 +hwmon_in.frmt_0x00bb_0x00=buf +hwmon_in.fpath_0x00bb_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00bb_0x00=0 +hwmon_in.len_0x00bb_0x00=8 +hwmon_in.str_cons_0x00bb_0x00=in12_input +hwmon_in.int_extra1_0x00bb_0x00=0 +hwmon_in.int_extra2_0x00bb_0x00=0 + +hwmon_in.mode_0x00bb_0x01=str_constant +hwmon_in.str_cons_0x00bb_0x01=UCD90160_07_OSFP_VDD3V3_A4_V + +hwmon_in.mode_0x00bb_0x02=str_constant +hwmon_in.str_cons_0x00bb_0x02=UCD90160_07 + +hwmon_in.mode_0x00bb_0x03=constant +hwmon_in.int_cons_0x00bb_0x03=3630 + +hwmon_in.mode_0x00bb_0x05=constant +hwmon_in.int_cons_0x00bb_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00bb_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00bb_0x00=1 + + +# vol sensor 188 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00bc_0x00=config +hwmon_in.src_0x00bc_0x00=file +hwmon_in.int_cons_0x00bc_0x00=0 +hwmon_in.frmt_0x00bc_0x00=buf +hwmon_in.fpath_0x00bc_0x00=/sys/bus/i2c/devices/100-005b/hwmon/ +hwmon_in.addr_0x00bc_0x00=0 +hwmon_in.len_0x00bc_0x00=8 +hwmon_in.str_cons_0x00bc_0x00=in13_input +hwmon_in.int_extra1_0x00bc_0x00=0 +hwmon_in.int_extra2_0x00bc_0x00=0 + +hwmon_in.mode_0x00bc_0x01=str_constant +hwmon_in.str_cons_0x00bc_0x01=UCD90160_07_OSFP_VDD3V3_B4_V + +hwmon_in.mode_0x00bc_0x02=str_constant +hwmon_in.str_cons_0x00bc_0x02=UCD90160_07 + +hwmon_in.mode_0x00bc_0x03=constant +hwmon_in.int_cons_0x00bc_0x03=3630 + +hwmon_in.mode_0x00bc_0x05=constant +hwmon_in.int_cons_0x00bc_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00bc_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00bc_0x00=1 + + +# vol sensor 189 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00bd_0x00=config +hwmon_in.src_0x00bd_0x00=file +hwmon_in.int_cons_0x00bd_0x00=3 +hwmon_in.frmt_0x00bd_0x00=buf +hwmon_in.fpath_0x00bd_0x00=/sys/bus/i2c/devices/102-0060/hwmon/ +hwmon_in.addr_0x00bd_0x00=0 +hwmon_in.len_0x00bd_0x00=8 +hwmon_in.str_cons_0x00bd_0x00=in3_input +hwmon_in.int_extra1_0x00bd_0x00=1500 +hwmon_in.int_extra2_0x00bd_0x00=0 + +hwmon_in.mode_0x00bd_0x01=str_constant +hwmon_in.str_cons_0x00bd_0x01=XDPE12284C_25_OSFP_VDD3V3_A1_V + +hwmon_in.mode_0x00bd_0x02=str_constant +hwmon_in.str_cons_0x00bd_0x02=XDPE12284C_25 + +hwmon_in.mode_0x00bd_0x03=constant +hwmon_in.int_cons_0x00bd_0x03=3630 + +hwmon_in.mode_0x00bd_0x05=constant +hwmon_in.int_cons_0x00bd_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00bd_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00bd_0x00=1 + + +# vol sensor 190 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00be_0x00=config +hwmon_in.src_0x00be_0x00=file +hwmon_in.int_cons_0x00be_0x00=3 +hwmon_in.frmt_0x00be_0x00=buf +hwmon_in.fpath_0x00be_0x00=/sys/bus/i2c/devices/102-0060/hwmon/ +hwmon_in.addr_0x00be_0x00=0 +hwmon_in.len_0x00be_0x00=8 +hwmon_in.str_cons_0x00be_0x00=in4_input +hwmon_in.int_extra1_0x00be_0x00=1500 +hwmon_in.int_extra2_0x00be_0x00=0 + +hwmon_in.mode_0x00be_0x01=str_constant +hwmon_in.str_cons_0x00be_0x01=XDPE12284C_25_OSFP_VDD3V3_B1_V + +hwmon_in.mode_0x00be_0x02=str_constant +hwmon_in.str_cons_0x00be_0x02=XDPE12284C_25 + +hwmon_in.mode_0x00be_0x03=constant +hwmon_in.int_cons_0x00be_0x03=3630 + +hwmon_in.mode_0x00be_0x05=constant +hwmon_in.int_cons_0x00be_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00be_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00be_0x00=1 + + +# vol sensor 191 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00bf_0x00=config +hwmon_in.src_0x00bf_0x00=file +hwmon_in.int_cons_0x00bf_0x00=3 +hwmon_in.frmt_0x00bf_0x00=buf +hwmon_in.fpath_0x00bf_0x00=/sys/bus/i2c/devices/103-0060/hwmon/ +hwmon_in.addr_0x00bf_0x00=0 +hwmon_in.len_0x00bf_0x00=8 +hwmon_in.str_cons_0x00bf_0x00=in3_input +hwmon_in.int_extra1_0x00bf_0x00=1500 +hwmon_in.int_extra2_0x00bf_0x00=0 + +hwmon_in.mode_0x00bf_0x01=str_constant +hwmon_in.str_cons_0x00bf_0x01=XDPE12284C_26_OSFP_VDD3V3_A2_V + +hwmon_in.mode_0x00bf_0x02=str_constant +hwmon_in.str_cons_0x00bf_0x02=XDPE12284C_26 + +hwmon_in.mode_0x00bf_0x03=constant +hwmon_in.int_cons_0x00bf_0x03=3630 + +hwmon_in.mode_0x00bf_0x05=constant +hwmon_in.int_cons_0x00bf_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00bf_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00bf_0x00=1 + + +# vol sensor 192 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c0_0x00=config +hwmon_in.src_0x00c0_0x00=file +hwmon_in.int_cons_0x00c0_0x00=3 +hwmon_in.frmt_0x00c0_0x00=buf +hwmon_in.fpath_0x00c0_0x00=/sys/bus/i2c/devices/103-0060/hwmon/ +hwmon_in.addr_0x00c0_0x00=0 +hwmon_in.len_0x00c0_0x00=8 +hwmon_in.str_cons_0x00c0_0x00=in4_input +hwmon_in.int_extra1_0x00c0_0x00=1500 +hwmon_in.int_extra2_0x00c0_0x00=0 + +hwmon_in.mode_0x00c0_0x01=str_constant +hwmon_in.str_cons_0x00c0_0x01=XDPE12284C_26_OSFP_VDD3V3_B2_V + +hwmon_in.mode_0x00c0_0x02=str_constant +hwmon_in.str_cons_0x00c0_0x02=XDPE12284C_26 + +hwmon_in.mode_0x00c0_0x03=constant +hwmon_in.int_cons_0x00c0_0x03=3630 + +hwmon_in.mode_0x00c0_0x05=constant +hwmon_in.int_cons_0x00c0_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c0_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c0_0x00=1 + + +# vol sensor 193 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c1_0x00=config +hwmon_in.src_0x00c1_0x00=file +hwmon_in.int_cons_0x00c1_0x00=3 +hwmon_in.frmt_0x00c1_0x00=buf +hwmon_in.fpath_0x00c1_0x00=/sys/bus/i2c/devices/104-0060/hwmon/ +hwmon_in.addr_0x00c1_0x00=0 +hwmon_in.len_0x00c1_0x00=8 +hwmon_in.str_cons_0x00c1_0x00=in3_input +hwmon_in.int_extra1_0x00c1_0x00=1500 +hwmon_in.int_extra2_0x00c1_0x00=0 + +hwmon_in.mode_0x00c1_0x01=str_constant +hwmon_in.str_cons_0x00c1_0x01=XDPE12284C_27_OSFP_VDD3V3_A3_V + +hwmon_in.mode_0x00c1_0x02=str_constant +hwmon_in.str_cons_0x00c1_0x02=XDPE12284C_27 + +hwmon_in.mode_0x00c1_0x03=constant +hwmon_in.int_cons_0x00c1_0x03=3630 + +hwmon_in.mode_0x00c1_0x05=constant +hwmon_in.int_cons_0x00c1_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c1_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c1_0x00=1 + + +# vol sensor 194 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c2_0x00=config +hwmon_in.src_0x00c2_0x00=file +hwmon_in.int_cons_0x00c2_0x00=3 +hwmon_in.frmt_0x00c2_0x00=buf +hwmon_in.fpath_0x00c2_0x00=/sys/bus/i2c/devices/104-0060/hwmon/ +hwmon_in.addr_0x00c2_0x00=0 +hwmon_in.len_0x00c2_0x00=8 +hwmon_in.str_cons_0x00c2_0x00=in4_input +hwmon_in.int_extra1_0x00c2_0x00=1500 +hwmon_in.int_extra2_0x00c2_0x00=0 + +hwmon_in.mode_0x00c2_0x01=str_constant +hwmon_in.str_cons_0x00c2_0x01=XDPE12284C_27_OSFP_VDD3V3_B3_V + +hwmon_in.mode_0x00c2_0x02=str_constant +hwmon_in.str_cons_0x00c2_0x02=XDPE12284C_27 + +hwmon_in.mode_0x00c2_0x03=constant +hwmon_in.int_cons_0x00c2_0x03=3630 + +hwmon_in.mode_0x00c2_0x05=constant +hwmon_in.int_cons_0x00c2_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c2_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c2_0x00=1 + + +# vol sensor 195 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c3_0x00=config +hwmon_in.src_0x00c3_0x00=file +hwmon_in.int_cons_0x00c3_0x00=3 +hwmon_in.frmt_0x00c3_0x00=buf +hwmon_in.fpath_0x00c3_0x00=/sys/bus/i2c/devices/105-0060/hwmon/ +hwmon_in.addr_0x00c3_0x00=0 +hwmon_in.len_0x00c3_0x00=8 +hwmon_in.str_cons_0x00c3_0x00=in3_input +hwmon_in.int_extra1_0x00c3_0x00=1500 +hwmon_in.int_extra2_0x00c3_0x00=0 + +hwmon_in.mode_0x00c3_0x01=str_constant +hwmon_in.str_cons_0x00c3_0x01=XDPE12284C_28_OSFP_VDD3V3_A4_V + +hwmon_in.mode_0x00c3_0x02=str_constant +hwmon_in.str_cons_0x00c3_0x02=XDPE12284C_28 + +hwmon_in.mode_0x00c3_0x03=constant +hwmon_in.int_cons_0x00c3_0x03=3630 + +hwmon_in.mode_0x00c3_0x05=constant +hwmon_in.int_cons_0x00c3_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c3_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c3_0x00=1 + + +# vol sensor 196 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c4_0x00=config +hwmon_in.src_0x00c4_0x00=file +hwmon_in.int_cons_0x00c4_0x00=3 +hwmon_in.frmt_0x00c4_0x00=buf +hwmon_in.fpath_0x00c4_0x00=/sys/bus/i2c/devices/105-0060/hwmon/ +hwmon_in.addr_0x00c4_0x00=0 +hwmon_in.len_0x00c4_0x00=8 +hwmon_in.str_cons_0x00c4_0x00=in4_input +hwmon_in.int_extra1_0x00c4_0x00=1500 +hwmon_in.int_extra2_0x00c4_0x00=0 + +hwmon_in.mode_0x00c4_0x01=str_constant +hwmon_in.str_cons_0x00c4_0x01=XDPE12284C_28_OSFP_VDD3V3_B4_V + +hwmon_in.mode_0x00c4_0x02=str_constant +hwmon_in.str_cons_0x00c4_0x02=XDPE12284C_28 + +hwmon_in.mode_0x00c4_0x03=constant +hwmon_in.int_cons_0x00c4_0x03=3630 + +hwmon_in.mode_0x00c4_0x05=constant +hwmon_in.int_cons_0x00c4_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c4_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c4_0x00=1 + + +# vol sensor 197 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c5_0x00=config +hwmon_in.src_0x00c5_0x00=logic_file +hwmon_in.int_cons_0x00c5_0x00=0 +hwmon_in.frmt_0x00c5_0x00=num_bytes +hwmon_in.fpath_0x00c5_0x00=/dev/cpld7 +hwmon_in.addr_0x00c5_0x00=0xe8 +hwmon_in.len_0x00c5_0x00=2 +hwmon_in.int_extra1_0x00c5_0x00=0 +hwmon_in.int_extra2_0x00c5_0x00=2000 +hwmon_in.int_extra3_0x00c5_0x00=1 + +hwmon_in.mode_0x00c5_0x01=str_constant +hwmon_in.str_cons_0x00c5_0x01=CPLD_02_UFANA_VDD3V3_V + +hwmon_in.mode_0x00c5_0x02=str_constant +hwmon_in.str_cons_0x00c5_0x02=CPLD_02 + +hwmon_in.mode_0x00c5_0x03=constant +hwmon_in.int_cons_0x00c5_0x03=3630 + +hwmon_in.mode_0x00c5_0x05=constant +hwmon_in.int_cons_0x00c5_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c5_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c5_0x00=1 + + +# vol sensor 198 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c6_0x00=config +hwmon_in.src_0x00c6_0x00=logic_file +hwmon_in.int_cons_0x00c6_0x00=0 +hwmon_in.frmt_0x00c6_0x00=num_bytes +hwmon_in.fpath_0x00c6_0x00=/dev/cpld7 +hwmon_in.addr_0x00c6_0x00=0xea +hwmon_in.len_0x00c6_0x00=2 +hwmon_in.int_extra1_0x00c6_0x00=0 +hwmon_in.int_extra2_0x00c6_0x00=2000 +hwmon_in.int_extra3_0x00c6_0x00=1 + +hwmon_in.mode_0x00c6_0x01=str_constant +hwmon_in.str_cons_0x00c6_0x01=CPLD_02_UFANB_VDD3V3_V + +hwmon_in.mode_0x00c6_0x02=str_constant +hwmon_in.str_cons_0x00c6_0x02=CPLD_02 + +hwmon_in.mode_0x00c6_0x03=constant +hwmon_in.int_cons_0x00c6_0x03=3630 + +hwmon_in.mode_0x00c6_0x05=constant +hwmon_in.int_cons_0x00c6_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c6_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c6_0x00=1 + + +# vol sensor 199 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c7_0x00=config +hwmon_in.src_0x00c7_0x00=logic_file +hwmon_in.int_cons_0x00c7_0x00=0 +hwmon_in.frmt_0x00c7_0x00=num_bytes +hwmon_in.fpath_0x00c7_0x00=/dev/cpld7 +hwmon_in.addr_0x00c7_0x00=0xec +hwmon_in.len_0x00c7_0x00=2 +hwmon_in.int_extra1_0x00c7_0x00=0 +hwmon_in.int_extra2_0x00c7_0x00=2000 +hwmon_in.int_extra3_0x00c7_0x00=1 + +hwmon_in.mode_0x00c7_0x01=str_constant +hwmon_in.str_cons_0x00c7_0x01=CPLD_02_UFANC_VDD3V3_V + +hwmon_in.mode_0x00c7_0x02=str_constant +hwmon_in.str_cons_0x00c7_0x02=CPLD_02 + +hwmon_in.mode_0x00c7_0x03=constant +hwmon_in.int_cons_0x00c7_0x03=3630 + +hwmon_in.mode_0x00c7_0x05=constant +hwmon_in.int_cons_0x00c7_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c7_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c7_0x00=1 + + +# vol sensor 200 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c8_0x00=config +hwmon_in.src_0x00c8_0x00=logic_file +hwmon_in.int_cons_0x00c8_0x00=0 +hwmon_in.frmt_0x00c8_0x00=num_bytes +hwmon_in.fpath_0x00c8_0x00=/dev/cpld7 +hwmon_in.addr_0x00c8_0x00=0xee +hwmon_in.len_0x00c8_0x00=2 +hwmon_in.int_extra1_0x00c8_0x00=0 +hwmon_in.int_extra2_0x00c8_0x00=2000 +hwmon_in.int_extra3_0x00c8_0x00=1 + +hwmon_in.mode_0x00c8_0x01=str_constant +hwmon_in.str_cons_0x00c8_0x01=CPLD_02_UFAND_VDD3V3_V + +hwmon_in.mode_0x00c8_0x02=str_constant +hwmon_in.str_cons_0x00c8_0x02=CPLD_02 + +hwmon_in.mode_0x00c8_0x03=constant +hwmon_in.int_cons_0x00c8_0x03=3630 + +hwmon_in.mode_0x00c8_0x05=constant +hwmon_in.int_cons_0x00c8_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00c8_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c8_0x00=1 + + +# vol sensor 201 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00c9_0x00=config +hwmon_in.src_0x00c9_0x00=logic_file +hwmon_in.int_cons_0x00c9_0x00=0 +hwmon_in.frmt_0x00c9_0x00=num_bytes +hwmon_in.fpath_0x00c9_0x00=/dev/cpld7 +hwmon_in.addr_0x00c9_0x00=0xe0 +hwmon_in.len_0x00c9_0x00=2 +hwmon_in.int_extra1_0x00c9_0x00=0 +hwmon_in.int_extra2_0x00c9_0x00=7096 +hwmon_in.int_extra3_0x00c9_0x00=1 + +hwmon_in.mode_0x00c9_0x01=str_constant +hwmon_in.str_cons_0x00c9_0x01=CPLD_02_UFAN_VDD12V_1_V + +hwmon_in.mode_0x00c9_0x02=str_constant +hwmon_in.str_cons_0x00c9_0x02=CPLD_02 + +hwmon_in.mode_0x00c9_0x03=constant +hwmon_in.int_cons_0x00c9_0x03=13200 + +hwmon_in.mode_0x00c9_0x05=constant +hwmon_in.int_cons_0x00c9_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00c9_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00c9_0x00=1 + + +# vol sensor 202 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ca_0x00=config +hwmon_in.src_0x00ca_0x00=logic_file +hwmon_in.int_cons_0x00ca_0x00=0 +hwmon_in.frmt_0x00ca_0x00=num_bytes +hwmon_in.fpath_0x00ca_0x00=/dev/cpld7 +hwmon_in.addr_0x00ca_0x00=0xe2 +hwmon_in.len_0x00ca_0x00=2 +hwmon_in.int_extra1_0x00ca_0x00=0 +hwmon_in.int_extra2_0x00ca_0x00=7096 +hwmon_in.int_extra3_0x00ca_0x00=1 + +hwmon_in.mode_0x00ca_0x01=str_constant +hwmon_in.str_cons_0x00ca_0x01=CPLD_02_UFAN_VDD12V_2_V + +hwmon_in.mode_0x00ca_0x02=str_constant +hwmon_in.str_cons_0x00ca_0x02=CPLD_02 + +hwmon_in.mode_0x00ca_0x03=constant +hwmon_in.int_cons_0x00ca_0x03=13200 + +hwmon_in.mode_0x00ca_0x05=constant +hwmon_in.int_cons_0x00ca_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00ca_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ca_0x00=1 + + +# vol sensor 203 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00cb_0x00=config +hwmon_in.src_0x00cb_0x00=logic_file +hwmon_in.int_cons_0x00cb_0x00=0 +hwmon_in.frmt_0x00cb_0x00=num_bytes +hwmon_in.fpath_0x00cb_0x00=/dev/cpld7 +hwmon_in.addr_0x00cb_0x00=0xe4 +hwmon_in.len_0x00cb_0x00=2 +hwmon_in.int_extra1_0x00cb_0x00=0 +hwmon_in.int_extra2_0x00cb_0x00=7096 +hwmon_in.int_extra3_0x00cb_0x00=1 + +hwmon_in.mode_0x00cb_0x01=str_constant +hwmon_in.str_cons_0x00cb_0x01=CPLD_02_UFAN_VDD12V_3_V + +hwmon_in.mode_0x00cb_0x02=str_constant +hwmon_in.str_cons_0x00cb_0x02=CPLD_02 + +hwmon_in.mode_0x00cb_0x03=constant +hwmon_in.int_cons_0x00cb_0x03=13200 + +hwmon_in.mode_0x00cb_0x05=constant +hwmon_in.int_cons_0x00cb_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00cb_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00cb_0x00=1 + + +# vol sensor 204 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00cc_0x00=config +hwmon_in.src_0x00cc_0x00=logic_file +hwmon_in.int_cons_0x00cc_0x00=0 +hwmon_in.frmt_0x00cc_0x00=num_bytes +hwmon_in.fpath_0x00cc_0x00=/dev/cpld7 +hwmon_in.addr_0x00cc_0x00=0xe6 +hwmon_in.len_0x00cc_0x00=2 +hwmon_in.int_extra1_0x00cc_0x00=0 +hwmon_in.int_extra2_0x00cc_0x00=7096 +hwmon_in.int_extra3_0x00cc_0x00=1 + +hwmon_in.mode_0x00cc_0x01=str_constant +hwmon_in.str_cons_0x00cc_0x01=CPLD_02_UFAN_VDD12V_4_V + +hwmon_in.mode_0x00cc_0x02=str_constant +hwmon_in.str_cons_0x00cc_0x02=CPLD_02 + +hwmon_in.mode_0x00cc_0x03=constant +hwmon_in.int_cons_0x00cc_0x03=13200 + +hwmon_in.mode_0x00cc_0x05=constant +hwmon_in.int_cons_0x00cc_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00cc_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00cc_0x00=1 + + +# vol sensor 205 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00cd_0x00=config +hwmon_in.src_0x00cd_0x00=logic_file +hwmon_in.int_cons_0x00cd_0x00=0 +hwmon_in.frmt_0x00cd_0x00=num_bytes +hwmon_in.fpath_0x00cd_0x00=/dev/cpld8 +hwmon_in.addr_0x00cd_0x00=0xe8 +hwmon_in.len_0x00cd_0x00=2 +hwmon_in.int_extra1_0x00cd_0x00=0 +hwmon_in.int_extra2_0x00cd_0x00=2000 +hwmon_in.int_extra3_0x00cd_0x00=1 + +hwmon_in.mode_0x00cd_0x01=str_constant +hwmon_in.str_cons_0x00cd_0x01=CPLD_03_DFANA_VDD3V3_V + +hwmon_in.mode_0x00cd_0x02=str_constant +hwmon_in.str_cons_0x00cd_0x02=CPLD_03 + +hwmon_in.mode_0x00cd_0x03=constant +hwmon_in.int_cons_0x00cd_0x03=3630 + +hwmon_in.mode_0x00cd_0x05=constant +hwmon_in.int_cons_0x00cd_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00cd_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00cd_0x00=1 + + +# vol sensor 206 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00ce_0x00=config +hwmon_in.src_0x00ce_0x00=logic_file +hwmon_in.int_cons_0x00ce_0x00=0 +hwmon_in.frmt_0x00ce_0x00=num_bytes +hwmon_in.fpath_0x00ce_0x00=/dev/cpld8 +hwmon_in.addr_0x00ce_0x00=0xea +hwmon_in.len_0x00ce_0x00=2 +hwmon_in.int_extra1_0x00ce_0x00=0 +hwmon_in.int_extra2_0x00ce_0x00=2000 +hwmon_in.int_extra3_0x00ce_0x00=1 + +hwmon_in.mode_0x00ce_0x01=str_constant +hwmon_in.str_cons_0x00ce_0x01=CPLD_03_DFANB_VDD3V3_V + +hwmon_in.mode_0x00ce_0x02=str_constant +hwmon_in.str_cons_0x00ce_0x02=CPLD_03 + +hwmon_in.mode_0x00ce_0x03=constant +hwmon_in.int_cons_0x00ce_0x03=3630 + +hwmon_in.mode_0x00ce_0x05=constant +hwmon_in.int_cons_0x00ce_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00ce_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00ce_0x00=1 + + +# vol sensor 207 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00cf_0x00=config +hwmon_in.src_0x00cf_0x00=logic_file +hwmon_in.int_cons_0x00cf_0x00=0 +hwmon_in.frmt_0x00cf_0x00=num_bytes +hwmon_in.fpath_0x00cf_0x00=/dev/cpld8 +hwmon_in.addr_0x00cf_0x00=0xec +hwmon_in.len_0x00cf_0x00=2 +hwmon_in.int_extra1_0x00cf_0x00=0 +hwmon_in.int_extra2_0x00cf_0x00=2000 +hwmon_in.int_extra3_0x00cf_0x00=1 + +hwmon_in.mode_0x00cf_0x01=str_constant +hwmon_in.str_cons_0x00cf_0x01=CPLD_03_DFANC_VDD3V3_V + +hwmon_in.mode_0x00cf_0x02=str_constant +hwmon_in.str_cons_0x00cf_0x02=CPLD_03 + +hwmon_in.mode_0x00cf_0x03=constant +hwmon_in.int_cons_0x00cf_0x03=3630 + +hwmon_in.mode_0x00cf_0x05=constant +hwmon_in.int_cons_0x00cf_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00cf_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00cf_0x00=1 + + +# vol sensor 208 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00d0_0x00=config +hwmon_in.src_0x00d0_0x00=logic_file +hwmon_in.int_cons_0x00d0_0x00=0 +hwmon_in.frmt_0x00d0_0x00=num_bytes +hwmon_in.fpath_0x00d0_0x00=/dev/cpld8 +hwmon_in.addr_0x00d0_0x00=0xee +hwmon_in.len_0x00d0_0x00=2 +hwmon_in.int_extra1_0x00d0_0x00=0 +hwmon_in.int_extra2_0x00d0_0x00=2000 +hwmon_in.int_extra3_0x00d0_0x00=1 + +hwmon_in.mode_0x00d0_0x01=str_constant +hwmon_in.str_cons_0x00d0_0x01=CPLD_03_DFAND_VDD3V3_V + +hwmon_in.mode_0x00d0_0x02=str_constant +hwmon_in.str_cons_0x00d0_0x02=CPLD_03 + +hwmon_in.mode_0x00d0_0x03=constant +hwmon_in.int_cons_0x00d0_0x03=3630 + +hwmon_in.mode_0x00d0_0x05=constant +hwmon_in.int_cons_0x00d0_0x05=2970 + +monitor_flag_hwmon_in.mode_0x00d0_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00d0_0x00=1 + + +# vol sensor 209 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00d1_0x00=config +hwmon_in.src_0x00d1_0x00=logic_file +hwmon_in.int_cons_0x00d1_0x00=0 +hwmon_in.frmt_0x00d1_0x00=num_bytes +hwmon_in.fpath_0x00d1_0x00=/dev/cpld8 +hwmon_in.addr_0x00d1_0x00=0xe0 +hwmon_in.len_0x00d1_0x00=2 +hwmon_in.int_extra1_0x00d1_0x00=0 +hwmon_in.int_extra2_0x00d1_0x00=7096 +hwmon_in.int_extra3_0x00d1_0x00=1 + +hwmon_in.mode_0x00d1_0x01=str_constant +hwmon_in.str_cons_0x00d1_0x01=CPLD_03_DFAN_VDD12V_1_V + +hwmon_in.mode_0x00d1_0x02=str_constant +hwmon_in.str_cons_0x00d1_0x02=CPLD_03 + +hwmon_in.mode_0x00d1_0x03=constant +hwmon_in.int_cons_0x00d1_0x03=13200 + +hwmon_in.mode_0x00d1_0x05=constant +hwmon_in.int_cons_0x00d1_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00d1_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00d1_0x00=1 + + +# vol sensor 210 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00d2_0x00=config +hwmon_in.src_0x00d2_0x00=logic_file +hwmon_in.int_cons_0x00d2_0x00=0 +hwmon_in.frmt_0x00d2_0x00=num_bytes +hwmon_in.fpath_0x00d2_0x00=/dev/cpld8 +hwmon_in.addr_0x00d2_0x00=0xe2 +hwmon_in.len_0x00d2_0x00=2 +hwmon_in.int_extra1_0x00d2_0x00=0 +hwmon_in.int_extra2_0x00d2_0x00=7096 +hwmon_in.int_extra3_0x00d2_0x00=1 + +hwmon_in.mode_0x00d2_0x01=str_constant +hwmon_in.str_cons_0x00d2_0x01=CPLD_03_DFAN_VDD12V_2_V + +hwmon_in.mode_0x00d2_0x02=str_constant +hwmon_in.str_cons_0x00d2_0x02=CPLD_03 + +hwmon_in.mode_0x00d2_0x03=constant +hwmon_in.int_cons_0x00d2_0x03=13200 + +hwmon_in.mode_0x00d2_0x05=constant +hwmon_in.int_cons_0x00d2_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00d2_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00d2_0x00=1 + + +# vol sensor 211 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00d3_0x00=config +hwmon_in.src_0x00d3_0x00=logic_file +hwmon_in.int_cons_0x00d3_0x00=0 +hwmon_in.frmt_0x00d3_0x00=num_bytes +hwmon_in.fpath_0x00d3_0x00=/dev/cpld8 +hwmon_in.addr_0x00d3_0x00=0xe4 +hwmon_in.len_0x00d3_0x00=2 +hwmon_in.int_extra1_0x00d3_0x00=0 +hwmon_in.int_extra2_0x00d3_0x00=7096 +hwmon_in.int_extra3_0x00d3_0x00=1 + +hwmon_in.mode_0x00d3_0x01=str_constant +hwmon_in.str_cons_0x00d3_0x01=CPLD_03_DFAN_VDD12V_3_V + +hwmon_in.mode_0x00d3_0x02=str_constant +hwmon_in.str_cons_0x00d3_0x02=CPLD_03 + +hwmon_in.mode_0x00d3_0x03=constant +hwmon_in.int_cons_0x00d3_0x03=13200 + +hwmon_in.mode_0x00d3_0x05=constant +hwmon_in.int_cons_0x00d3_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00d3_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00d3_0x00=1 + + +# vol sensor 212 alias(0x01) type(0x02) max(0x03) min(0x05) range(0x07) nominal_value(0x08) +# high(0x09) low(0x0a) notice_high(0x0b) notice_low(0x0c) monitor_flag +hwmon_in.mode_0x00d4_0x00=config +hwmon_in.src_0x00d4_0x00=logic_file +hwmon_in.int_cons_0x00d4_0x00=0 +hwmon_in.frmt_0x00d4_0x00=num_bytes +hwmon_in.fpath_0x00d4_0x00=/dev/cpld8 +hwmon_in.addr_0x00d4_0x00=0xe6 +hwmon_in.len_0x00d4_0x00=2 +hwmon_in.int_extra1_0x00d4_0x00=0 +hwmon_in.int_extra2_0x00d4_0x00=7096 +hwmon_in.int_extra3_0x00d4_0x00=1 + +hwmon_in.mode_0x00d4_0x01=str_constant +hwmon_in.str_cons_0x00d4_0x01=CPLD_03_DFAN_VDD12V_4_V + +hwmon_in.mode_0x00d4_0x02=str_constant +hwmon_in.str_cons_0x00d4_0x02=CPLD_03 + +hwmon_in.mode_0x00d4_0x03=constant +hwmon_in.int_cons_0x00d4_0x03=13200 + +hwmon_in.mode_0x00d4_0x05=constant +hwmon_in.int_cons_0x00d4_0x05=10800 + +monitor_flag_hwmon_in.mode_0x00d4_0x00=constant +monitor_flag_hwmon_in.int_cons_0x00d4_0x00=1 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SFF.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SFF.cfg new file mode 100644 index 0000000000..0881381f2b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/SFF.cfg @@ -0,0 +1,6527 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration item: Number of optical modules +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,optical module is 3, minor_dev, 0:does not exist +dev_num_3_0=130 + +# Configuration items: optical module EEPROM sysfs path +# Description: Format eeprom_path_[main_dev]_[index] +# Note: main_dev,optical module is 3, index, Optical module index, starting from 1 + +eeprom_size_3_1=0x8180 +eeprom_size_3_2=0x8180 +eeprom_size_3_3=0x8180 +eeprom_size_3_4=0x8180 +eeprom_size_3_5=0x8180 +eeprom_size_3_6=0x8180 +eeprom_size_3_7=0x8180 +eeprom_size_3_8=0x8180 +eeprom_size_3_9=0x8180 +eeprom_size_3_10=0x8180 +eeprom_size_3_11=0x8180 +eeprom_size_3_12=0x8180 +eeprom_size_3_13=0x8180 +eeprom_size_3_14=0x8180 +eeprom_size_3_15=0x8180 +eeprom_size_3_16=0x8180 +eeprom_size_3_17=0x8180 +eeprom_size_3_18=0x8180 +eeprom_size_3_19=0x8180 +eeprom_size_3_20=0x8180 +eeprom_size_3_21=0x8180 +eeprom_size_3_22=0x8180 +eeprom_size_3_23=0x8180 +eeprom_size_3_24=0x8180 +eeprom_size_3_25=0x8180 +eeprom_size_3_26=0x8180 +eeprom_size_3_27=0x8180 +eeprom_size_3_28=0x8180 +eeprom_size_3_29=0x8180 +eeprom_size_3_30=0x8180 +eeprom_size_3_31=0x8180 +eeprom_size_3_32=0x8180 +eeprom_size_3_33=0x8180 +eeprom_size_3_34=0x8180 +eeprom_size_3_35=0x8180 +eeprom_size_3_36=0x8180 +eeprom_size_3_37=0x8180 +eeprom_size_3_38=0x8180 +eeprom_size_3_39=0x8180 +eeprom_size_3_40=0x8180 +eeprom_size_3_41=0x8180 +eeprom_size_3_42=0x8180 +eeprom_size_3_43=0x8180 +eeprom_size_3_44=0x8180 +eeprom_size_3_45=0x8180 +eeprom_size_3_46=0x8180 +eeprom_size_3_47=0x8180 +eeprom_size_3_48=0x8180 +eeprom_size_3_49=0x8180 +eeprom_size_3_50=0x8180 +eeprom_size_3_51=0x8180 +eeprom_size_3_52=0x8180 +eeprom_size_3_53=0x8180 +eeprom_size_3_54=0x8180 +eeprom_size_3_55=0x8180 +eeprom_size_3_56=0x8180 +eeprom_size_3_57=0x8180 +eeprom_size_3_58=0x8180 +eeprom_size_3_59=0x8180 +eeprom_size_3_60=0x8180 +eeprom_size_3_61=0x8180 +eeprom_size_3_62=0x8180 +eeprom_size_3_63=0x8180 +eeprom_size_3_64=0x8180 +eeprom_size_3_65=0x8180 +eeprom_size_3_66=0x8180 +eeprom_size_3_67=0x8180 +eeprom_size_3_68=0x8180 +eeprom_size_3_69=0x8180 +eeprom_size_3_70=0x8180 +eeprom_size_3_71=0x8180 +eeprom_size_3_72=0x8180 +eeprom_size_3_73=0x8180 +eeprom_size_3_74=0x8180 +eeprom_size_3_75=0x8180 +eeprom_size_3_76=0x8180 +eeprom_size_3_77=0x8180 +eeprom_size_3_78=0x8180 +eeprom_size_3_79=0x8180 +eeprom_size_3_80=0x8180 +eeprom_size_3_81=0x8180 +eeprom_size_3_82=0x8180 +eeprom_size_3_83=0x8180 +eeprom_size_3_84=0x8180 +eeprom_size_3_85=0x8180 +eeprom_size_3_86=0x8180 +eeprom_size_3_87=0x8180 +eeprom_size_3_88=0x8180 +eeprom_size_3_89=0x8180 +eeprom_size_3_90=0x8180 +eeprom_size_3_91=0x8180 +eeprom_size_3_92=0x8180 +eeprom_size_3_93=0x8180 +eeprom_size_3_94=0x8180 +eeprom_size_3_95=0x8180 +eeprom_size_3_96=0x8180 +eeprom_size_3_97=0x8180 +eeprom_size_3_98=0x8180 +eeprom_size_3_99=0x8180 +eeprom_size_3_100=0x8180 +eeprom_size_3_101=0x8180 +eeprom_size_3_102=0x8180 +eeprom_size_3_103=0x8180 +eeprom_size_3_104=0x8180 +eeprom_size_3_105=0x8180 +eeprom_size_3_106=0x8180 +eeprom_size_3_107=0x8180 +eeprom_size_3_108=0x8180 +eeprom_size_3_109=0x8180 +eeprom_size_3_110=0x8180 +eeprom_size_3_111=0x8180 +eeprom_size_3_112=0x8180 +eeprom_size_3_113=0x8180 +eeprom_size_3_114=0x8180 +eeprom_size_3_115=0x8180 +eeprom_size_3_116=0x8180 +eeprom_size_3_117=0x8180 +eeprom_size_3_118=0x8180 +eeprom_size_3_119=0x8180 +eeprom_size_3_120=0x8180 +eeprom_size_3_121=0x8180 +eeprom_size_3_122=0x8180 +eeprom_size_3_123=0x8180 +eeprom_size_3_124=0x8180 +eeprom_size_3_125=0x8180 +eeprom_size_3_126=0x8180 +eeprom_size_3_127=0x8180 +eeprom_size_3_128=0x8180 +eeprom_size_3_129=0x8180 +eeprom_size_3_130=0x8180 + +eeprom_path_3_1=/sys/bus/i2c/devices/201-0050/eeprom +eeprom_path_3_2=/sys/bus/i2c/devices/202-0050/eeprom +eeprom_path_3_3=/sys/bus/i2c/devices/203-0050/eeprom +eeprom_path_3_4=/sys/bus/i2c/devices/204-0050/eeprom +eeprom_path_3_5=/sys/bus/i2c/devices/205-0050/eeprom +eeprom_path_3_6=/sys/bus/i2c/devices/206-0050/eeprom +eeprom_path_3_7=/sys/bus/i2c/devices/207-0050/eeprom +eeprom_path_3_8=/sys/bus/i2c/devices/208-0050/eeprom +eeprom_path_3_9=/sys/bus/i2c/devices/209-0050/eeprom +eeprom_path_3_10=/sys/bus/i2c/devices/210-0050/eeprom +eeprom_path_3_11=/sys/bus/i2c/devices/211-0050/eeprom +eeprom_path_3_12=/sys/bus/i2c/devices/212-0050/eeprom +eeprom_path_3_13=/sys/bus/i2c/devices/213-0050/eeprom +eeprom_path_3_14=/sys/bus/i2c/devices/214-0050/eeprom +eeprom_path_3_15=/sys/bus/i2c/devices/215-0050/eeprom +eeprom_path_3_16=/sys/bus/i2c/devices/216-0050/eeprom +eeprom_path_3_17=/sys/bus/i2c/devices/217-0050/eeprom +eeprom_path_3_18=/sys/bus/i2c/devices/218-0050/eeprom +eeprom_path_3_19=/sys/bus/i2c/devices/219-0050/eeprom +eeprom_path_3_20=/sys/bus/i2c/devices/220-0050/eeprom +eeprom_path_3_21=/sys/bus/i2c/devices/221-0050/eeprom +eeprom_path_3_22=/sys/bus/i2c/devices/222-0050/eeprom +eeprom_path_3_23=/sys/bus/i2c/devices/223-0050/eeprom +eeprom_path_3_24=/sys/bus/i2c/devices/224-0050/eeprom +eeprom_path_3_25=/sys/bus/i2c/devices/225-0050/eeprom +eeprom_path_3_26=/sys/bus/i2c/devices/226-0050/eeprom +eeprom_path_3_27=/sys/bus/i2c/devices/227-0050/eeprom +eeprom_path_3_28=/sys/bus/i2c/devices/228-0050/eeprom +eeprom_path_3_29=/sys/bus/i2c/devices/229-0050/eeprom +eeprom_path_3_30=/sys/bus/i2c/devices/230-0050/eeprom +eeprom_path_3_31=/sys/bus/i2c/devices/231-0050/eeprom +eeprom_path_3_32=/sys/bus/i2c/devices/232-0050/eeprom +eeprom_path_3_33=/sys/bus/i2c/devices/233-0050/eeprom +eeprom_path_3_34=/sys/bus/i2c/devices/234-0050/eeprom +eeprom_path_3_35=/sys/bus/i2c/devices/235-0050/eeprom +eeprom_path_3_36=/sys/bus/i2c/devices/236-0050/eeprom +eeprom_path_3_37=/sys/bus/i2c/devices/237-0050/eeprom +eeprom_path_3_38=/sys/bus/i2c/devices/238-0050/eeprom +eeprom_path_3_39=/sys/bus/i2c/devices/239-0050/eeprom +eeprom_path_3_40=/sys/bus/i2c/devices/240-0050/eeprom +eeprom_path_3_41=/sys/bus/i2c/devices/241-0050/eeprom +eeprom_path_3_42=/sys/bus/i2c/devices/242-0050/eeprom +eeprom_path_3_43=/sys/bus/i2c/devices/243-0050/eeprom +eeprom_path_3_44=/sys/bus/i2c/devices/244-0050/eeprom +eeprom_path_3_45=/sys/bus/i2c/devices/245-0050/eeprom +eeprom_path_3_46=/sys/bus/i2c/devices/246-0050/eeprom +eeprom_path_3_47=/sys/bus/i2c/devices/247-0050/eeprom +eeprom_path_3_48=/sys/bus/i2c/devices/248-0050/eeprom +eeprom_path_3_49=/sys/bus/i2c/devices/249-0050/eeprom +eeprom_path_3_50=/sys/bus/i2c/devices/250-0050/eeprom +eeprom_path_3_51=/sys/bus/i2c/devices/251-0050/eeprom +eeprom_path_3_52=/sys/bus/i2c/devices/252-0050/eeprom +eeprom_path_3_53=/sys/bus/i2c/devices/253-0050/eeprom +eeprom_path_3_54=/sys/bus/i2c/devices/254-0050/eeprom +eeprom_path_3_55=/sys/bus/i2c/devices/255-0050/eeprom +eeprom_path_3_56=/sys/bus/i2c/devices/256-0050/eeprom +eeprom_path_3_57=/sys/bus/i2c/devices/257-0050/eeprom +eeprom_path_3_58=/sys/bus/i2c/devices/258-0050/eeprom +eeprom_path_3_59=/sys/bus/i2c/devices/259-0050/eeprom +eeprom_path_3_60=/sys/bus/i2c/devices/260-0050/eeprom +eeprom_path_3_61=/sys/bus/i2c/devices/261-0050/eeprom +eeprom_path_3_62=/sys/bus/i2c/devices/262-0050/eeprom +eeprom_path_3_63=/sys/bus/i2c/devices/263-0050/eeprom +eeprom_path_3_64=/sys/bus/i2c/devices/264-0050/eeprom +eeprom_path_3_65=/sys/bus/i2c/devices/265-0050/eeprom +eeprom_path_3_66=/sys/bus/i2c/devices/266-0050/eeprom +eeprom_path_3_67=/sys/bus/i2c/devices/267-0050/eeprom +eeprom_path_3_68=/sys/bus/i2c/devices/268-0050/eeprom +eeprom_path_3_69=/sys/bus/i2c/devices/269-0050/eeprom +eeprom_path_3_70=/sys/bus/i2c/devices/270-0050/eeprom +eeprom_path_3_71=/sys/bus/i2c/devices/271-0050/eeprom +eeprom_path_3_72=/sys/bus/i2c/devices/272-0050/eeprom +eeprom_path_3_73=/sys/bus/i2c/devices/273-0050/eeprom +eeprom_path_3_74=/sys/bus/i2c/devices/274-0050/eeprom +eeprom_path_3_75=/sys/bus/i2c/devices/275-0050/eeprom +eeprom_path_3_76=/sys/bus/i2c/devices/276-0050/eeprom +eeprom_path_3_77=/sys/bus/i2c/devices/277-0050/eeprom +eeprom_path_3_78=/sys/bus/i2c/devices/278-0050/eeprom +eeprom_path_3_79=/sys/bus/i2c/devices/279-0050/eeprom +eeprom_path_3_80=/sys/bus/i2c/devices/280-0050/eeprom +eeprom_path_3_81=/sys/bus/i2c/devices/281-0050/eeprom +eeprom_path_3_82=/sys/bus/i2c/devices/282-0050/eeprom +eeprom_path_3_83=/sys/bus/i2c/devices/283-0050/eeprom +eeprom_path_3_84=/sys/bus/i2c/devices/284-0050/eeprom +eeprom_path_3_85=/sys/bus/i2c/devices/285-0050/eeprom +eeprom_path_3_86=/sys/bus/i2c/devices/286-0050/eeprom +eeprom_path_3_87=/sys/bus/i2c/devices/287-0050/eeprom +eeprom_path_3_88=/sys/bus/i2c/devices/288-0050/eeprom +eeprom_path_3_89=/sys/bus/i2c/devices/289-0050/eeprom +eeprom_path_3_90=/sys/bus/i2c/devices/290-0050/eeprom +eeprom_path_3_91=/sys/bus/i2c/devices/291-0050/eeprom +eeprom_path_3_92=/sys/bus/i2c/devices/292-0050/eeprom +eeprom_path_3_93=/sys/bus/i2c/devices/293-0050/eeprom +eeprom_path_3_94=/sys/bus/i2c/devices/294-0050/eeprom +eeprom_path_3_95=/sys/bus/i2c/devices/295-0050/eeprom +eeprom_path_3_96=/sys/bus/i2c/devices/296-0050/eeprom +eeprom_path_3_97=/sys/bus/i2c/devices/297-0050/eeprom +eeprom_path_3_98=/sys/bus/i2c/devices/298-0050/eeprom +eeprom_path_3_99=/sys/bus/i2c/devices/299-0050/eeprom +eeprom_path_3_100=/sys/bus/i2c/devices/300-0050/eeprom +eeprom_path_3_101=/sys/bus/i2c/devices/301-0050/eeprom +eeprom_path_3_102=/sys/bus/i2c/devices/302-0050/eeprom +eeprom_path_3_103=/sys/bus/i2c/devices/303-0050/eeprom +eeprom_path_3_104=/sys/bus/i2c/devices/304-0050/eeprom +eeprom_path_3_105=/sys/bus/i2c/devices/305-0050/eeprom +eeprom_path_3_106=/sys/bus/i2c/devices/306-0050/eeprom +eeprom_path_3_107=/sys/bus/i2c/devices/307-0050/eeprom +eeprom_path_3_108=/sys/bus/i2c/devices/308-0050/eeprom +eeprom_path_3_109=/sys/bus/i2c/devices/309-0050/eeprom +eeprom_path_3_110=/sys/bus/i2c/devices/310-0050/eeprom +eeprom_path_3_111=/sys/bus/i2c/devices/311-0050/eeprom +eeprom_path_3_112=/sys/bus/i2c/devices/312-0050/eeprom +eeprom_path_3_113=/sys/bus/i2c/devices/313-0050/eeprom +eeprom_path_3_114=/sys/bus/i2c/devices/314-0050/eeprom +eeprom_path_3_115=/sys/bus/i2c/devices/315-0050/eeprom +eeprom_path_3_116=/sys/bus/i2c/devices/316-0050/eeprom +eeprom_path_3_117=/sys/bus/i2c/devices/317-0050/eeprom +eeprom_path_3_118=/sys/bus/i2c/devices/318-0050/eeprom +eeprom_path_3_119=/sys/bus/i2c/devices/319-0050/eeprom +eeprom_path_3_120=/sys/bus/i2c/devices/320-0050/eeprom +eeprom_path_3_121=/sys/bus/i2c/devices/321-0050/eeprom +eeprom_path_3_122=/sys/bus/i2c/devices/322-0050/eeprom +eeprom_path_3_123=/sys/bus/i2c/devices/323-0050/eeprom +eeprom_path_3_124=/sys/bus/i2c/devices/324-0050/eeprom +eeprom_path_3_125=/sys/bus/i2c/devices/325-0050/eeprom +eeprom_path_3_126=/sys/bus/i2c/devices/326-0050/eeprom +eeprom_path_3_127=/sys/bus/i2c/devices/327-0050/eeprom +eeprom_path_3_128=/sys/bus/i2c/devices/328-0050/eeprom +eeprom_path_3_129=/sys/bus/i2c/devices/329-0050/eeprom +eeprom_path_3_130=/sys/bus/i2c/devices/330-0050/eeprom + +# 1:SFP 2:QSFP, 3:CMIS(QSFP-DD), 4:rj45 +sff_cage_type_1=3 +sff_cage_type_2=3 +sff_cage_type_3=3 +sff_cage_type_4=3 +sff_cage_type_5=3 +sff_cage_type_6=3 +sff_cage_type_7=3 +sff_cage_type_8=3 +sff_cage_type_9=3 +sff_cage_type_10=3 +sff_cage_type_11=3 +sff_cage_type_12=3 +sff_cage_type_13=3 +sff_cage_type_14=3 +sff_cage_type_15=3 +sff_cage_type_16=3 +sff_cage_type_17=3 +sff_cage_type_18=3 +sff_cage_type_19=3 +sff_cage_type_20=3 +sff_cage_type_21=3 +sff_cage_type_22=3 +sff_cage_type_23=3 +sff_cage_type_24=3 +sff_cage_type_25=3 +sff_cage_type_26=3 +sff_cage_type_27=3 +sff_cage_type_28=3 +sff_cage_type_29=3 +sff_cage_type_30=3 +sff_cage_type_31=3 +sff_cage_type_32=3 +sff_cage_type_33=3 +sff_cage_type_34=3 +sff_cage_type_35=3 +sff_cage_type_36=3 +sff_cage_type_37=3 +sff_cage_type_38=3 +sff_cage_type_39=3 +sff_cage_type_40=3 +sff_cage_type_41=3 +sff_cage_type_42=3 +sff_cage_type_43=3 +sff_cage_type_44=3 +sff_cage_type_45=3 +sff_cage_type_46=3 +sff_cage_type_47=3 +sff_cage_type_48=3 +sff_cage_type_49=3 +sff_cage_type_50=3 +sff_cage_type_51=3 +sff_cage_type_52=3 +sff_cage_type_53=3 +sff_cage_type_54=3 +sff_cage_type_55=3 +sff_cage_type_56=3 +sff_cage_type_57=3 +sff_cage_type_58=3 +sff_cage_type_59=3 +sff_cage_type_60=3 +sff_cage_type_61=3 +sff_cage_type_62=3 +sff_cage_type_63=3 +sff_cage_type_64=3 +sff_cage_type_65=3 +sff_cage_type_66=3 +sff_cage_type_67=3 +sff_cage_type_68=3 +sff_cage_type_69=3 +sff_cage_type_70=3 +sff_cage_type_71=3 +sff_cage_type_72=3 +sff_cage_type_73=3 +sff_cage_type_74=3 +sff_cage_type_75=3 +sff_cage_type_76=3 +sff_cage_type_77=3 +sff_cage_type_78=3 +sff_cage_type_79=3 +sff_cage_type_80=3 +sff_cage_type_81=3 +sff_cage_type_82=3 +sff_cage_type_83=3 +sff_cage_type_84=3 +sff_cage_type_85=3 +sff_cage_type_86=3 +sff_cage_type_87=3 +sff_cage_type_88=3 +sff_cage_type_89=3 +sff_cage_type_90=3 +sff_cage_type_91=3 +sff_cage_type_92=3 +sff_cage_type_93=3 +sff_cage_type_94=3 +sff_cage_type_95=3 +sff_cage_type_96=3 +sff_cage_type_97=3 +sff_cage_type_98=3 +sff_cage_type_99=3 +sff_cage_type_100=3 +sff_cage_type_101=3 +sff_cage_type_102=3 +sff_cage_type_103=3 +sff_cage_type_104=3 +sff_cage_type_105=3 +sff_cage_type_106=3 +sff_cage_type_107=3 +sff_cage_type_108=3 +sff_cage_type_109=3 +sff_cage_type_110=3 +sff_cage_type_111=3 +sff_cage_type_112=3 +sff_cage_type_113=3 +sff_cage_type_114=3 +sff_cage_type_115=3 +sff_cage_type_116=3 +sff_cage_type_117=3 +sff_cage_type_118=3 +sff_cage_type_119=3 +sff_cage_type_120=3 +sff_cage_type_121=3 +sff_cage_type_122=3 +sff_cage_type_123=3 +sff_cage_type_124=3 +sff_cage_type_125=3 +sff_cage_type_126=3 +sff_cage_type_127=3 +sff_cage_type_128=3 +sff_cage_type_129=2 +sff_cage_type_130=1 + +# Configuration items: Optical module CPLD register +# Description: Format sff_cpld_reg_[sff_index]_[cpld_reg] +# Note: sff_index indicates the optical module number, starting from 1. 0 indicates that the power_on register is useful +# cpld_reg 1:power_on 2:tx_fault, 3:tx_dis 4:reserve 5:rx_los +# 6:reset 7:lpmode 8:module_present 9:interrupt + +# 800G module reset signal +reg_key_0x0306_0x00=0x01 +reg_key_0x0306_0x01=0x00 + +sysfs_decode_0x0306_0x00=1 +sysfs_decode_0x0306_0x01=0 + +sff_cpld_reg.mode_1_6=config +sff_cpld_reg.src_1_6=logic_file +sff_cpld_reg.frmt_1_6=byte +sff_cpld_reg.pola_1_6=positive +sff_cpld_reg.fpath_1_6=/dev/cpld5 +sff_cpld_reg.addr_1_6=0x50 +sff_cpld_reg.len_1_6=1 +sff_cpld_reg.val_type_1_6=nega_key + +sff_cpld_reg.mode_2_6=config +sff_cpld_reg.src_2_6=logic_file +sff_cpld_reg.frmt_2_6=byte +sff_cpld_reg.pola_2_6=positive +sff_cpld_reg.fpath_2_6=/dev/cpld5 +sff_cpld_reg.addr_2_6=0x51 +sff_cpld_reg.len_2_6=1 +sff_cpld_reg.val_type_2_6=nega_key + +sff_cpld_reg.mode_3_6=config +sff_cpld_reg.src_3_6=logic_file +sff_cpld_reg.frmt_3_6=byte +sff_cpld_reg.pola_3_6=positive +sff_cpld_reg.fpath_3_6=/dev/cpld5 +sff_cpld_reg.addr_3_6=0x52 +sff_cpld_reg.len_3_6=1 +sff_cpld_reg.val_type_3_6=nega_key + +sff_cpld_reg.mode_4_6=config +sff_cpld_reg.src_4_6=logic_file +sff_cpld_reg.frmt_4_6=byte +sff_cpld_reg.pola_4_6=positive +sff_cpld_reg.fpath_4_6=/dev/cpld5 +sff_cpld_reg.addr_4_6=0x53 +sff_cpld_reg.len_4_6=1 +sff_cpld_reg.val_type_4_6=nega_key + +sff_cpld_reg.mode_5_6=config +sff_cpld_reg.src_5_6=logic_file +sff_cpld_reg.frmt_5_6=byte +sff_cpld_reg.pola_5_6=positive +sff_cpld_reg.fpath_5_6=/dev/cpld5 +sff_cpld_reg.addr_5_6=0x54 +sff_cpld_reg.len_5_6=1 +sff_cpld_reg.val_type_5_6=nega_key + +sff_cpld_reg.mode_6_6=config +sff_cpld_reg.src_6_6=logic_file +sff_cpld_reg.frmt_6_6=byte +sff_cpld_reg.pola_6_6=positive +sff_cpld_reg.fpath_6_6=/dev/cpld5 +sff_cpld_reg.addr_6_6=0x55 +sff_cpld_reg.len_6_6=1 +sff_cpld_reg.val_type_6_6=nega_key + +sff_cpld_reg.mode_7_6=config +sff_cpld_reg.src_7_6=logic_file +sff_cpld_reg.frmt_7_6=byte +sff_cpld_reg.pola_7_6=positive +sff_cpld_reg.fpath_7_6=/dev/cpld5 +sff_cpld_reg.addr_7_6=0x56 +sff_cpld_reg.len_7_6=1 +sff_cpld_reg.val_type_7_6=nega_key + +sff_cpld_reg.mode_8_6=config +sff_cpld_reg.src_8_6=logic_file +sff_cpld_reg.frmt_8_6=byte +sff_cpld_reg.pola_8_6=positive +sff_cpld_reg.fpath_8_6=/dev/cpld5 +sff_cpld_reg.addr_8_6=0x57 +sff_cpld_reg.len_8_6=1 +sff_cpld_reg.val_type_8_6=nega_key + +sff_cpld_reg.mode_9_6=config +sff_cpld_reg.src_9_6=logic_file +sff_cpld_reg.frmt_9_6=byte +sff_cpld_reg.pola_9_6=positive +sff_cpld_reg.fpath_9_6=/dev/cpld5 +sff_cpld_reg.addr_9_6=0x58 +sff_cpld_reg.len_9_6=1 +sff_cpld_reg.val_type_9_6=nega_key + +sff_cpld_reg.mode_10_6=config +sff_cpld_reg.src_10_6=logic_file +sff_cpld_reg.frmt_10_6=byte +sff_cpld_reg.pola_10_6=positive +sff_cpld_reg.fpath_10_6=/dev/cpld5 +sff_cpld_reg.addr_10_6=0x59 +sff_cpld_reg.len_10_6=1 +sff_cpld_reg.val_type_10_6=nega_key + +sff_cpld_reg.mode_11_6=config +sff_cpld_reg.src_11_6=logic_file +sff_cpld_reg.frmt_11_6=byte +sff_cpld_reg.pola_11_6=positive +sff_cpld_reg.fpath_11_6=/dev/cpld5 +sff_cpld_reg.addr_11_6=0x5a +sff_cpld_reg.len_11_6=1 +sff_cpld_reg.val_type_11_6=nega_key + +sff_cpld_reg.mode_12_6=config +sff_cpld_reg.src_12_6=logic_file +sff_cpld_reg.frmt_12_6=byte +sff_cpld_reg.pola_12_6=positive +sff_cpld_reg.fpath_12_6=/dev/cpld5 +sff_cpld_reg.addr_12_6=0x5b +sff_cpld_reg.len_12_6=1 +sff_cpld_reg.val_type_12_6=nega_key + +sff_cpld_reg.mode_13_6=config +sff_cpld_reg.src_13_6=logic_file +sff_cpld_reg.frmt_13_6=byte +sff_cpld_reg.pola_13_6=positive +sff_cpld_reg.fpath_13_6=/dev/cpld5 +sff_cpld_reg.addr_13_6=0x5c +sff_cpld_reg.len_13_6=1 +sff_cpld_reg.val_type_13_6=nega_key + +sff_cpld_reg.mode_14_6=config +sff_cpld_reg.src_14_6=logic_file +sff_cpld_reg.frmt_14_6=byte +sff_cpld_reg.pola_14_6=positive +sff_cpld_reg.fpath_14_6=/dev/cpld5 +sff_cpld_reg.addr_14_6=0x5d +sff_cpld_reg.len_14_6=1 +sff_cpld_reg.val_type_14_6=nega_key + +sff_cpld_reg.mode_15_6=config +sff_cpld_reg.src_15_6=logic_file +sff_cpld_reg.frmt_15_6=byte +sff_cpld_reg.pola_15_6=positive +sff_cpld_reg.fpath_15_6=/dev/cpld5 +sff_cpld_reg.addr_15_6=0x5e +sff_cpld_reg.len_15_6=1 +sff_cpld_reg.val_type_15_6=nega_key + +sff_cpld_reg.mode_16_6=config +sff_cpld_reg.src_16_6=logic_file +sff_cpld_reg.frmt_16_6=byte +sff_cpld_reg.pola_16_6=positive +sff_cpld_reg.fpath_16_6=/dev/cpld5 +sff_cpld_reg.addr_16_6=0x5f +sff_cpld_reg.len_16_6=1 +sff_cpld_reg.val_type_16_6=nega_key + +sff_cpld_reg.mode_17_6=config +sff_cpld_reg.src_17_6=logic_file +sff_cpld_reg.frmt_17_6=byte +sff_cpld_reg.pola_17_6=positive +sff_cpld_reg.fpath_17_6=/dev/cpld5 +sff_cpld_reg.addr_17_6=0x60 +sff_cpld_reg.len_17_6=1 +sff_cpld_reg.val_type_17_6=nega_key + +sff_cpld_reg.mode_18_6=config +sff_cpld_reg.src_18_6=logic_file +sff_cpld_reg.frmt_18_6=byte +sff_cpld_reg.pola_18_6=positive +sff_cpld_reg.fpath_18_6=/dev/cpld5 +sff_cpld_reg.addr_18_6=0x61 +sff_cpld_reg.len_18_6=1 +sff_cpld_reg.val_type_18_6=nega_key + +sff_cpld_reg.mode_19_6=config +sff_cpld_reg.src_19_6=logic_file +sff_cpld_reg.frmt_19_6=byte +sff_cpld_reg.pola_19_6=positive +sff_cpld_reg.fpath_19_6=/dev/cpld5 +sff_cpld_reg.addr_19_6=0x62 +sff_cpld_reg.len_19_6=1 +sff_cpld_reg.val_type_19_6=nega_key + +sff_cpld_reg.mode_20_6=config +sff_cpld_reg.src_20_6=logic_file +sff_cpld_reg.frmt_20_6=byte +sff_cpld_reg.pola_20_6=positive +sff_cpld_reg.fpath_20_6=/dev/cpld5 +sff_cpld_reg.addr_20_6=0x63 +sff_cpld_reg.len_20_6=1 +sff_cpld_reg.val_type_20_6=nega_key + +sff_cpld_reg.mode_21_6=config +sff_cpld_reg.src_21_6=logic_file +sff_cpld_reg.frmt_21_6=byte +sff_cpld_reg.pola_21_6=positive +sff_cpld_reg.fpath_21_6=/dev/cpld5 +sff_cpld_reg.addr_21_6=0x64 +sff_cpld_reg.len_21_6=1 +sff_cpld_reg.val_type_21_6=nega_key + +sff_cpld_reg.mode_22_6=config +sff_cpld_reg.src_22_6=logic_file +sff_cpld_reg.frmt_22_6=byte +sff_cpld_reg.pola_22_6=positive +sff_cpld_reg.fpath_22_6=/dev/cpld5 +sff_cpld_reg.addr_22_6=0x65 +sff_cpld_reg.len_22_6=1 +sff_cpld_reg.val_type_22_6=nega_key + +sff_cpld_reg.mode_23_6=config +sff_cpld_reg.src_23_6=logic_file +sff_cpld_reg.frmt_23_6=byte +sff_cpld_reg.pola_23_6=positive +sff_cpld_reg.fpath_23_6=/dev/cpld5 +sff_cpld_reg.addr_23_6=0x66 +sff_cpld_reg.len_23_6=1 +sff_cpld_reg.val_type_23_6=nega_key + +sff_cpld_reg.mode_24_6=config +sff_cpld_reg.src_24_6=logic_file +sff_cpld_reg.frmt_24_6=byte +sff_cpld_reg.pola_24_6=positive +sff_cpld_reg.fpath_24_6=/dev/cpld5 +sff_cpld_reg.addr_24_6=0x67 +sff_cpld_reg.len_24_6=1 +sff_cpld_reg.val_type_24_6=nega_key + +sff_cpld_reg.mode_25_6=config +sff_cpld_reg.src_25_6=logic_file +sff_cpld_reg.frmt_25_6=byte +sff_cpld_reg.pola_25_6=positive +sff_cpld_reg.fpath_25_6=/dev/cpld5 +sff_cpld_reg.addr_25_6=0x68 +sff_cpld_reg.len_25_6=1 +sff_cpld_reg.val_type_25_6=nega_key + +sff_cpld_reg.mode_26_6=config +sff_cpld_reg.src_26_6=logic_file +sff_cpld_reg.frmt_26_6=byte +sff_cpld_reg.pola_26_6=positive +sff_cpld_reg.fpath_26_6=/dev/cpld5 +sff_cpld_reg.addr_26_6=0x69 +sff_cpld_reg.len_26_6=1 +sff_cpld_reg.val_type_26_6=nega_key + +sff_cpld_reg.mode_27_6=config +sff_cpld_reg.src_27_6=logic_file +sff_cpld_reg.frmt_27_6=byte +sff_cpld_reg.pola_27_6=positive +sff_cpld_reg.fpath_27_6=/dev/cpld5 +sff_cpld_reg.addr_27_6=0x6a +sff_cpld_reg.len_27_6=1 +sff_cpld_reg.val_type_27_6=nega_key + +sff_cpld_reg.mode_28_6=config +sff_cpld_reg.src_28_6=logic_file +sff_cpld_reg.frmt_28_6=byte +sff_cpld_reg.pola_28_6=positive +sff_cpld_reg.fpath_28_6=/dev/cpld5 +sff_cpld_reg.addr_28_6=0x6b +sff_cpld_reg.len_28_6=1 +sff_cpld_reg.val_type_28_6=nega_key + +sff_cpld_reg.mode_29_6=config +sff_cpld_reg.src_29_6=logic_file +sff_cpld_reg.frmt_29_6=byte +sff_cpld_reg.pola_29_6=positive +sff_cpld_reg.fpath_29_6=/dev/cpld5 +sff_cpld_reg.addr_29_6=0x6c +sff_cpld_reg.len_29_6=1 +sff_cpld_reg.val_type_29_6=nega_key + +sff_cpld_reg.mode_30_6=config +sff_cpld_reg.src_30_6=logic_file +sff_cpld_reg.frmt_30_6=byte +sff_cpld_reg.pola_30_6=positive +sff_cpld_reg.fpath_30_6=/dev/cpld5 +sff_cpld_reg.addr_30_6=0x6d +sff_cpld_reg.len_30_6=1 +sff_cpld_reg.val_type_30_6=nega_key + +sff_cpld_reg.mode_31_6=config +sff_cpld_reg.src_31_6=logic_file +sff_cpld_reg.frmt_31_6=byte +sff_cpld_reg.pola_31_6=positive +sff_cpld_reg.fpath_31_6=/dev/cpld5 +sff_cpld_reg.addr_31_6=0x6e +sff_cpld_reg.len_31_6=1 +sff_cpld_reg.val_type_31_6=nega_key + +sff_cpld_reg.mode_32_6=config +sff_cpld_reg.src_32_6=logic_file +sff_cpld_reg.frmt_32_6=byte +sff_cpld_reg.pola_32_6=positive +sff_cpld_reg.fpath_32_6=/dev/cpld5 +sff_cpld_reg.addr_32_6=0x6f +sff_cpld_reg.len_32_6=1 +sff_cpld_reg.val_type_32_6=nega_key + +sff_cpld_reg.mode_33_6=config +sff_cpld_reg.src_33_6=logic_file +sff_cpld_reg.frmt_33_6=byte +sff_cpld_reg.pola_33_6=positive +sff_cpld_reg.fpath_33_6=/dev/cpld2 +sff_cpld_reg.addr_33_6=0x60 +sff_cpld_reg.len_33_6=1 +sff_cpld_reg.val_type_33_6=nega_key + +sff_cpld_reg.mode_34_6=config +sff_cpld_reg.src_34_6=logic_file +sff_cpld_reg.frmt_34_6=byte +sff_cpld_reg.pola_34_6=positive +sff_cpld_reg.fpath_34_6=/dev/cpld2 +sff_cpld_reg.addr_34_6=0x61 +sff_cpld_reg.len_34_6=1 +sff_cpld_reg.val_type_34_6=nega_key + +sff_cpld_reg.mode_35_6=config +sff_cpld_reg.src_35_6=logic_file +sff_cpld_reg.frmt_35_6=byte +sff_cpld_reg.pola_35_6=positive +sff_cpld_reg.fpath_35_6=/dev/cpld2 +sff_cpld_reg.addr_35_6=0x62 +sff_cpld_reg.len_35_6=1 +sff_cpld_reg.val_type_35_6=nega_key + +sff_cpld_reg.mode_36_6=config +sff_cpld_reg.src_36_6=logic_file +sff_cpld_reg.frmt_36_6=byte +sff_cpld_reg.pola_36_6=positive +sff_cpld_reg.fpath_36_6=/dev/cpld2 +sff_cpld_reg.addr_36_6=0x63 +sff_cpld_reg.len_36_6=1 +sff_cpld_reg.val_type_36_6=nega_key + +sff_cpld_reg.mode_37_6=config +sff_cpld_reg.src_37_6=logic_file +sff_cpld_reg.frmt_37_6=byte +sff_cpld_reg.pola_37_6=positive +sff_cpld_reg.fpath_37_6=/dev/cpld2 +sff_cpld_reg.addr_37_6=0x64 +sff_cpld_reg.len_37_6=1 +sff_cpld_reg.val_type_37_6=nega_key + +sff_cpld_reg.mode_38_6=config +sff_cpld_reg.src_38_6=logic_file +sff_cpld_reg.frmt_38_6=byte +sff_cpld_reg.pola_38_6=positive +sff_cpld_reg.fpath_38_6=/dev/cpld2 +sff_cpld_reg.addr_38_6=0x65 +sff_cpld_reg.len_38_6=1 +sff_cpld_reg.val_type_38_6=nega_key + +sff_cpld_reg.mode_39_6=config +sff_cpld_reg.src_39_6=logic_file +sff_cpld_reg.frmt_39_6=byte +sff_cpld_reg.pola_39_6=positive +sff_cpld_reg.fpath_39_6=/dev/cpld2 +sff_cpld_reg.addr_39_6=0x66 +sff_cpld_reg.len_39_6=1 +sff_cpld_reg.val_type_39_6=nega_key + +sff_cpld_reg.mode_40_6=config +sff_cpld_reg.src_40_6=logic_file +sff_cpld_reg.frmt_40_6=byte +sff_cpld_reg.pola_40_6=positive +sff_cpld_reg.fpath_40_6=/dev/cpld2 +sff_cpld_reg.addr_40_6=0x67 +sff_cpld_reg.len_40_6=1 +sff_cpld_reg.val_type_40_6=nega_key + +sff_cpld_reg.mode_41_6=config +sff_cpld_reg.src_41_6=logic_file +sff_cpld_reg.frmt_41_6=byte +sff_cpld_reg.pola_41_6=positive +sff_cpld_reg.fpath_41_6=/dev/cpld2 +sff_cpld_reg.addr_41_6=0x68 +sff_cpld_reg.len_41_6=1 +sff_cpld_reg.val_type_41_6=nega_key + +sff_cpld_reg.mode_42_6=config +sff_cpld_reg.src_42_6=logic_file +sff_cpld_reg.frmt_42_6=byte +sff_cpld_reg.pola_42_6=positive +sff_cpld_reg.fpath_42_6=/dev/cpld2 +sff_cpld_reg.addr_42_6=0x69 +sff_cpld_reg.len_42_6=1 +sff_cpld_reg.val_type_42_6=nega_key + +sff_cpld_reg.mode_43_6=config +sff_cpld_reg.src_43_6=logic_file +sff_cpld_reg.frmt_43_6=byte +sff_cpld_reg.pola_43_6=positive +sff_cpld_reg.fpath_43_6=/dev/cpld3 +sff_cpld_reg.addr_43_6=0x50 +sff_cpld_reg.len_43_6=1 +sff_cpld_reg.val_type_43_6=nega_key + +sff_cpld_reg.mode_44_6=config +sff_cpld_reg.src_44_6=logic_file +sff_cpld_reg.frmt_44_6=byte +sff_cpld_reg.pola_44_6=positive +sff_cpld_reg.fpath_44_6=/dev/cpld3 +sff_cpld_reg.addr_44_6=0x51 +sff_cpld_reg.len_44_6=1 +sff_cpld_reg.val_type_44_6=nega_key + +sff_cpld_reg.mode_45_6=config +sff_cpld_reg.src_45_6=logic_file +sff_cpld_reg.frmt_45_6=byte +sff_cpld_reg.pola_45_6=positive +sff_cpld_reg.fpath_45_6=/dev/cpld3 +sff_cpld_reg.addr_45_6=0x52 +sff_cpld_reg.len_45_6=1 +sff_cpld_reg.val_type_45_6=nega_key + +sff_cpld_reg.mode_46_6=config +sff_cpld_reg.src_46_6=logic_file +sff_cpld_reg.frmt_46_6=byte +sff_cpld_reg.pola_46_6=positive +sff_cpld_reg.fpath_46_6=/dev/cpld3 +sff_cpld_reg.addr_46_6=0x53 +sff_cpld_reg.len_46_6=1 +sff_cpld_reg.val_type_46_6=nega_key + +sff_cpld_reg.mode_47_6=config +sff_cpld_reg.src_47_6=logic_file +sff_cpld_reg.frmt_47_6=byte +sff_cpld_reg.pola_47_6=positive +sff_cpld_reg.fpath_47_6=/dev/cpld3 +sff_cpld_reg.addr_47_6=0x54 +sff_cpld_reg.len_47_6=1 +sff_cpld_reg.val_type_47_6=nega_key + +sff_cpld_reg.mode_48_6=config +sff_cpld_reg.src_48_6=logic_file +sff_cpld_reg.frmt_48_6=byte +sff_cpld_reg.pola_48_6=positive +sff_cpld_reg.fpath_48_6=/dev/cpld3 +sff_cpld_reg.addr_48_6=0x55 +sff_cpld_reg.len_48_6=1 +sff_cpld_reg.val_type_48_6=nega_key + +sff_cpld_reg.mode_49_6=config +sff_cpld_reg.src_49_6=logic_file +sff_cpld_reg.frmt_49_6=byte +sff_cpld_reg.pola_49_6=positive +sff_cpld_reg.fpath_49_6=/dev/cpld3 +sff_cpld_reg.addr_49_6=0x56 +sff_cpld_reg.len_49_6=1 +sff_cpld_reg.val_type_49_6=nega_key + +sff_cpld_reg.mode_50_6=config +sff_cpld_reg.src_50_6=logic_file +sff_cpld_reg.frmt_50_6=byte +sff_cpld_reg.pola_50_6=positive +sff_cpld_reg.fpath_50_6=/dev/cpld3 +sff_cpld_reg.addr_50_6=0x57 +sff_cpld_reg.len_50_6=1 +sff_cpld_reg.val_type_50_6=nega_key + +sff_cpld_reg.mode_51_6=config +sff_cpld_reg.src_51_6=logic_file +sff_cpld_reg.frmt_51_6=byte +sff_cpld_reg.pola_51_6=positive +sff_cpld_reg.fpath_51_6=/dev/cpld3 +sff_cpld_reg.addr_51_6=0x58 +sff_cpld_reg.len_51_6=1 +sff_cpld_reg.val_type_51_6=nega_key + +sff_cpld_reg.mode_52_6=config +sff_cpld_reg.src_52_6=logic_file +sff_cpld_reg.frmt_52_6=byte +sff_cpld_reg.pola_52_6=positive +sff_cpld_reg.fpath_52_6=/dev/cpld3 +sff_cpld_reg.addr_52_6=0x59 +sff_cpld_reg.len_52_6=1 +sff_cpld_reg.val_type_52_6=nega_key + +sff_cpld_reg.mode_53_6=config +sff_cpld_reg.src_53_6=logic_file +sff_cpld_reg.frmt_53_6=byte +sff_cpld_reg.pola_53_6=positive +sff_cpld_reg.fpath_53_6=/dev/cpld3 +sff_cpld_reg.addr_53_6=0x5a +sff_cpld_reg.len_53_6=1 +sff_cpld_reg.val_type_53_6=nega_key + +sff_cpld_reg.mode_54_6=config +sff_cpld_reg.src_54_6=logic_file +sff_cpld_reg.frmt_54_6=byte +sff_cpld_reg.pola_54_6=positive +sff_cpld_reg.fpath_54_6=/dev/cpld3 +sff_cpld_reg.addr_54_6=0x5b +sff_cpld_reg.len_54_6=1 +sff_cpld_reg.val_type_54_6=nega_key + +sff_cpld_reg.mode_55_6=config +sff_cpld_reg.src_55_6=logic_file +sff_cpld_reg.frmt_55_6=byte +sff_cpld_reg.pola_55_6=positive +sff_cpld_reg.fpath_55_6=/dev/cpld3 +sff_cpld_reg.addr_55_6=0x5c +sff_cpld_reg.len_55_6=1 +sff_cpld_reg.val_type_55_6=nega_key + +sff_cpld_reg.mode_56_6=config +sff_cpld_reg.src_56_6=logic_file +sff_cpld_reg.frmt_56_6=byte +sff_cpld_reg.pola_56_6=positive +sff_cpld_reg.fpath_56_6=/dev/cpld3 +sff_cpld_reg.addr_56_6=0x5d +sff_cpld_reg.len_56_6=1 +sff_cpld_reg.val_type_56_6=nega_key + +sff_cpld_reg.mode_57_6=config +sff_cpld_reg.src_57_6=logic_file +sff_cpld_reg.frmt_57_6=byte +sff_cpld_reg.pola_57_6=positive +sff_cpld_reg.fpath_57_6=/dev/cpld3 +sff_cpld_reg.addr_57_6=0x5e +sff_cpld_reg.len_57_6=1 +sff_cpld_reg.val_type_57_6=nega_key + +sff_cpld_reg.mode_58_6=config +sff_cpld_reg.src_58_6=logic_file +sff_cpld_reg.frmt_58_6=byte +sff_cpld_reg.pola_58_6=positive +sff_cpld_reg.fpath_58_6=/dev/cpld3 +sff_cpld_reg.addr_58_6=0x5f +sff_cpld_reg.len_58_6=1 +sff_cpld_reg.val_type_58_6=nega_key + +sff_cpld_reg.mode_59_6=config +sff_cpld_reg.src_59_6=logic_file +sff_cpld_reg.frmt_59_6=byte +sff_cpld_reg.pola_59_6=positive +sff_cpld_reg.fpath_59_6=/dev/cpld3 +sff_cpld_reg.addr_59_6=0x60 +sff_cpld_reg.len_59_6=1 +sff_cpld_reg.val_type_59_6=nega_key + +sff_cpld_reg.mode_60_6=config +sff_cpld_reg.src_60_6=logic_file +sff_cpld_reg.frmt_60_6=byte +sff_cpld_reg.pola_60_6=positive +sff_cpld_reg.fpath_60_6=/dev/cpld3 +sff_cpld_reg.addr_60_6=0x61 +sff_cpld_reg.len_60_6=1 +sff_cpld_reg.val_type_60_6=nega_key + +sff_cpld_reg.mode_61_6=config +sff_cpld_reg.src_61_6=logic_file +sff_cpld_reg.frmt_61_6=byte +sff_cpld_reg.pola_61_6=positive +sff_cpld_reg.fpath_61_6=/dev/cpld3 +sff_cpld_reg.addr_61_6=0x62 +sff_cpld_reg.len_61_6=1 +sff_cpld_reg.val_type_61_6=nega_key + +sff_cpld_reg.mode_62_6=config +sff_cpld_reg.src_62_6=logic_file +sff_cpld_reg.frmt_62_6=byte +sff_cpld_reg.pola_62_6=positive +sff_cpld_reg.fpath_62_6=/dev/cpld3 +sff_cpld_reg.addr_62_6=0x63 +sff_cpld_reg.len_62_6=1 +sff_cpld_reg.val_type_62_6=nega_key + +sff_cpld_reg.mode_63_6=config +sff_cpld_reg.src_63_6=logic_file +sff_cpld_reg.frmt_63_6=byte +sff_cpld_reg.pola_63_6=positive +sff_cpld_reg.fpath_63_6=/dev/cpld3 +sff_cpld_reg.addr_63_6=0x64 +sff_cpld_reg.len_63_6=1 +sff_cpld_reg.val_type_63_6=nega_key + +sff_cpld_reg.mode_64_6=config +sff_cpld_reg.src_64_6=logic_file +sff_cpld_reg.frmt_64_6=byte +sff_cpld_reg.pola_64_6=positive +sff_cpld_reg.fpath_64_6=/dev/cpld3 +sff_cpld_reg.addr_64_6=0x65 +sff_cpld_reg.len_64_6=1 +sff_cpld_reg.val_type_64_6=nega_key + +sff_cpld_reg.mode_65_6=config +sff_cpld_reg.src_65_6=logic_file +sff_cpld_reg.frmt_65_6=byte +sff_cpld_reg.pola_65_6=positive +sff_cpld_reg.fpath_65_6=/dev/cpld2 +sff_cpld_reg.addr_65_6=0x6a +sff_cpld_reg.len_65_6=1 +sff_cpld_reg.val_type_65_6=nega_key + +sff_cpld_reg.mode_66_6=config +sff_cpld_reg.src_66_6=logic_file +sff_cpld_reg.frmt_66_6=byte +sff_cpld_reg.pola_66_6=positive +sff_cpld_reg.fpath_66_6=/dev/cpld2 +sff_cpld_reg.addr_66_6=0x6b +sff_cpld_reg.len_66_6=1 +sff_cpld_reg.val_type_66_6=nega_key + +sff_cpld_reg.mode_67_6=config +sff_cpld_reg.src_67_6=logic_file +sff_cpld_reg.frmt_67_6=byte +sff_cpld_reg.pola_67_6=positive +sff_cpld_reg.fpath_67_6=/dev/cpld2 +sff_cpld_reg.addr_67_6=0x6c +sff_cpld_reg.len_67_6=1 +sff_cpld_reg.val_type_67_6=nega_key + +sff_cpld_reg.mode_68_6=config +sff_cpld_reg.src_68_6=logic_file +sff_cpld_reg.frmt_68_6=byte +sff_cpld_reg.pola_68_6=positive +sff_cpld_reg.fpath_68_6=/dev/cpld2 +sff_cpld_reg.addr_68_6=0x6d +sff_cpld_reg.len_68_6=1 +sff_cpld_reg.val_type_68_6=nega_key + +sff_cpld_reg.mode_69_6=config +sff_cpld_reg.src_69_6=logic_file +sff_cpld_reg.frmt_69_6=byte +sff_cpld_reg.pola_69_6=positive +sff_cpld_reg.fpath_69_6=/dev/cpld2 +sff_cpld_reg.addr_69_6=0x6e +sff_cpld_reg.len_69_6=1 +sff_cpld_reg.val_type_69_6=nega_key + +sff_cpld_reg.mode_70_6=config +sff_cpld_reg.src_70_6=logic_file +sff_cpld_reg.frmt_70_6=byte +sff_cpld_reg.pola_70_6=positive +sff_cpld_reg.fpath_70_6=/dev/cpld2 +sff_cpld_reg.addr_70_6=0x6f +sff_cpld_reg.len_70_6=1 +sff_cpld_reg.val_type_70_6=nega_key + +sff_cpld_reg.mode_71_6=config +sff_cpld_reg.src_71_6=logic_file +sff_cpld_reg.frmt_71_6=byte +sff_cpld_reg.pola_71_6=positive +sff_cpld_reg.fpath_71_6=/dev/cpld2 +sff_cpld_reg.addr_71_6=0x70 +sff_cpld_reg.len_71_6=1 +sff_cpld_reg.val_type_71_6=nega_key + +sff_cpld_reg.mode_72_6=config +sff_cpld_reg.src_72_6=logic_file +sff_cpld_reg.frmt_72_6=byte +sff_cpld_reg.pola_72_6=positive +sff_cpld_reg.fpath_72_6=/dev/cpld2 +sff_cpld_reg.addr_72_6=0x71 +sff_cpld_reg.len_72_6=1 +sff_cpld_reg.val_type_72_6=nega_key + +sff_cpld_reg.mode_73_6=config +sff_cpld_reg.src_73_6=logic_file +sff_cpld_reg.frmt_73_6=byte +sff_cpld_reg.pola_73_6=positive +sff_cpld_reg.fpath_73_6=/dev/cpld2 +sff_cpld_reg.addr_73_6=0x72 +sff_cpld_reg.len_73_6=1 +sff_cpld_reg.val_type_73_6=nega_key + +sff_cpld_reg.mode_74_6=config +sff_cpld_reg.src_74_6=logic_file +sff_cpld_reg.frmt_74_6=byte +sff_cpld_reg.pola_74_6=positive +sff_cpld_reg.fpath_74_6=/dev/cpld2 +sff_cpld_reg.addr_74_6=0x73 +sff_cpld_reg.len_74_6=1 +sff_cpld_reg.val_type_74_6=nega_key + +sff_cpld_reg.mode_75_6=config +sff_cpld_reg.src_75_6=logic_file +sff_cpld_reg.frmt_75_6=byte +sff_cpld_reg.pola_75_6=positive +sff_cpld_reg.fpath_75_6=/dev/cpld3 +sff_cpld_reg.addr_75_6=0x66 +sff_cpld_reg.len_75_6=1 +sff_cpld_reg.val_type_75_6=nega_key + +sff_cpld_reg.mode_76_6=config +sff_cpld_reg.src_76_6=logic_file +sff_cpld_reg.frmt_76_6=byte +sff_cpld_reg.pola_76_6=positive +sff_cpld_reg.fpath_76_6=/dev/cpld3 +sff_cpld_reg.addr_76_6=0x67 +sff_cpld_reg.len_76_6=1 +sff_cpld_reg.val_type_76_6=nega_key + +sff_cpld_reg.mode_77_6=config +sff_cpld_reg.src_77_6=logic_file +sff_cpld_reg.frmt_77_6=byte +sff_cpld_reg.pola_77_6=positive +sff_cpld_reg.fpath_77_6=/dev/cpld3 +sff_cpld_reg.addr_77_6=0x68 +sff_cpld_reg.len_77_6=1 +sff_cpld_reg.val_type_77_6=nega_key + +sff_cpld_reg.mode_78_6=config +sff_cpld_reg.src_78_6=logic_file +sff_cpld_reg.frmt_78_6=byte +sff_cpld_reg.pola_78_6=positive +sff_cpld_reg.fpath_78_6=/dev/cpld3 +sff_cpld_reg.addr_78_6=0x69 +sff_cpld_reg.len_78_6=1 +sff_cpld_reg.val_type_78_6=nega_key + +sff_cpld_reg.mode_79_6=config +sff_cpld_reg.src_79_6=logic_file +sff_cpld_reg.frmt_79_6=byte +sff_cpld_reg.pola_79_6=positive +sff_cpld_reg.fpath_79_6=/dev/cpld3 +sff_cpld_reg.addr_79_6=0x6a +sff_cpld_reg.len_79_6=1 +sff_cpld_reg.val_type_79_6=nega_key + +sff_cpld_reg.mode_80_6=config +sff_cpld_reg.src_80_6=logic_file +sff_cpld_reg.frmt_80_6=byte +sff_cpld_reg.pola_80_6=positive +sff_cpld_reg.fpath_80_6=/dev/cpld3 +sff_cpld_reg.addr_80_6=0x6b +sff_cpld_reg.len_80_6=1 +sff_cpld_reg.val_type_80_6=nega_key + +sff_cpld_reg.mode_81_6=config +sff_cpld_reg.src_81_6=logic_file +sff_cpld_reg.frmt_81_6=byte +sff_cpld_reg.pola_81_6=positive +sff_cpld_reg.fpath_81_6=/dev/cpld3 +sff_cpld_reg.addr_81_6=0x6c +sff_cpld_reg.len_81_6=1 +sff_cpld_reg.val_type_81_6=nega_key + +sff_cpld_reg.mode_82_6=config +sff_cpld_reg.src_82_6=logic_file +sff_cpld_reg.frmt_82_6=byte +sff_cpld_reg.pola_82_6=positive +sff_cpld_reg.fpath_82_6=/dev/cpld3 +sff_cpld_reg.addr_82_6=0x6d +sff_cpld_reg.len_82_6=1 +sff_cpld_reg.val_type_82_6=nega_key + +sff_cpld_reg.mode_83_6=config +sff_cpld_reg.src_83_6=logic_file +sff_cpld_reg.frmt_83_6=byte +sff_cpld_reg.pola_83_6=positive +sff_cpld_reg.fpath_83_6=/dev/cpld3 +sff_cpld_reg.addr_83_6=0x6e +sff_cpld_reg.len_83_6=1 +sff_cpld_reg.val_type_83_6=nega_key + +sff_cpld_reg.mode_84_6=config +sff_cpld_reg.src_84_6=logic_file +sff_cpld_reg.frmt_84_6=byte +sff_cpld_reg.pola_84_6=positive +sff_cpld_reg.fpath_84_6=/dev/cpld3 +sff_cpld_reg.addr_84_6=0x6f +sff_cpld_reg.len_84_6=1 +sff_cpld_reg.val_type_84_6=nega_key + +sff_cpld_reg.mode_85_6=config +sff_cpld_reg.src_85_6=logic_file +sff_cpld_reg.frmt_85_6=byte +sff_cpld_reg.pola_85_6=positive +sff_cpld_reg.fpath_85_6=/dev/cpld3 +sff_cpld_reg.addr_85_6=0x70 +sff_cpld_reg.len_85_6=1 +sff_cpld_reg.val_type_85_6=nega_key + +sff_cpld_reg.mode_86_6=config +sff_cpld_reg.src_86_6=logic_file +sff_cpld_reg.frmt_86_6=byte +sff_cpld_reg.pola_86_6=positive +sff_cpld_reg.fpath_86_6=/dev/cpld3 +sff_cpld_reg.addr_86_6=0x71 +sff_cpld_reg.len_86_6=1 +sff_cpld_reg.val_type_86_6=nega_key + +sff_cpld_reg.mode_87_6=config +sff_cpld_reg.src_87_6=logic_file +sff_cpld_reg.frmt_87_6=byte +sff_cpld_reg.pola_87_6=positive +sff_cpld_reg.fpath_87_6=/dev/cpld3 +sff_cpld_reg.addr_87_6=0x72 +sff_cpld_reg.len_87_6=1 +sff_cpld_reg.val_type_87_6=nega_key + +sff_cpld_reg.mode_88_6=config +sff_cpld_reg.src_88_6=logic_file +sff_cpld_reg.frmt_88_6=byte +sff_cpld_reg.pola_88_6=positive +sff_cpld_reg.fpath_88_6=/dev/cpld3 +sff_cpld_reg.addr_88_6=0x73 +sff_cpld_reg.len_88_6=1 +sff_cpld_reg.val_type_88_6=nega_key + +sff_cpld_reg.mode_89_6=config +sff_cpld_reg.src_89_6=logic_file +sff_cpld_reg.frmt_89_6=byte +sff_cpld_reg.pola_89_6=positive +sff_cpld_reg.fpath_89_6=/dev/cpld3 +sff_cpld_reg.addr_89_6=0x74 +sff_cpld_reg.len_89_6=1 +sff_cpld_reg.val_type_89_6=nega_key + +sff_cpld_reg.mode_90_6=config +sff_cpld_reg.src_90_6=logic_file +sff_cpld_reg.frmt_90_6=byte +sff_cpld_reg.pola_90_6=positive +sff_cpld_reg.fpath_90_6=/dev/cpld3 +sff_cpld_reg.addr_90_6=0x75 +sff_cpld_reg.len_90_6=1 +sff_cpld_reg.val_type_90_6=nega_key + +sff_cpld_reg.mode_91_6=config +sff_cpld_reg.src_91_6=logic_file +sff_cpld_reg.frmt_91_6=byte +sff_cpld_reg.pola_91_6=positive +sff_cpld_reg.fpath_91_6=/dev/cpld3 +sff_cpld_reg.addr_91_6=0x76 +sff_cpld_reg.len_91_6=1 +sff_cpld_reg.val_type_91_6=nega_key + +sff_cpld_reg.mode_92_6=config +sff_cpld_reg.src_92_6=logic_file +sff_cpld_reg.frmt_92_6=byte +sff_cpld_reg.pola_92_6=positive +sff_cpld_reg.fpath_92_6=/dev/cpld3 +sff_cpld_reg.addr_92_6=0x77 +sff_cpld_reg.len_92_6=1 +sff_cpld_reg.val_type_92_6=nega_key + +sff_cpld_reg.mode_93_6=config +sff_cpld_reg.src_93_6=logic_file +sff_cpld_reg.frmt_93_6=byte +sff_cpld_reg.pola_93_6=positive +sff_cpld_reg.fpath_93_6=/dev/cpld3 +sff_cpld_reg.addr_93_6=0x78 +sff_cpld_reg.len_93_6=1 +sff_cpld_reg.val_type_93_6=nega_key + +sff_cpld_reg.mode_94_6=config +sff_cpld_reg.src_94_6=logic_file +sff_cpld_reg.frmt_94_6=byte +sff_cpld_reg.pola_94_6=positive +sff_cpld_reg.fpath_94_6=/dev/cpld3 +sff_cpld_reg.addr_94_6=0x79 +sff_cpld_reg.len_94_6=1 +sff_cpld_reg.val_type_94_6=nega_key + +sff_cpld_reg.mode_95_6=config +sff_cpld_reg.src_95_6=logic_file +sff_cpld_reg.frmt_95_6=byte +sff_cpld_reg.pola_95_6=positive +sff_cpld_reg.fpath_95_6=/dev/cpld3 +sff_cpld_reg.addr_95_6=0x7a +sff_cpld_reg.len_95_6=1 +sff_cpld_reg.val_type_95_6=nega_key + +sff_cpld_reg.mode_96_6=config +sff_cpld_reg.src_96_6=logic_file +sff_cpld_reg.frmt_96_6=byte +sff_cpld_reg.pola_96_6=positive +sff_cpld_reg.fpath_96_6=/dev/cpld3 +sff_cpld_reg.addr_96_6=0x7b +sff_cpld_reg.len_96_6=1 +sff_cpld_reg.val_type_96_6=nega_key + +sff_cpld_reg.mode_97_6=config +sff_cpld_reg.src_97_6=logic_file +sff_cpld_reg.frmt_97_6=byte +sff_cpld_reg.pola_97_6=positive +sff_cpld_reg.fpath_97_6=/dev/cpld6 +sff_cpld_reg.addr_97_6=0x50 +sff_cpld_reg.len_97_6=1 +sff_cpld_reg.val_type_97_6=nega_key + +sff_cpld_reg.mode_98_6=config +sff_cpld_reg.src_98_6=logic_file +sff_cpld_reg.frmt_98_6=byte +sff_cpld_reg.pola_98_6=positive +sff_cpld_reg.fpath_98_6=/dev/cpld6 +sff_cpld_reg.addr_98_6=0x51 +sff_cpld_reg.len_98_6=1 +sff_cpld_reg.val_type_98_6=nega_key + +sff_cpld_reg.mode_99_6=config +sff_cpld_reg.src_99_6=logic_file +sff_cpld_reg.frmt_99_6=byte +sff_cpld_reg.pola_99_6=positive +sff_cpld_reg.fpath_99_6=/dev/cpld6 +sff_cpld_reg.addr_99_6=0x52 +sff_cpld_reg.len_99_6=1 +sff_cpld_reg.val_type_99_6=nega_key + +sff_cpld_reg.mode_100_6=config +sff_cpld_reg.src_100_6=logic_file +sff_cpld_reg.frmt_100_6=byte +sff_cpld_reg.pola_100_6=positive +sff_cpld_reg.fpath_100_6=/dev/cpld6 +sff_cpld_reg.addr_100_6=0x53 +sff_cpld_reg.len_100_6=1 +sff_cpld_reg.val_type_100_6=nega_key + +sff_cpld_reg.mode_101_6=config +sff_cpld_reg.src_101_6=logic_file +sff_cpld_reg.frmt_101_6=byte +sff_cpld_reg.pola_101_6=positive +sff_cpld_reg.fpath_101_6=/dev/cpld6 +sff_cpld_reg.addr_101_6=0x54 +sff_cpld_reg.len_101_6=1 +sff_cpld_reg.val_type_101_6=nega_key + +sff_cpld_reg.mode_102_6=config +sff_cpld_reg.src_102_6=logic_file +sff_cpld_reg.frmt_102_6=byte +sff_cpld_reg.pola_102_6=positive +sff_cpld_reg.fpath_102_6=/dev/cpld6 +sff_cpld_reg.addr_102_6=0x55 +sff_cpld_reg.len_102_6=1 +sff_cpld_reg.val_type_102_6=nega_key + +sff_cpld_reg.mode_103_6=config +sff_cpld_reg.src_103_6=logic_file +sff_cpld_reg.frmt_103_6=byte +sff_cpld_reg.pola_103_6=positive +sff_cpld_reg.fpath_103_6=/dev/cpld6 +sff_cpld_reg.addr_103_6=0x56 +sff_cpld_reg.len_103_6=1 +sff_cpld_reg.val_type_103_6=nega_key + +sff_cpld_reg.mode_104_6=config +sff_cpld_reg.src_104_6=logic_file +sff_cpld_reg.frmt_104_6=byte +sff_cpld_reg.pola_104_6=positive +sff_cpld_reg.fpath_104_6=/dev/cpld6 +sff_cpld_reg.addr_104_6=0x57 +sff_cpld_reg.len_104_6=1 +sff_cpld_reg.val_type_104_6=nega_key + +sff_cpld_reg.mode_105_6=config +sff_cpld_reg.src_105_6=logic_file +sff_cpld_reg.frmt_105_6=byte +sff_cpld_reg.pola_105_6=positive +sff_cpld_reg.fpath_105_6=/dev/cpld6 +sff_cpld_reg.addr_105_6=0x58 +sff_cpld_reg.len_105_6=1 +sff_cpld_reg.val_type_105_6=nega_key + +sff_cpld_reg.mode_106_6=config +sff_cpld_reg.src_106_6=logic_file +sff_cpld_reg.frmt_106_6=byte +sff_cpld_reg.pola_106_6=positive +sff_cpld_reg.fpath_106_6=/dev/cpld6 +sff_cpld_reg.addr_106_6=0x59 +sff_cpld_reg.len_106_6=1 +sff_cpld_reg.val_type_106_6=nega_key + +sff_cpld_reg.mode_107_6=config +sff_cpld_reg.src_107_6=logic_file +sff_cpld_reg.frmt_107_6=byte +sff_cpld_reg.pola_107_6=positive +sff_cpld_reg.fpath_107_6=/dev/cpld6 +sff_cpld_reg.addr_107_6=0x5a +sff_cpld_reg.len_107_6=1 +sff_cpld_reg.val_type_107_6=nega_key + +sff_cpld_reg.mode_108_6=config +sff_cpld_reg.src_108_6=logic_file +sff_cpld_reg.frmt_108_6=byte +sff_cpld_reg.pola_108_6=positive +sff_cpld_reg.fpath_108_6=/dev/cpld6 +sff_cpld_reg.addr_108_6=0x5b +sff_cpld_reg.len_108_6=1 +sff_cpld_reg.val_type_108_6=nega_key + +sff_cpld_reg.mode_109_6=config +sff_cpld_reg.src_109_6=logic_file +sff_cpld_reg.frmt_109_6=byte +sff_cpld_reg.pola_109_6=positive +sff_cpld_reg.fpath_109_6=/dev/cpld6 +sff_cpld_reg.addr_109_6=0x5c +sff_cpld_reg.len_109_6=1 +sff_cpld_reg.val_type_109_6=nega_key + +sff_cpld_reg.mode_110_6=config +sff_cpld_reg.src_110_6=logic_file +sff_cpld_reg.frmt_110_6=byte +sff_cpld_reg.pola_110_6=positive +sff_cpld_reg.fpath_110_6=/dev/cpld6 +sff_cpld_reg.addr_110_6=0x5d +sff_cpld_reg.len_110_6=1 +sff_cpld_reg.val_type_110_6=nega_key + +sff_cpld_reg.mode_111_6=config +sff_cpld_reg.src_111_6=logic_file +sff_cpld_reg.frmt_111_6=byte +sff_cpld_reg.pola_111_6=positive +sff_cpld_reg.fpath_111_6=/dev/cpld6 +sff_cpld_reg.addr_111_6=0x5e +sff_cpld_reg.len_111_6=1 +sff_cpld_reg.val_type_111_6=nega_key + +sff_cpld_reg.mode_112_6=config +sff_cpld_reg.src_112_6=logic_file +sff_cpld_reg.frmt_112_6=byte +sff_cpld_reg.pola_112_6=positive +sff_cpld_reg.fpath_112_6=/dev/cpld6 +sff_cpld_reg.addr_112_6=0x5f +sff_cpld_reg.len_112_6=1 +sff_cpld_reg.val_type_112_6=nega_key + +sff_cpld_reg.mode_113_6=config +sff_cpld_reg.src_113_6=logic_file +sff_cpld_reg.frmt_113_6=byte +sff_cpld_reg.pola_113_6=positive +sff_cpld_reg.fpath_113_6=/dev/cpld6 +sff_cpld_reg.addr_113_6=0x60 +sff_cpld_reg.len_113_6=1 +sff_cpld_reg.val_type_113_6=nega_key + +sff_cpld_reg.mode_114_6=config +sff_cpld_reg.src_114_6=logic_file +sff_cpld_reg.frmt_114_6=byte +sff_cpld_reg.pola_114_6=positive +sff_cpld_reg.fpath_114_6=/dev/cpld6 +sff_cpld_reg.addr_114_6=0x61 +sff_cpld_reg.len_114_6=1 +sff_cpld_reg.val_type_114_6=nega_key + +sff_cpld_reg.mode_115_6=config +sff_cpld_reg.src_115_6=logic_file +sff_cpld_reg.frmt_115_6=byte +sff_cpld_reg.pola_115_6=positive +sff_cpld_reg.fpath_115_6=/dev/cpld6 +sff_cpld_reg.addr_115_6=0x62 +sff_cpld_reg.len_115_6=1 +sff_cpld_reg.val_type_115_6=nega_key + +sff_cpld_reg.mode_116_6=config +sff_cpld_reg.src_116_6=logic_file +sff_cpld_reg.frmt_116_6=byte +sff_cpld_reg.pola_116_6=positive +sff_cpld_reg.fpath_116_6=/dev/cpld6 +sff_cpld_reg.addr_116_6=0x63 +sff_cpld_reg.len_116_6=1 +sff_cpld_reg.val_type_116_6=nega_key + +sff_cpld_reg.mode_117_6=config +sff_cpld_reg.src_117_6=logic_file +sff_cpld_reg.frmt_117_6=byte +sff_cpld_reg.pola_117_6=positive +sff_cpld_reg.fpath_117_6=/dev/cpld6 +sff_cpld_reg.addr_117_6=0x64 +sff_cpld_reg.len_117_6=1 +sff_cpld_reg.val_type_117_6=nega_key + +sff_cpld_reg.mode_118_6=config +sff_cpld_reg.src_118_6=logic_file +sff_cpld_reg.frmt_118_6=byte +sff_cpld_reg.pola_118_6=positive +sff_cpld_reg.fpath_118_6=/dev/cpld6 +sff_cpld_reg.addr_118_6=0x65 +sff_cpld_reg.len_118_6=1 +sff_cpld_reg.val_type_118_6=nega_key + +sff_cpld_reg.mode_119_6=config +sff_cpld_reg.src_119_6=logic_file +sff_cpld_reg.frmt_119_6=byte +sff_cpld_reg.pola_119_6=positive +sff_cpld_reg.fpath_119_6=/dev/cpld6 +sff_cpld_reg.addr_119_6=0x66 +sff_cpld_reg.len_119_6=1 +sff_cpld_reg.val_type_119_6=nega_key + +sff_cpld_reg.mode_120_6=config +sff_cpld_reg.src_120_6=logic_file +sff_cpld_reg.frmt_120_6=byte +sff_cpld_reg.pola_120_6=positive +sff_cpld_reg.fpath_120_6=/dev/cpld6 +sff_cpld_reg.addr_120_6=0x67 +sff_cpld_reg.len_120_6=1 +sff_cpld_reg.val_type_120_6=nega_key + +sff_cpld_reg.mode_121_6=config +sff_cpld_reg.src_121_6=logic_file +sff_cpld_reg.frmt_121_6=byte +sff_cpld_reg.pola_121_6=positive +sff_cpld_reg.fpath_121_6=/dev/cpld6 +sff_cpld_reg.addr_121_6=0x68 +sff_cpld_reg.len_121_6=1 +sff_cpld_reg.val_type_121_6=nega_key + +sff_cpld_reg.mode_122_6=config +sff_cpld_reg.src_122_6=logic_file +sff_cpld_reg.frmt_122_6=byte +sff_cpld_reg.pola_122_6=positive +sff_cpld_reg.fpath_122_6=/dev/cpld6 +sff_cpld_reg.addr_122_6=0x69 +sff_cpld_reg.len_122_6=1 +sff_cpld_reg.val_type_122_6=nega_key + +sff_cpld_reg.mode_123_6=config +sff_cpld_reg.src_123_6=logic_file +sff_cpld_reg.frmt_123_6=byte +sff_cpld_reg.pola_123_6=positive +sff_cpld_reg.fpath_123_6=/dev/cpld6 +sff_cpld_reg.addr_123_6=0x6a +sff_cpld_reg.len_123_6=1 +sff_cpld_reg.val_type_123_6=nega_key + +sff_cpld_reg.mode_124_6=config +sff_cpld_reg.src_124_6=logic_file +sff_cpld_reg.frmt_124_6=byte +sff_cpld_reg.pola_124_6=positive +sff_cpld_reg.fpath_124_6=/dev/cpld6 +sff_cpld_reg.addr_124_6=0x6b +sff_cpld_reg.len_124_6=1 +sff_cpld_reg.val_type_124_6=nega_key + +sff_cpld_reg.mode_125_6=config +sff_cpld_reg.src_125_6=logic_file +sff_cpld_reg.frmt_125_6=byte +sff_cpld_reg.pola_125_6=positive +sff_cpld_reg.fpath_125_6=/dev/cpld6 +sff_cpld_reg.addr_125_6=0x6c +sff_cpld_reg.len_125_6=1 +sff_cpld_reg.val_type_125_6=nega_key + +sff_cpld_reg.mode_126_6=config +sff_cpld_reg.src_126_6=logic_file +sff_cpld_reg.frmt_126_6=byte +sff_cpld_reg.pola_126_6=positive +sff_cpld_reg.fpath_126_6=/dev/cpld6 +sff_cpld_reg.addr_126_6=0x6d +sff_cpld_reg.len_126_6=1 +sff_cpld_reg.val_type_126_6=nega_key + +sff_cpld_reg.mode_127_6=config +sff_cpld_reg.src_127_6=logic_file +sff_cpld_reg.frmt_127_6=byte +sff_cpld_reg.pola_127_6=positive +sff_cpld_reg.fpath_127_6=/dev/cpld6 +sff_cpld_reg.addr_127_6=0x6e +sff_cpld_reg.len_127_6=1 +sff_cpld_reg.val_type_127_6=nega_key + +sff_cpld_reg.mode_128_6=config +sff_cpld_reg.src_128_6=logic_file +sff_cpld_reg.frmt_128_6=byte +sff_cpld_reg.pola_128_6=positive +sff_cpld_reg.fpath_128_6=/dev/cpld6 +sff_cpld_reg.addr_128_6=0x6f +sff_cpld_reg.len_128_6=1 +sff_cpld_reg.val_type_128_6=nega_key + +sff_cpld_reg.mode_129_6=config +sff_cpld_reg.src_129_6=logic_file +sff_cpld_reg.frmt_129_6=byte +sff_cpld_reg.pola_129_6=positive +sff_cpld_reg.fpath_129_6=/dev/cpld1 +sff_cpld_reg.addr_129_6=0xdd +sff_cpld_reg.len_129_6=1 +sff_cpld_reg.val_type_129_6=nega_key + +# 800G module lpmode signal +reg_key_0x0307_0x00=0x01 +reg_key_0x0307_0x01=0x00 + +sysfs_decode_0x0307_0x00=0x01 +sysfs_decode_0x0307_0x01=0x00 + +sff_cpld_reg.mode_1_7=config +sff_cpld_reg.src_1_7=logic_file +sff_cpld_reg.frmt_1_7=byte +sff_cpld_reg.pola_1_7=positive +sff_cpld_reg.fpath_1_7=/dev/cpld5 +sff_cpld_reg.addr_1_7=0x70 +sff_cpld_reg.len_1_7=1 +sff_cpld_reg.val_type_1_7=nega_key + +sff_cpld_reg.mode_2_7=config +sff_cpld_reg.src_2_7=logic_file +sff_cpld_reg.frmt_2_7=byte +sff_cpld_reg.pola_2_7=positive +sff_cpld_reg.fpath_2_7=/dev/cpld5 +sff_cpld_reg.addr_2_7=0x71 +sff_cpld_reg.len_2_7=1 +sff_cpld_reg.val_type_2_7=nega_key + +sff_cpld_reg.mode_3_7=config +sff_cpld_reg.src_3_7=logic_file +sff_cpld_reg.frmt_3_7=byte +sff_cpld_reg.pola_3_7=positive +sff_cpld_reg.fpath_3_7=/dev/cpld5 +sff_cpld_reg.addr_3_7=0x72 +sff_cpld_reg.len_3_7=1 +sff_cpld_reg.val_type_3_7=nega_key + +sff_cpld_reg.mode_4_7=config +sff_cpld_reg.src_4_7=logic_file +sff_cpld_reg.frmt_4_7=byte +sff_cpld_reg.pola_4_7=positive +sff_cpld_reg.fpath_4_7=/dev/cpld5 +sff_cpld_reg.addr_4_7=0x73 +sff_cpld_reg.len_4_7=1 +sff_cpld_reg.val_type_4_7=nega_key + +sff_cpld_reg.mode_5_7=config +sff_cpld_reg.src_5_7=logic_file +sff_cpld_reg.frmt_5_7=byte +sff_cpld_reg.pola_5_7=positive +sff_cpld_reg.fpath_5_7=/dev/cpld5 +sff_cpld_reg.addr_5_7=0x74 +sff_cpld_reg.len_5_7=1 +sff_cpld_reg.val_type_5_7=nega_key + +sff_cpld_reg.mode_6_7=config +sff_cpld_reg.src_6_7=logic_file +sff_cpld_reg.frmt_6_7=byte +sff_cpld_reg.pola_6_7=positive +sff_cpld_reg.fpath_6_7=/dev/cpld5 +sff_cpld_reg.addr_6_7=0x75 +sff_cpld_reg.len_6_7=1 +sff_cpld_reg.val_type_6_7=nega_key + +sff_cpld_reg.mode_7_7=config +sff_cpld_reg.src_7_7=logic_file +sff_cpld_reg.frmt_7_7=byte +sff_cpld_reg.pola_7_7=positive +sff_cpld_reg.fpath_7_7=/dev/cpld5 +sff_cpld_reg.addr_7_7=0x76 +sff_cpld_reg.len_7_7=1 +sff_cpld_reg.val_type_7_7=nega_key + +sff_cpld_reg.mode_8_7=config +sff_cpld_reg.src_8_7=logic_file +sff_cpld_reg.frmt_8_7=byte +sff_cpld_reg.pola_8_7=positive +sff_cpld_reg.fpath_8_7=/dev/cpld5 +sff_cpld_reg.addr_8_7=0x77 +sff_cpld_reg.len_8_7=1 +sff_cpld_reg.val_type_8_7=nega_key + +sff_cpld_reg.mode_9_7=config +sff_cpld_reg.src_9_7=logic_file +sff_cpld_reg.frmt_9_7=byte +sff_cpld_reg.pola_9_7=positive +sff_cpld_reg.fpath_9_7=/dev/cpld5 +sff_cpld_reg.addr_9_7=0x78 +sff_cpld_reg.len_9_7=1 +sff_cpld_reg.val_type_9_7=nega_key + +sff_cpld_reg.mode_10_7=config +sff_cpld_reg.src_10_7=logic_file +sff_cpld_reg.frmt_10_7=byte +sff_cpld_reg.pola_10_7=positive +sff_cpld_reg.fpath_10_7=/dev/cpld5 +sff_cpld_reg.addr_10_7=0x79 +sff_cpld_reg.len_10_7=1 +sff_cpld_reg.val_type_10_7=nega_key + +sff_cpld_reg.mode_11_7=config +sff_cpld_reg.src_11_7=logic_file +sff_cpld_reg.frmt_11_7=byte +sff_cpld_reg.pola_11_7=positive +sff_cpld_reg.fpath_11_7=/dev/cpld5 +sff_cpld_reg.addr_11_7=0x7a +sff_cpld_reg.len_11_7=1 +sff_cpld_reg.val_type_11_7=nega_key + +sff_cpld_reg.mode_12_7=config +sff_cpld_reg.src_12_7=logic_file +sff_cpld_reg.frmt_12_7=byte +sff_cpld_reg.pola_12_7=positive +sff_cpld_reg.fpath_12_7=/dev/cpld5 +sff_cpld_reg.addr_12_7=0x7b +sff_cpld_reg.len_12_7=1 +sff_cpld_reg.val_type_12_7=nega_key + +sff_cpld_reg.mode_13_7=config +sff_cpld_reg.src_13_7=logic_file +sff_cpld_reg.frmt_13_7=byte +sff_cpld_reg.pola_13_7=positive +sff_cpld_reg.fpath_13_7=/dev/cpld5 +sff_cpld_reg.addr_13_7=0x7c +sff_cpld_reg.len_13_7=1 +sff_cpld_reg.val_type_13_7=nega_key + +sff_cpld_reg.mode_14_7=config +sff_cpld_reg.src_14_7=logic_file +sff_cpld_reg.frmt_14_7=byte +sff_cpld_reg.pola_14_7=positive +sff_cpld_reg.fpath_14_7=/dev/cpld5 +sff_cpld_reg.addr_14_7=0x7d +sff_cpld_reg.len_14_7=1 +sff_cpld_reg.val_type_14_7=nega_key + +sff_cpld_reg.mode_15_7=config +sff_cpld_reg.src_15_7=logic_file +sff_cpld_reg.frmt_15_7=byte +sff_cpld_reg.pola_15_7=positive +sff_cpld_reg.fpath_15_7=/dev/cpld5 +sff_cpld_reg.addr_15_7=0x7e +sff_cpld_reg.len_15_7=1 +sff_cpld_reg.val_type_15_7=nega_key + +sff_cpld_reg.mode_16_7=config +sff_cpld_reg.src_16_7=logic_file +sff_cpld_reg.frmt_16_7=byte +sff_cpld_reg.pola_16_7=positive +sff_cpld_reg.fpath_16_7=/dev/cpld5 +sff_cpld_reg.addr_16_7=0x7f +sff_cpld_reg.len_16_7=1 +sff_cpld_reg.val_type_16_7=nega_key + +sff_cpld_reg.mode_17_7=config +sff_cpld_reg.src_17_7=logic_file +sff_cpld_reg.frmt_17_7=byte +sff_cpld_reg.pola_17_7=positive +sff_cpld_reg.fpath_17_7=/dev/cpld5 +sff_cpld_reg.addr_17_7=0x80 +sff_cpld_reg.len_17_7=1 +sff_cpld_reg.val_type_17_7=nega_key + +sff_cpld_reg.mode_18_7=config +sff_cpld_reg.src_18_7=logic_file +sff_cpld_reg.frmt_18_7=byte +sff_cpld_reg.pola_18_7=positive +sff_cpld_reg.fpath_18_7=/dev/cpld5 +sff_cpld_reg.addr_18_7=0x81 +sff_cpld_reg.len_18_7=1 +sff_cpld_reg.val_type_18_7=nega_key + +sff_cpld_reg.mode_19_7=config +sff_cpld_reg.src_19_7=logic_file +sff_cpld_reg.frmt_19_7=byte +sff_cpld_reg.pola_19_7=positive +sff_cpld_reg.fpath_19_7=/dev/cpld5 +sff_cpld_reg.addr_19_7=0x82 +sff_cpld_reg.len_19_7=1 +sff_cpld_reg.val_type_19_7=nega_key + +sff_cpld_reg.mode_20_7=config +sff_cpld_reg.src_20_7=logic_file +sff_cpld_reg.frmt_20_7=byte +sff_cpld_reg.pola_20_7=positive +sff_cpld_reg.fpath_20_7=/dev/cpld5 +sff_cpld_reg.addr_20_7=0x83 +sff_cpld_reg.len_20_7=1 +sff_cpld_reg.val_type_20_7=nega_key + +sff_cpld_reg.mode_21_7=config +sff_cpld_reg.src_21_7=logic_file +sff_cpld_reg.frmt_21_7=byte +sff_cpld_reg.pola_21_7=positive +sff_cpld_reg.fpath_21_7=/dev/cpld5 +sff_cpld_reg.addr_21_7=0x84 +sff_cpld_reg.len_21_7=1 +sff_cpld_reg.val_type_21_7=nega_key + +sff_cpld_reg.mode_22_7=config +sff_cpld_reg.src_22_7=logic_file +sff_cpld_reg.frmt_22_7=byte +sff_cpld_reg.pola_22_7=positive +sff_cpld_reg.fpath_22_7=/dev/cpld5 +sff_cpld_reg.addr_22_7=0x85 +sff_cpld_reg.len_22_7=1 +sff_cpld_reg.val_type_22_7=nega_key + +sff_cpld_reg.mode_23_7=config +sff_cpld_reg.src_23_7=logic_file +sff_cpld_reg.frmt_23_7=byte +sff_cpld_reg.pola_23_7=positive +sff_cpld_reg.fpath_23_7=/dev/cpld5 +sff_cpld_reg.addr_23_7=0x86 +sff_cpld_reg.len_23_7=1 +sff_cpld_reg.val_type_23_7=nega_key + +sff_cpld_reg.mode_24_7=config +sff_cpld_reg.src_24_7=logic_file +sff_cpld_reg.frmt_24_7=byte +sff_cpld_reg.pola_24_7=positive +sff_cpld_reg.fpath_24_7=/dev/cpld5 +sff_cpld_reg.addr_24_7=0x87 +sff_cpld_reg.len_24_7=1 +sff_cpld_reg.val_type_24_7=nega_key + +sff_cpld_reg.mode_25_7=config +sff_cpld_reg.src_25_7=logic_file +sff_cpld_reg.frmt_25_7=byte +sff_cpld_reg.pola_25_7=positive +sff_cpld_reg.fpath_25_7=/dev/cpld5 +sff_cpld_reg.addr_25_7=0x88 +sff_cpld_reg.len_25_7=1 +sff_cpld_reg.val_type_25_7=nega_key + +sff_cpld_reg.mode_26_7=config +sff_cpld_reg.src_26_7=logic_file +sff_cpld_reg.frmt_26_7=byte +sff_cpld_reg.pola_26_7=positive +sff_cpld_reg.fpath_26_7=/dev/cpld5 +sff_cpld_reg.addr_26_7=0x89 +sff_cpld_reg.len_26_7=1 +sff_cpld_reg.val_type_26_7=nega_key + +sff_cpld_reg.mode_27_7=config +sff_cpld_reg.src_27_7=logic_file +sff_cpld_reg.frmt_27_7=byte +sff_cpld_reg.pola_27_7=positive +sff_cpld_reg.fpath_27_7=/dev/cpld5 +sff_cpld_reg.addr_27_7=0x8a +sff_cpld_reg.len_27_7=1 +sff_cpld_reg.val_type_27_7=nega_key + +sff_cpld_reg.mode_28_7=config +sff_cpld_reg.src_28_7=logic_file +sff_cpld_reg.frmt_28_7=byte +sff_cpld_reg.pola_28_7=positive +sff_cpld_reg.fpath_28_7=/dev/cpld5 +sff_cpld_reg.addr_28_7=0x8b +sff_cpld_reg.len_28_7=1 +sff_cpld_reg.val_type_28_7=nega_key + +sff_cpld_reg.mode_29_7=config +sff_cpld_reg.src_29_7=logic_file +sff_cpld_reg.frmt_29_7=byte +sff_cpld_reg.pola_29_7=positive +sff_cpld_reg.fpath_29_7=/dev/cpld5 +sff_cpld_reg.addr_29_7=0x8c +sff_cpld_reg.len_29_7=1 +sff_cpld_reg.val_type_29_7=nega_key + +sff_cpld_reg.mode_30_7=config +sff_cpld_reg.src_30_7=logic_file +sff_cpld_reg.frmt_30_7=byte +sff_cpld_reg.pola_30_7=positive +sff_cpld_reg.fpath_30_7=/dev/cpld5 +sff_cpld_reg.addr_30_7=0x8d +sff_cpld_reg.len_30_7=1 +sff_cpld_reg.val_type_30_7=nega_key + +sff_cpld_reg.mode_31_7=config +sff_cpld_reg.src_31_7=logic_file +sff_cpld_reg.frmt_31_7=byte +sff_cpld_reg.pola_31_7=positive +sff_cpld_reg.fpath_31_7=/dev/cpld5 +sff_cpld_reg.addr_31_7=0x8e +sff_cpld_reg.len_31_7=1 +sff_cpld_reg.val_type_31_7=nega_key + +sff_cpld_reg.mode_32_7=config +sff_cpld_reg.src_32_7=logic_file +sff_cpld_reg.frmt_32_7=byte +sff_cpld_reg.pola_32_7=positive +sff_cpld_reg.fpath_32_7=/dev/cpld5 +sff_cpld_reg.addr_32_7=0x8f +sff_cpld_reg.len_32_7=1 +sff_cpld_reg.val_type_32_7=nega_key + +sff_cpld_reg.mode_33_7=config +sff_cpld_reg.src_33_7=logic_file +sff_cpld_reg.frmt_33_7=byte +sff_cpld_reg.pola_33_7=positive +sff_cpld_reg.fpath_33_7=/dev/cpld2 +sff_cpld_reg.addr_33_7=0x74 +sff_cpld_reg.len_33_7=1 +sff_cpld_reg.val_type_33_7=nega_key + +sff_cpld_reg.mode_34_7=config +sff_cpld_reg.src_34_7=logic_file +sff_cpld_reg.frmt_34_7=byte +sff_cpld_reg.pola_34_7=positive +sff_cpld_reg.fpath_34_7=/dev/cpld2 +sff_cpld_reg.addr_34_7=0x75 +sff_cpld_reg.len_34_7=1 +sff_cpld_reg.val_type_34_7=nega_key + +sff_cpld_reg.mode_35_7=config +sff_cpld_reg.src_35_7=logic_file +sff_cpld_reg.frmt_35_7=byte +sff_cpld_reg.pola_35_7=positive +sff_cpld_reg.fpath_35_7=/dev/cpld2 +sff_cpld_reg.addr_35_7=0x76 +sff_cpld_reg.len_35_7=1 +sff_cpld_reg.val_type_35_7=nega_key + +sff_cpld_reg.mode_36_7=config +sff_cpld_reg.src_36_7=logic_file +sff_cpld_reg.frmt_36_7=byte +sff_cpld_reg.pola_36_7=positive +sff_cpld_reg.fpath_36_7=/dev/cpld2 +sff_cpld_reg.addr_36_7=0x77 +sff_cpld_reg.len_36_7=1 +sff_cpld_reg.val_type_36_7=nega_key + +sff_cpld_reg.mode_37_7=config +sff_cpld_reg.src_37_7=logic_file +sff_cpld_reg.frmt_37_7=byte +sff_cpld_reg.pola_37_7=positive +sff_cpld_reg.fpath_37_7=/dev/cpld2 +sff_cpld_reg.addr_37_7=0x78 +sff_cpld_reg.len_37_7=1 +sff_cpld_reg.val_type_37_7=nega_key + +sff_cpld_reg.mode_38_7=config +sff_cpld_reg.src_38_7=logic_file +sff_cpld_reg.frmt_38_7=byte +sff_cpld_reg.pola_38_7=positive +sff_cpld_reg.fpath_38_7=/dev/cpld2 +sff_cpld_reg.addr_38_7=0x79 +sff_cpld_reg.len_38_7=1 +sff_cpld_reg.val_type_38_7=nega_key + +sff_cpld_reg.mode_39_7=config +sff_cpld_reg.src_39_7=logic_file +sff_cpld_reg.frmt_39_7=byte +sff_cpld_reg.pola_39_7=positive +sff_cpld_reg.fpath_39_7=/dev/cpld2 +sff_cpld_reg.addr_39_7=0x7a +sff_cpld_reg.len_39_7=1 +sff_cpld_reg.val_type_39_7=nega_key + +sff_cpld_reg.mode_40_7=config +sff_cpld_reg.src_40_7=logic_file +sff_cpld_reg.frmt_40_7=byte +sff_cpld_reg.pola_40_7=positive +sff_cpld_reg.fpath_40_7=/dev/cpld2 +sff_cpld_reg.addr_40_7=0x7b +sff_cpld_reg.len_40_7=1 +sff_cpld_reg.val_type_40_7=nega_key + +sff_cpld_reg.mode_41_7=config +sff_cpld_reg.src_41_7=logic_file +sff_cpld_reg.frmt_41_7=byte +sff_cpld_reg.pola_41_7=positive +sff_cpld_reg.fpath_41_7=/dev/cpld2 +sff_cpld_reg.addr_41_7=0x7c +sff_cpld_reg.len_41_7=1 +sff_cpld_reg.val_type_41_7=nega_key + +sff_cpld_reg.mode_42_7=config +sff_cpld_reg.src_42_7=logic_file +sff_cpld_reg.frmt_42_7=byte +sff_cpld_reg.pola_42_7=positive +sff_cpld_reg.fpath_42_7=/dev/cpld2 +sff_cpld_reg.addr_42_7=0x7d +sff_cpld_reg.len_42_7=1 +sff_cpld_reg.val_type_42_7=nega_key + +sff_cpld_reg.mode_43_7=config +sff_cpld_reg.src_43_7=logic_file +sff_cpld_reg.frmt_43_7=byte +sff_cpld_reg.pola_43_7=positive +sff_cpld_reg.fpath_43_7=/dev/cpld3 +sff_cpld_reg.addr_43_7=0x7c +sff_cpld_reg.len_43_7=1 +sff_cpld_reg.val_type_43_7=nega_key + +sff_cpld_reg.mode_44_7=config +sff_cpld_reg.src_44_7=logic_file +sff_cpld_reg.frmt_44_7=byte +sff_cpld_reg.pola_44_7=positive +sff_cpld_reg.fpath_44_7=/dev/cpld3 +sff_cpld_reg.addr_44_7=0x7d +sff_cpld_reg.len_44_7=1 +sff_cpld_reg.val_type_44_7=nega_key + +sff_cpld_reg.mode_45_7=config +sff_cpld_reg.src_45_7=logic_file +sff_cpld_reg.frmt_45_7=byte +sff_cpld_reg.pola_45_7=positive +sff_cpld_reg.fpath_45_7=/dev/cpld3 +sff_cpld_reg.addr_45_7=0x7e +sff_cpld_reg.len_45_7=1 +sff_cpld_reg.val_type_45_7=nega_key + +sff_cpld_reg.mode_46_7=config +sff_cpld_reg.src_46_7=logic_file +sff_cpld_reg.frmt_46_7=byte +sff_cpld_reg.pola_46_7=positive +sff_cpld_reg.fpath_46_7=/dev/cpld3 +sff_cpld_reg.addr_46_7=0x7f +sff_cpld_reg.len_46_7=1 +sff_cpld_reg.val_type_46_7=nega_key + +sff_cpld_reg.mode_47_7=config +sff_cpld_reg.src_47_7=logic_file +sff_cpld_reg.frmt_47_7=byte +sff_cpld_reg.pola_47_7=positive +sff_cpld_reg.fpath_47_7=/dev/cpld3 +sff_cpld_reg.addr_47_7=0x80 +sff_cpld_reg.len_47_7=1 +sff_cpld_reg.val_type_47_7=nega_key + +sff_cpld_reg.mode_48_7=config +sff_cpld_reg.src_48_7=logic_file +sff_cpld_reg.frmt_48_7=byte +sff_cpld_reg.pola_48_7=positive +sff_cpld_reg.fpath_48_7=/dev/cpld3 +sff_cpld_reg.addr_48_7=0x81 +sff_cpld_reg.len_48_7=1 +sff_cpld_reg.val_type_48_7=nega_key + +sff_cpld_reg.mode_49_7=config +sff_cpld_reg.src_49_7=logic_file +sff_cpld_reg.frmt_49_7=byte +sff_cpld_reg.pola_49_7=positive +sff_cpld_reg.fpath_49_7=/dev/cpld3 +sff_cpld_reg.addr_49_7=0x82 +sff_cpld_reg.len_49_7=1 +sff_cpld_reg.val_type_49_7=nega_key + +sff_cpld_reg.mode_50_7=config +sff_cpld_reg.src_50_7=logic_file +sff_cpld_reg.frmt_50_7=byte +sff_cpld_reg.pola_50_7=positive +sff_cpld_reg.fpath_50_7=/dev/cpld3 +sff_cpld_reg.addr_50_7=0x83 +sff_cpld_reg.len_50_7=1 +sff_cpld_reg.val_type_50_7=nega_key + +sff_cpld_reg.mode_51_7=config +sff_cpld_reg.src_51_7=logic_file +sff_cpld_reg.frmt_51_7=byte +sff_cpld_reg.pola_51_7=positive +sff_cpld_reg.fpath_51_7=/dev/cpld3 +sff_cpld_reg.addr_51_7=0x84 +sff_cpld_reg.len_51_7=1 +sff_cpld_reg.val_type_51_7=nega_key + +sff_cpld_reg.mode_52_7=config +sff_cpld_reg.src_52_7=logic_file +sff_cpld_reg.frmt_52_7=byte +sff_cpld_reg.pola_52_7=positive +sff_cpld_reg.fpath_52_7=/dev/cpld3 +sff_cpld_reg.addr_52_7=0x85 +sff_cpld_reg.len_52_7=1 +sff_cpld_reg.val_type_52_7=nega_key + +sff_cpld_reg.mode_53_7=config +sff_cpld_reg.src_53_7=logic_file +sff_cpld_reg.frmt_53_7=byte +sff_cpld_reg.pola_53_7=positive +sff_cpld_reg.fpath_53_7=/dev/cpld3 +sff_cpld_reg.addr_53_7=0x86 +sff_cpld_reg.len_53_7=1 +sff_cpld_reg.val_type_53_7=nega_key + +sff_cpld_reg.mode_54_7=config +sff_cpld_reg.src_54_7=logic_file +sff_cpld_reg.frmt_54_7=byte +sff_cpld_reg.pola_54_7=positive +sff_cpld_reg.fpath_54_7=/dev/cpld3 +sff_cpld_reg.addr_54_7=0x87 +sff_cpld_reg.len_54_7=1 +sff_cpld_reg.val_type_54_7=nega_key + +sff_cpld_reg.mode_55_7=config +sff_cpld_reg.src_55_7=logic_file +sff_cpld_reg.frmt_55_7=byte +sff_cpld_reg.pola_55_7=positive +sff_cpld_reg.fpath_55_7=/dev/cpld3 +sff_cpld_reg.addr_55_7=0x88 +sff_cpld_reg.len_55_7=1 +sff_cpld_reg.val_type_55_7=nega_key + +sff_cpld_reg.mode_56_7=config +sff_cpld_reg.src_56_7=logic_file +sff_cpld_reg.frmt_56_7=byte +sff_cpld_reg.pola_56_7=positive +sff_cpld_reg.fpath_56_7=/dev/cpld3 +sff_cpld_reg.addr_56_7=0x89 +sff_cpld_reg.len_56_7=1 +sff_cpld_reg.val_type_56_7=nega_key + +sff_cpld_reg.mode_57_7=config +sff_cpld_reg.src_57_7=logic_file +sff_cpld_reg.frmt_57_7=byte +sff_cpld_reg.pola_57_7=positive +sff_cpld_reg.fpath_57_7=/dev/cpld3 +sff_cpld_reg.addr_57_7=0x8a +sff_cpld_reg.len_57_7=1 +sff_cpld_reg.val_type_57_7=nega_key + +sff_cpld_reg.mode_58_7=config +sff_cpld_reg.src_58_7=logic_file +sff_cpld_reg.frmt_58_7=byte +sff_cpld_reg.pola_58_7=positive +sff_cpld_reg.fpath_58_7=/dev/cpld3 +sff_cpld_reg.addr_58_7=0x8b +sff_cpld_reg.len_58_7=1 +sff_cpld_reg.val_type_58_7=nega_key + +sff_cpld_reg.mode_59_7=config +sff_cpld_reg.src_59_7=logic_file +sff_cpld_reg.frmt_59_7=byte +sff_cpld_reg.pola_59_7=positive +sff_cpld_reg.fpath_59_7=/dev/cpld3 +sff_cpld_reg.addr_59_7=0x8c +sff_cpld_reg.len_59_7=1 +sff_cpld_reg.val_type_59_7=nega_key + +sff_cpld_reg.mode_60_7=config +sff_cpld_reg.src_60_7=logic_file +sff_cpld_reg.frmt_60_7=byte +sff_cpld_reg.pola_60_7=positive +sff_cpld_reg.fpath_60_7=/dev/cpld3 +sff_cpld_reg.addr_60_7=0x8d +sff_cpld_reg.len_60_7=1 +sff_cpld_reg.val_type_60_7=nega_key + +sff_cpld_reg.mode_61_7=config +sff_cpld_reg.src_61_7=logic_file +sff_cpld_reg.frmt_61_7=byte +sff_cpld_reg.pola_61_7=positive +sff_cpld_reg.fpath_61_7=/dev/cpld3 +sff_cpld_reg.addr_61_7=0x8e +sff_cpld_reg.len_61_7=1 +sff_cpld_reg.val_type_61_7=nega_key + +sff_cpld_reg.mode_62_7=config +sff_cpld_reg.src_62_7=logic_file +sff_cpld_reg.frmt_62_7=byte +sff_cpld_reg.pola_62_7=positive +sff_cpld_reg.fpath_62_7=/dev/cpld3 +sff_cpld_reg.addr_62_7=0x8f +sff_cpld_reg.len_62_7=1 +sff_cpld_reg.val_type_62_7=nega_key + +sff_cpld_reg.mode_63_7=config +sff_cpld_reg.src_63_7=logic_file +sff_cpld_reg.frmt_63_7=byte +sff_cpld_reg.pola_63_7=positive +sff_cpld_reg.fpath_63_7=/dev/cpld3 +sff_cpld_reg.addr_63_7=0x90 +sff_cpld_reg.len_63_7=1 +sff_cpld_reg.val_type_63_7=nega_key + +sff_cpld_reg.mode_64_7=config +sff_cpld_reg.src_64_7=logic_file +sff_cpld_reg.frmt_64_7=byte +sff_cpld_reg.pola_64_7=positive +sff_cpld_reg.fpath_64_7=/dev/cpld3 +sff_cpld_reg.addr_64_7=0x91 +sff_cpld_reg.len_64_7=1 +sff_cpld_reg.val_type_64_7=nega_key + +sff_cpld_reg.mode_65_7=config +sff_cpld_reg.src_65_7=logic_file +sff_cpld_reg.frmt_65_7=byte +sff_cpld_reg.pola_65_7=positive +sff_cpld_reg.fpath_65_7=/dev/cpld2 +sff_cpld_reg.addr_65_7=0x7e +sff_cpld_reg.len_65_7=1 +sff_cpld_reg.val_type_65_7=nega_key + +sff_cpld_reg.mode_66_7=config +sff_cpld_reg.src_66_7=logic_file +sff_cpld_reg.frmt_66_7=byte +sff_cpld_reg.pola_66_7=positive +sff_cpld_reg.fpath_66_7=/dev/cpld2 +sff_cpld_reg.addr_66_7=0x7f +sff_cpld_reg.len_66_7=1 +sff_cpld_reg.val_type_66_7=nega_key + +sff_cpld_reg.mode_67_7=config +sff_cpld_reg.src_67_7=logic_file +sff_cpld_reg.frmt_67_7=byte +sff_cpld_reg.pola_67_7=positive +sff_cpld_reg.fpath_67_7=/dev/cpld2 +sff_cpld_reg.addr_67_7=0x80 +sff_cpld_reg.len_67_7=1 +sff_cpld_reg.val_type_67_7=nega_key + +sff_cpld_reg.mode_68_7=config +sff_cpld_reg.src_68_7=logic_file +sff_cpld_reg.frmt_68_7=byte +sff_cpld_reg.pola_68_7=positive +sff_cpld_reg.fpath_68_7=/dev/cpld2 +sff_cpld_reg.addr_68_7=0x81 +sff_cpld_reg.len_68_7=1 +sff_cpld_reg.val_type_68_7=nega_key + +sff_cpld_reg.mode_69_7=config +sff_cpld_reg.src_69_7=logic_file +sff_cpld_reg.frmt_69_7=byte +sff_cpld_reg.pola_69_7=positive +sff_cpld_reg.fpath_69_7=/dev/cpld2 +sff_cpld_reg.addr_69_7=0x82 +sff_cpld_reg.len_69_7=1 +sff_cpld_reg.val_type_69_7=nega_key + +sff_cpld_reg.mode_70_7=config +sff_cpld_reg.src_70_7=logic_file +sff_cpld_reg.frmt_70_7=byte +sff_cpld_reg.pola_70_7=positive +sff_cpld_reg.fpath_70_7=/dev/cpld2 +sff_cpld_reg.addr_70_7=0x83 +sff_cpld_reg.len_70_7=1 +sff_cpld_reg.val_type_70_7=nega_key + +sff_cpld_reg.mode_71_7=config +sff_cpld_reg.src_71_7=logic_file +sff_cpld_reg.frmt_71_7=byte +sff_cpld_reg.pola_71_7=positive +sff_cpld_reg.fpath_71_7=/dev/cpld2 +sff_cpld_reg.addr_71_7=0x84 +sff_cpld_reg.len_71_7=1 +sff_cpld_reg.val_type_71_7=nega_key + +sff_cpld_reg.mode_72_7=config +sff_cpld_reg.src_72_7=logic_file +sff_cpld_reg.frmt_72_7=byte +sff_cpld_reg.pola_72_7=positive +sff_cpld_reg.fpath_72_7=/dev/cpld2 +sff_cpld_reg.addr_72_7=0x85 +sff_cpld_reg.len_72_7=1 +sff_cpld_reg.val_type_72_7=nega_key + +sff_cpld_reg.mode_73_7=config +sff_cpld_reg.src_73_7=logic_file +sff_cpld_reg.frmt_73_7=byte +sff_cpld_reg.pola_73_7=positive +sff_cpld_reg.fpath_73_7=/dev/cpld2 +sff_cpld_reg.addr_73_7=0x86 +sff_cpld_reg.len_73_7=1 +sff_cpld_reg.val_type_73_7=nega_key + +sff_cpld_reg.mode_74_7=config +sff_cpld_reg.src_74_7=logic_file +sff_cpld_reg.frmt_74_7=byte +sff_cpld_reg.pola_74_7=positive +sff_cpld_reg.fpath_74_7=/dev/cpld2 +sff_cpld_reg.addr_74_7=0x87 +sff_cpld_reg.len_74_7=1 +sff_cpld_reg.val_type_74_7=nega_key + +sff_cpld_reg.mode_75_7=config +sff_cpld_reg.src_75_7=logic_file +sff_cpld_reg.frmt_75_7=byte +sff_cpld_reg.pola_75_7=positive +sff_cpld_reg.fpath_75_7=/dev/cpld3 +sff_cpld_reg.addr_75_7=0x92 +sff_cpld_reg.len_75_7=1 +sff_cpld_reg.val_type_75_7=nega_key + +sff_cpld_reg.mode_76_7=config +sff_cpld_reg.src_76_7=logic_file +sff_cpld_reg.frmt_76_7=byte +sff_cpld_reg.pola_76_7=positive +sff_cpld_reg.fpath_76_7=/dev/cpld3 +sff_cpld_reg.addr_76_7=0x93 +sff_cpld_reg.len_76_7=1 +sff_cpld_reg.val_type_76_7=nega_key + +sff_cpld_reg.mode_77_7=config +sff_cpld_reg.src_77_7=logic_file +sff_cpld_reg.frmt_77_7=byte +sff_cpld_reg.pola_77_7=positive +sff_cpld_reg.fpath_77_7=/dev/cpld3 +sff_cpld_reg.addr_77_7=0x94 +sff_cpld_reg.len_77_7=1 +sff_cpld_reg.val_type_77_7=nega_key + +sff_cpld_reg.mode_78_7=config +sff_cpld_reg.src_78_7=logic_file +sff_cpld_reg.frmt_78_7=byte +sff_cpld_reg.pola_78_7=positive +sff_cpld_reg.fpath_78_7=/dev/cpld3 +sff_cpld_reg.addr_78_7=0x95 +sff_cpld_reg.len_78_7=1 +sff_cpld_reg.val_type_78_7=nega_key + +sff_cpld_reg.mode_79_7=config +sff_cpld_reg.src_79_7=logic_file +sff_cpld_reg.frmt_79_7=byte +sff_cpld_reg.pola_79_7=positive +sff_cpld_reg.fpath_79_7=/dev/cpld3 +sff_cpld_reg.addr_79_7=0x96 +sff_cpld_reg.len_79_7=1 +sff_cpld_reg.val_type_79_7=nega_key + +sff_cpld_reg.mode_80_7=config +sff_cpld_reg.src_80_7=logic_file +sff_cpld_reg.frmt_80_7=byte +sff_cpld_reg.pola_80_7=positive +sff_cpld_reg.fpath_80_7=/dev/cpld3 +sff_cpld_reg.addr_80_7=0x97 +sff_cpld_reg.len_80_7=1 +sff_cpld_reg.val_type_80_7=nega_key + +sff_cpld_reg.mode_81_7=config +sff_cpld_reg.src_81_7=logic_file +sff_cpld_reg.frmt_81_7=byte +sff_cpld_reg.pola_81_7=positive +sff_cpld_reg.fpath_81_7=/dev/cpld3 +sff_cpld_reg.addr_81_7=0x98 +sff_cpld_reg.len_81_7=1 +sff_cpld_reg.val_type_81_7=nega_key + +sff_cpld_reg.mode_82_7=config +sff_cpld_reg.src_82_7=logic_file +sff_cpld_reg.frmt_82_7=byte +sff_cpld_reg.pola_82_7=positive +sff_cpld_reg.fpath_82_7=/dev/cpld3 +sff_cpld_reg.addr_82_7=0x99 +sff_cpld_reg.len_82_7=1 +sff_cpld_reg.val_type_82_7=nega_key + +sff_cpld_reg.mode_83_7=config +sff_cpld_reg.src_83_7=logic_file +sff_cpld_reg.frmt_83_7=byte +sff_cpld_reg.pola_83_7=positive +sff_cpld_reg.fpath_83_7=/dev/cpld3 +sff_cpld_reg.addr_83_7=0x9a +sff_cpld_reg.len_83_7=1 +sff_cpld_reg.val_type_83_7=nega_key + +sff_cpld_reg.mode_84_7=config +sff_cpld_reg.src_84_7=logic_file +sff_cpld_reg.frmt_84_7=byte +sff_cpld_reg.pola_84_7=positive +sff_cpld_reg.fpath_84_7=/dev/cpld3 +sff_cpld_reg.addr_84_7=0x9b +sff_cpld_reg.len_84_7=1 +sff_cpld_reg.val_type_84_7=nega_key + +sff_cpld_reg.mode_85_7=config +sff_cpld_reg.src_85_7=logic_file +sff_cpld_reg.frmt_85_7=byte +sff_cpld_reg.pola_85_7=positive +sff_cpld_reg.fpath_85_7=/dev/cpld3 +sff_cpld_reg.addr_85_7=0x9c +sff_cpld_reg.len_85_7=1 +sff_cpld_reg.val_type_85_7=nega_key + +sff_cpld_reg.mode_86_7=config +sff_cpld_reg.src_86_7=logic_file +sff_cpld_reg.frmt_86_7=byte +sff_cpld_reg.pola_86_7=positive +sff_cpld_reg.fpath_86_7=/dev/cpld3 +sff_cpld_reg.addr_86_7=0x9d +sff_cpld_reg.len_86_7=1 +sff_cpld_reg.val_type_86_7=nega_key + +sff_cpld_reg.mode_87_7=config +sff_cpld_reg.src_87_7=logic_file +sff_cpld_reg.frmt_87_7=byte +sff_cpld_reg.pola_87_7=positive +sff_cpld_reg.fpath_87_7=/dev/cpld3 +sff_cpld_reg.addr_87_7=0x9e +sff_cpld_reg.len_87_7=1 +sff_cpld_reg.val_type_87_7=nega_key + +sff_cpld_reg.mode_88_7=config +sff_cpld_reg.src_88_7=logic_file +sff_cpld_reg.frmt_88_7=byte +sff_cpld_reg.pola_88_7=positive +sff_cpld_reg.fpath_88_7=/dev/cpld3 +sff_cpld_reg.addr_88_7=0x9f +sff_cpld_reg.len_88_7=1 +sff_cpld_reg.val_type_88_7=nega_key + +sff_cpld_reg.mode_89_7=config +sff_cpld_reg.src_89_7=logic_file +sff_cpld_reg.frmt_89_7=byte +sff_cpld_reg.pola_89_7=positive +sff_cpld_reg.fpath_89_7=/dev/cpld3 +sff_cpld_reg.addr_89_7=0xa0 +sff_cpld_reg.len_89_7=1 +sff_cpld_reg.val_type_89_7=nega_key + +sff_cpld_reg.mode_90_7=config +sff_cpld_reg.src_90_7=logic_file +sff_cpld_reg.frmt_90_7=byte +sff_cpld_reg.pola_90_7=positive +sff_cpld_reg.fpath_90_7=/dev/cpld3 +sff_cpld_reg.addr_90_7=0xa1 +sff_cpld_reg.len_90_7=1 +sff_cpld_reg.val_type_90_7=nega_key + +sff_cpld_reg.mode_91_7=config +sff_cpld_reg.src_91_7=logic_file +sff_cpld_reg.frmt_91_7=byte +sff_cpld_reg.pola_91_7=positive +sff_cpld_reg.fpath_91_7=/dev/cpld3 +sff_cpld_reg.addr_91_7=0xa2 +sff_cpld_reg.len_91_7=1 +sff_cpld_reg.val_type_91_7=nega_key + +sff_cpld_reg.mode_92_7=config +sff_cpld_reg.src_92_7=logic_file +sff_cpld_reg.frmt_92_7=byte +sff_cpld_reg.pola_92_7=positive +sff_cpld_reg.fpath_92_7=/dev/cpld3 +sff_cpld_reg.addr_92_7=0xa3 +sff_cpld_reg.len_92_7=1 +sff_cpld_reg.val_type_92_7=nega_key + +sff_cpld_reg.mode_93_7=config +sff_cpld_reg.src_93_7=logic_file +sff_cpld_reg.frmt_93_7=byte +sff_cpld_reg.pola_93_7=positive +sff_cpld_reg.fpath_93_7=/dev/cpld3 +sff_cpld_reg.addr_93_7=0xa4 +sff_cpld_reg.len_93_7=1 +sff_cpld_reg.val_type_93_7=nega_key + +sff_cpld_reg.mode_94_7=config +sff_cpld_reg.src_94_7=logic_file +sff_cpld_reg.frmt_94_7=byte +sff_cpld_reg.pola_94_7=positive +sff_cpld_reg.fpath_94_7=/dev/cpld3 +sff_cpld_reg.addr_94_7=0xa5 +sff_cpld_reg.len_94_7=1 +sff_cpld_reg.val_type_94_7=nega_key + +sff_cpld_reg.mode_95_7=config +sff_cpld_reg.src_95_7=logic_file +sff_cpld_reg.frmt_95_7=byte +sff_cpld_reg.pola_95_7=positive +sff_cpld_reg.fpath_95_7=/dev/cpld3 +sff_cpld_reg.addr_95_7=0xa6 +sff_cpld_reg.len_95_7=1 +sff_cpld_reg.val_type_95_7=nega_key + +sff_cpld_reg.mode_96_7=config +sff_cpld_reg.src_96_7=logic_file +sff_cpld_reg.frmt_96_7=byte +sff_cpld_reg.pola_96_7=positive +sff_cpld_reg.fpath_96_7=/dev/cpld3 +sff_cpld_reg.addr_96_7=0xa7 +sff_cpld_reg.len_96_7=1 +sff_cpld_reg.val_type_96_7=nega_key + +sff_cpld_reg.mode_97_7=config +sff_cpld_reg.src_97_7=logic_file +sff_cpld_reg.frmt_97_7=byte +sff_cpld_reg.pola_97_7=positive +sff_cpld_reg.fpath_97_7=/dev/cpld6 +sff_cpld_reg.addr_97_7=0x70 +sff_cpld_reg.len_97_7=1 +sff_cpld_reg.val_type_97_7=nega_key + +sff_cpld_reg.mode_98_7=config +sff_cpld_reg.src_98_7=logic_file +sff_cpld_reg.frmt_98_7=byte +sff_cpld_reg.pola_98_7=positive +sff_cpld_reg.fpath_98_7=/dev/cpld6 +sff_cpld_reg.addr_98_7=0x71 +sff_cpld_reg.len_98_7=1 +sff_cpld_reg.val_type_98_7=nega_key + +sff_cpld_reg.mode_99_7=config +sff_cpld_reg.src_99_7=logic_file +sff_cpld_reg.frmt_99_7=byte +sff_cpld_reg.pola_99_7=positive +sff_cpld_reg.fpath_99_7=/dev/cpld6 +sff_cpld_reg.addr_99_7=0x72 +sff_cpld_reg.len_99_7=1 +sff_cpld_reg.val_type_99_7=nega_key + +sff_cpld_reg.mode_100_7=config +sff_cpld_reg.src_100_7=logic_file +sff_cpld_reg.frmt_100_7=byte +sff_cpld_reg.pola_100_7=positive +sff_cpld_reg.fpath_100_7=/dev/cpld6 +sff_cpld_reg.addr_100_7=0x73 +sff_cpld_reg.len_100_7=1 +sff_cpld_reg.val_type_100_7=nega_key + +sff_cpld_reg.mode_101_7=config +sff_cpld_reg.src_101_7=logic_file +sff_cpld_reg.frmt_101_7=byte +sff_cpld_reg.pola_101_7=positive +sff_cpld_reg.fpath_101_7=/dev/cpld6 +sff_cpld_reg.addr_101_7=0x74 +sff_cpld_reg.len_101_7=1 +sff_cpld_reg.val_type_101_7=nega_key + +sff_cpld_reg.mode_102_7=config +sff_cpld_reg.src_102_7=logic_file +sff_cpld_reg.frmt_102_7=byte +sff_cpld_reg.pola_102_7=positive +sff_cpld_reg.fpath_102_7=/dev/cpld6 +sff_cpld_reg.addr_102_7=0x75 +sff_cpld_reg.len_102_7=1 +sff_cpld_reg.val_type_102_7=nega_key + +sff_cpld_reg.mode_103_7=config +sff_cpld_reg.src_103_7=logic_file +sff_cpld_reg.frmt_103_7=byte +sff_cpld_reg.pola_103_7=positive +sff_cpld_reg.fpath_103_7=/dev/cpld6 +sff_cpld_reg.addr_103_7=0x76 +sff_cpld_reg.len_103_7=1 +sff_cpld_reg.val_type_103_7=nega_key + +sff_cpld_reg.mode_104_7=config +sff_cpld_reg.src_104_7=logic_file +sff_cpld_reg.frmt_104_7=byte +sff_cpld_reg.pola_104_7=positive +sff_cpld_reg.fpath_104_7=/dev/cpld6 +sff_cpld_reg.addr_104_7=0x77 +sff_cpld_reg.len_104_7=1 +sff_cpld_reg.val_type_104_7=nega_key + +sff_cpld_reg.mode_105_7=config +sff_cpld_reg.src_105_7=logic_file +sff_cpld_reg.frmt_105_7=byte +sff_cpld_reg.pola_105_7=positive +sff_cpld_reg.fpath_105_7=/dev/cpld6 +sff_cpld_reg.addr_105_7=0x78 +sff_cpld_reg.len_105_7=1 +sff_cpld_reg.val_type_105_7=nega_key + +sff_cpld_reg.mode_106_7=config +sff_cpld_reg.src_106_7=logic_file +sff_cpld_reg.frmt_106_7=byte +sff_cpld_reg.pola_106_7=positive +sff_cpld_reg.fpath_106_7=/dev/cpld6 +sff_cpld_reg.addr_106_7=0x79 +sff_cpld_reg.len_106_7=1 +sff_cpld_reg.val_type_106_7=nega_key + +sff_cpld_reg.mode_107_7=config +sff_cpld_reg.src_107_7=logic_file +sff_cpld_reg.frmt_107_7=byte +sff_cpld_reg.pola_107_7=positive +sff_cpld_reg.fpath_107_7=/dev/cpld6 +sff_cpld_reg.addr_107_7=0x7a +sff_cpld_reg.len_107_7=1 +sff_cpld_reg.val_type_107_7=nega_key + +sff_cpld_reg.mode_108_7=config +sff_cpld_reg.src_108_7=logic_file +sff_cpld_reg.frmt_108_7=byte +sff_cpld_reg.pola_108_7=positive +sff_cpld_reg.fpath_108_7=/dev/cpld6 +sff_cpld_reg.addr_108_7=0x7b +sff_cpld_reg.len_108_7=1 +sff_cpld_reg.val_type_108_7=nega_key + +sff_cpld_reg.mode_109_7=config +sff_cpld_reg.src_109_7=logic_file +sff_cpld_reg.frmt_109_7=byte +sff_cpld_reg.pola_109_7=positive +sff_cpld_reg.fpath_109_7=/dev/cpld6 +sff_cpld_reg.addr_109_7=0x7c +sff_cpld_reg.len_109_7=1 +sff_cpld_reg.val_type_109_7=nega_key + +sff_cpld_reg.mode_110_7=config +sff_cpld_reg.src_110_7=logic_file +sff_cpld_reg.frmt_110_7=byte +sff_cpld_reg.pola_110_7=positive +sff_cpld_reg.fpath_110_7=/dev/cpld6 +sff_cpld_reg.addr_110_7=0x7d +sff_cpld_reg.len_110_7=1 +sff_cpld_reg.val_type_110_7=nega_key + +sff_cpld_reg.mode_111_7=config +sff_cpld_reg.src_111_7=logic_file +sff_cpld_reg.frmt_111_7=byte +sff_cpld_reg.pola_111_7=positive +sff_cpld_reg.fpath_111_7=/dev/cpld6 +sff_cpld_reg.addr_111_7=0x7e +sff_cpld_reg.len_111_7=1 +sff_cpld_reg.val_type_111_7=nega_key + +sff_cpld_reg.mode_112_7=config +sff_cpld_reg.src_112_7=logic_file +sff_cpld_reg.frmt_112_7=byte +sff_cpld_reg.pola_112_7=positive +sff_cpld_reg.fpath_112_7=/dev/cpld6 +sff_cpld_reg.addr_112_7=0x7f +sff_cpld_reg.len_112_7=1 +sff_cpld_reg.val_type_112_7=nega_key + +sff_cpld_reg.mode_113_7=config +sff_cpld_reg.src_113_7=logic_file +sff_cpld_reg.frmt_113_7=byte +sff_cpld_reg.pola_113_7=positive +sff_cpld_reg.fpath_113_7=/dev/cpld6 +sff_cpld_reg.addr_113_7=0x80 +sff_cpld_reg.len_113_7=1 +sff_cpld_reg.val_type_113_7=nega_key + +sff_cpld_reg.mode_114_7=config +sff_cpld_reg.src_114_7=logic_file +sff_cpld_reg.frmt_114_7=byte +sff_cpld_reg.pola_114_7=positive +sff_cpld_reg.fpath_114_7=/dev/cpld6 +sff_cpld_reg.addr_114_7=0x81 +sff_cpld_reg.len_114_7=1 +sff_cpld_reg.val_type_114_7=nega_key + +sff_cpld_reg.mode_115_7=config +sff_cpld_reg.src_115_7=logic_file +sff_cpld_reg.frmt_115_7=byte +sff_cpld_reg.pola_115_7=positive +sff_cpld_reg.fpath_115_7=/dev/cpld6 +sff_cpld_reg.addr_115_7=0x82 +sff_cpld_reg.len_115_7=1 +sff_cpld_reg.val_type_115_7=nega_key + +sff_cpld_reg.mode_116_7=config +sff_cpld_reg.src_116_7=logic_file +sff_cpld_reg.frmt_116_7=byte +sff_cpld_reg.pola_116_7=positive +sff_cpld_reg.fpath_116_7=/dev/cpld6 +sff_cpld_reg.addr_116_7=0x83 +sff_cpld_reg.len_116_7=1 +sff_cpld_reg.val_type_116_7=nega_key + +sff_cpld_reg.mode_117_7=config +sff_cpld_reg.src_117_7=logic_file +sff_cpld_reg.frmt_117_7=byte +sff_cpld_reg.pola_117_7=positive +sff_cpld_reg.fpath_117_7=/dev/cpld6 +sff_cpld_reg.addr_117_7=0x84 +sff_cpld_reg.len_117_7=1 +sff_cpld_reg.val_type_117_7=nega_key + +sff_cpld_reg.mode_118_7=config +sff_cpld_reg.src_118_7=logic_file +sff_cpld_reg.frmt_118_7=byte +sff_cpld_reg.pola_118_7=positive +sff_cpld_reg.fpath_118_7=/dev/cpld6 +sff_cpld_reg.addr_118_7=0x85 +sff_cpld_reg.len_118_7=1 +sff_cpld_reg.val_type_118_7=nega_key + +sff_cpld_reg.mode_119_7=config +sff_cpld_reg.src_119_7=logic_file +sff_cpld_reg.frmt_119_7=byte +sff_cpld_reg.pola_119_7=positive +sff_cpld_reg.fpath_119_7=/dev/cpld6 +sff_cpld_reg.addr_119_7=0x86 +sff_cpld_reg.len_119_7=1 +sff_cpld_reg.val_type_119_7=nega_key + +sff_cpld_reg.mode_120_7=config +sff_cpld_reg.src_120_7=logic_file +sff_cpld_reg.frmt_120_7=byte +sff_cpld_reg.pola_120_7=positive +sff_cpld_reg.fpath_120_7=/dev/cpld6 +sff_cpld_reg.addr_120_7=0x87 +sff_cpld_reg.len_120_7=1 +sff_cpld_reg.val_type_120_7=nega_key + +sff_cpld_reg.mode_121_7=config +sff_cpld_reg.src_121_7=logic_file +sff_cpld_reg.frmt_121_7=byte +sff_cpld_reg.pola_121_7=positive +sff_cpld_reg.fpath_121_7=/dev/cpld6 +sff_cpld_reg.addr_121_7=0x88 +sff_cpld_reg.len_121_7=1 +sff_cpld_reg.val_type_121_7=nega_key + +sff_cpld_reg.mode_122_7=config +sff_cpld_reg.src_122_7=logic_file +sff_cpld_reg.frmt_122_7=byte +sff_cpld_reg.pola_122_7=positive +sff_cpld_reg.fpath_122_7=/dev/cpld6 +sff_cpld_reg.addr_122_7=0x89 +sff_cpld_reg.len_122_7=1 +sff_cpld_reg.val_type_122_7=nega_key + +sff_cpld_reg.mode_123_7=config +sff_cpld_reg.src_123_7=logic_file +sff_cpld_reg.frmt_123_7=byte +sff_cpld_reg.pola_123_7=positive +sff_cpld_reg.fpath_123_7=/dev/cpld6 +sff_cpld_reg.addr_123_7=0x8a +sff_cpld_reg.len_123_7=1 +sff_cpld_reg.val_type_123_7=nega_key + +sff_cpld_reg.mode_124_7=config +sff_cpld_reg.src_124_7=logic_file +sff_cpld_reg.frmt_124_7=byte +sff_cpld_reg.pola_124_7=positive +sff_cpld_reg.fpath_124_7=/dev/cpld6 +sff_cpld_reg.addr_124_7=0x8b +sff_cpld_reg.len_124_7=1 +sff_cpld_reg.val_type_124_7=nega_key + +sff_cpld_reg.mode_125_7=config +sff_cpld_reg.src_125_7=logic_file +sff_cpld_reg.frmt_125_7=byte +sff_cpld_reg.pola_125_7=positive +sff_cpld_reg.fpath_125_7=/dev/cpld6 +sff_cpld_reg.addr_125_7=0x8c +sff_cpld_reg.len_125_7=1 +sff_cpld_reg.val_type_125_7=nega_key + +sff_cpld_reg.mode_126_7=config +sff_cpld_reg.src_126_7=logic_file +sff_cpld_reg.frmt_126_7=byte +sff_cpld_reg.pola_126_7=positive +sff_cpld_reg.fpath_126_7=/dev/cpld6 +sff_cpld_reg.addr_126_7=0x8d +sff_cpld_reg.len_126_7=1 +sff_cpld_reg.val_type_126_7=nega_key + +sff_cpld_reg.mode_127_7=config +sff_cpld_reg.src_127_7=logic_file +sff_cpld_reg.frmt_127_7=byte +sff_cpld_reg.pola_127_7=positive +sff_cpld_reg.fpath_127_7=/dev/cpld6 +sff_cpld_reg.addr_127_7=0x8e +sff_cpld_reg.len_127_7=1 +sff_cpld_reg.val_type_127_7=nega_key + +sff_cpld_reg.mode_128_7=config +sff_cpld_reg.src_128_7=logic_file +sff_cpld_reg.frmt_128_7=byte +sff_cpld_reg.pola_128_7=positive +sff_cpld_reg.fpath_128_7=/dev/cpld6 +sff_cpld_reg.addr_128_7=0x8f +sff_cpld_reg.len_128_7=1 +sff_cpld_reg.val_type_128_7=nega_key + +sff_cpld_reg.mode_129_7=config +sff_cpld_reg.src_129_7=logic_file +sff_cpld_reg.frmt_129_7=byte +sff_cpld_reg.pola_129_7=positive +sff_cpld_reg.fpath_129_7=/dev/cpld1 +sff_cpld_reg.addr_129_7=0xde +sff_cpld_reg.len_129_7=1 +sff_cpld_reg.val_type_129_7=nega_key + +# 800G module present signal +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=logic_file +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.fpath_1_8=/dev/cpld5 +sff_cpld_reg.addr_1_8=0x38 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=logic_file +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.fpath_2_8=/dev/cpld5 +sff_cpld_reg.addr_2_8=0x38 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=logic_file +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.fpath_3_8=/dev/cpld5 +sff_cpld_reg.addr_3_8=0x38 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=logic_file +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.fpath_4_8=/dev/cpld5 +sff_cpld_reg.addr_4_8=0x38 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=logic_file +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.fpath_5_8=/dev/cpld5 +sff_cpld_reg.addr_5_8=0x38 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=logic_file +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.fpath_6_8=/dev/cpld5 +sff_cpld_reg.addr_6_8=0x38 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=logic_file +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.fpath_7_8=/dev/cpld5 +sff_cpld_reg.addr_7_8=0x38 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=logic_file +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.fpath_8_8=/dev/cpld5 +sff_cpld_reg.addr_8_8=0x38 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=logic_file +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.fpath_9_8=/dev/cpld5 +sff_cpld_reg.addr_9_8=0x39 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=logic_file +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.fpath_10_8=/dev/cpld5 +sff_cpld_reg.addr_10_8=0x39 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=logic_file +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.fpath_11_8=/dev/cpld5 +sff_cpld_reg.addr_11_8=0x39 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=logic_file +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.fpath_12_8=/dev/cpld5 +sff_cpld_reg.addr_12_8=0x39 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=logic_file +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.fpath_13_8=/dev/cpld5 +sff_cpld_reg.addr_13_8=0x39 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=logic_file +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.fpath_14_8=/dev/cpld5 +sff_cpld_reg.addr_14_8=0x39 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=logic_file +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.fpath_15_8=/dev/cpld5 +sff_cpld_reg.addr_15_8=0x39 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=logic_file +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.fpath_16_8=/dev/cpld5 +sff_cpld_reg.addr_16_8=0x39 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=logic_file +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.fpath_17_8=/dev/cpld5 +sff_cpld_reg.addr_17_8=0x3a +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=logic_file +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.fpath_18_8=/dev/cpld5 +sff_cpld_reg.addr_18_8=0x3a +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=logic_file +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.fpath_19_8=/dev/cpld5 +sff_cpld_reg.addr_19_8=0x3a +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=logic_file +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.fpath_20_8=/dev/cpld5 +sff_cpld_reg.addr_20_8=0x3a +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=logic_file +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.fpath_21_8=/dev/cpld5 +sff_cpld_reg.addr_21_8=0x3a +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=logic_file +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.fpath_22_8=/dev/cpld5 +sff_cpld_reg.addr_22_8=0x3a +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=logic_file +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.fpath_23_8=/dev/cpld5 +sff_cpld_reg.addr_23_8=0x3a +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=logic_file +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.fpath_24_8=/dev/cpld5 +sff_cpld_reg.addr_24_8=0x3a +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=logic_file +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.fpath_25_8=/dev/cpld5 +sff_cpld_reg.addr_25_8=0x3b +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=logic_file +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.fpath_26_8=/dev/cpld5 +sff_cpld_reg.addr_26_8=0x3b +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=logic_file +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.fpath_27_8=/dev/cpld5 +sff_cpld_reg.addr_27_8=0x3b +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=logic_file +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.fpath_28_8=/dev/cpld5 +sff_cpld_reg.addr_28_8=0x3b +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=logic_file +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.fpath_29_8=/dev/cpld5 +sff_cpld_reg.addr_29_8=0x3b +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=logic_file +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.fpath_30_8=/dev/cpld5 +sff_cpld_reg.addr_30_8=0x3b +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=logic_file +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.fpath_31_8=/dev/cpld5 +sff_cpld_reg.addr_31_8=0x3b +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=logic_file +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.fpath_32_8=/dev/cpld5 +sff_cpld_reg.addr_32_8=0x3b +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=logic_file +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.fpath_33_8=/dev/cpld2 +sff_cpld_reg.addr_33_8=0x3c +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=logic_file +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.fpath_34_8=/dev/cpld2 +sff_cpld_reg.addr_34_8=0x3c +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=logic_file +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.fpath_35_8=/dev/cpld2 +sff_cpld_reg.addr_35_8=0x3c +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=2 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=logic_file +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.fpath_36_8=/dev/cpld2 +sff_cpld_reg.addr_36_8=0x3c +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=3 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=logic_file +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.fpath_37_8=/dev/cpld2 +sff_cpld_reg.addr_37_8=0x3c +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=4 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=logic_file +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.fpath_38_8=/dev/cpld2 +sff_cpld_reg.addr_38_8=0x3c +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=5 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=logic_file +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.fpath_39_8=/dev/cpld2 +sff_cpld_reg.addr_39_8=0x3c +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=6 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=logic_file +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.fpath_40_8=/dev/cpld2 +sff_cpld_reg.addr_40_8=0x3c +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=7 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=logic_file +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.fpath_41_8=/dev/cpld2 +sff_cpld_reg.addr_41_8=0x3d +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=0 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=logic_file +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.fpath_42_8=/dev/cpld2 +sff_cpld_reg.addr_42_8=0x3d +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=1 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=logic_file +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.fpath_43_8=/dev/cpld3 +sff_cpld_reg.addr_43_8=0x21 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=0 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=logic_file +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.fpath_44_8=/dev/cpld3 +sff_cpld_reg.addr_44_8=0x21 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=1 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=logic_file +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.fpath_45_8=/dev/cpld3 +sff_cpld_reg.addr_45_8=0x21 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=2 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=logic_file +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.fpath_46_8=/dev/cpld3 +sff_cpld_reg.addr_46_8=0x21 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=3 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=logic_file +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.fpath_47_8=/dev/cpld3 +sff_cpld_reg.addr_47_8=0x21 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=4 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=logic_file +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.fpath_48_8=/dev/cpld3 +sff_cpld_reg.addr_48_8=0x21 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=5 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=logic_file +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.fpath_49_8=/dev/cpld3 +sff_cpld_reg.addr_49_8=0x21 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=6 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=logic_file +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.fpath_50_8=/dev/cpld3 +sff_cpld_reg.addr_50_8=0x21 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=7 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=logic_file +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.fpath_51_8=/dev/cpld3 +sff_cpld_reg.addr_51_8=0x22 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=0 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=logic_file +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.fpath_52_8=/dev/cpld3 +sff_cpld_reg.addr_52_8=0x22 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=1 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=logic_file +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.fpath_53_8=/dev/cpld3 +sff_cpld_reg.addr_53_8=0x22 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=2 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=logic_file +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.fpath_54_8=/dev/cpld3 +sff_cpld_reg.addr_54_8=0x22 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=3 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=logic_file +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.fpath_55_8=/dev/cpld3 +sff_cpld_reg.addr_55_8=0x22 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=4 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=logic_file +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.fpath_56_8=/dev/cpld3 +sff_cpld_reg.addr_56_8=0x22 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=5 + +sff_cpld_reg.mode_57_8=config +sff_cpld_reg.src_57_8=logic_file +sff_cpld_reg.frmt_57_8=bit +sff_cpld_reg.pola_57_8=negative +sff_cpld_reg.fpath_57_8=/dev/cpld3 +sff_cpld_reg.addr_57_8=0x22 +sff_cpld_reg.len_57_8=1 +sff_cpld_reg.bit_offset_57_8=6 + +sff_cpld_reg.mode_58_8=config +sff_cpld_reg.src_58_8=logic_file +sff_cpld_reg.frmt_58_8=bit +sff_cpld_reg.pola_58_8=negative +sff_cpld_reg.fpath_58_8=/dev/cpld3 +sff_cpld_reg.addr_58_8=0x22 +sff_cpld_reg.len_58_8=1 +sff_cpld_reg.bit_offset_58_8=7 + +sff_cpld_reg.mode_59_8=config +sff_cpld_reg.src_59_8=logic_file +sff_cpld_reg.frmt_59_8=bit +sff_cpld_reg.pola_59_8=negative +sff_cpld_reg.fpath_59_8=/dev/cpld3 +sff_cpld_reg.addr_59_8=0x23 +sff_cpld_reg.len_59_8=1 +sff_cpld_reg.bit_offset_59_8=0 + +sff_cpld_reg.mode_60_8=config +sff_cpld_reg.src_60_8=logic_file +sff_cpld_reg.frmt_60_8=bit +sff_cpld_reg.pola_60_8=negative +sff_cpld_reg.fpath_60_8=/dev/cpld3 +sff_cpld_reg.addr_60_8=0x23 +sff_cpld_reg.len_60_8=1 +sff_cpld_reg.bit_offset_60_8=1 + +sff_cpld_reg.mode_61_8=config +sff_cpld_reg.src_61_8=logic_file +sff_cpld_reg.frmt_61_8=bit +sff_cpld_reg.pola_61_8=negative +sff_cpld_reg.fpath_61_8=/dev/cpld3 +sff_cpld_reg.addr_61_8=0x23 +sff_cpld_reg.len_61_8=1 +sff_cpld_reg.bit_offset_61_8=2 + +sff_cpld_reg.mode_62_8=config +sff_cpld_reg.src_62_8=logic_file +sff_cpld_reg.frmt_62_8=bit +sff_cpld_reg.pola_62_8=negative +sff_cpld_reg.fpath_62_8=/dev/cpld3 +sff_cpld_reg.addr_62_8=0x23 +sff_cpld_reg.len_62_8=1 +sff_cpld_reg.bit_offset_62_8=3 + +sff_cpld_reg.mode_63_8=config +sff_cpld_reg.src_63_8=logic_file +sff_cpld_reg.frmt_63_8=bit +sff_cpld_reg.pola_63_8=negative +sff_cpld_reg.fpath_63_8=/dev/cpld3 +sff_cpld_reg.addr_63_8=0x23 +sff_cpld_reg.len_63_8=1 +sff_cpld_reg.bit_offset_63_8=4 + +sff_cpld_reg.mode_64_8=config +sff_cpld_reg.src_64_8=logic_file +sff_cpld_reg.frmt_64_8=bit +sff_cpld_reg.pola_64_8=negative +sff_cpld_reg.fpath_64_8=/dev/cpld3 +sff_cpld_reg.addr_64_8=0x23 +sff_cpld_reg.len_64_8=1 +sff_cpld_reg.bit_offset_64_8=5 + +sff_cpld_reg.mode_65_8=config +sff_cpld_reg.src_65_8=logic_file +sff_cpld_reg.frmt_65_8=bit +sff_cpld_reg.pola_65_8=negative +sff_cpld_reg.fpath_65_8=/dev/cpld2 +sff_cpld_reg.addr_65_8=0x3d +sff_cpld_reg.len_65_8=1 +sff_cpld_reg.bit_offset_65_8=2 + +sff_cpld_reg.mode_66_8=config +sff_cpld_reg.src_66_8=logic_file +sff_cpld_reg.frmt_66_8=bit +sff_cpld_reg.pola_66_8=negative +sff_cpld_reg.fpath_66_8=/dev/cpld2 +sff_cpld_reg.addr_66_8=0x3d +sff_cpld_reg.len_66_8=1 +sff_cpld_reg.bit_offset_66_8=3 + +sff_cpld_reg.mode_67_8=config +sff_cpld_reg.src_67_8=logic_file +sff_cpld_reg.frmt_67_8=bit +sff_cpld_reg.pola_67_8=negative +sff_cpld_reg.fpath_67_8=/dev/cpld2 +sff_cpld_reg.addr_67_8=0x3d +sff_cpld_reg.len_67_8=1 +sff_cpld_reg.bit_offset_67_8=4 + +sff_cpld_reg.mode_68_8=config +sff_cpld_reg.src_68_8=logic_file +sff_cpld_reg.frmt_68_8=bit +sff_cpld_reg.pola_68_8=negative +sff_cpld_reg.fpath_68_8=/dev/cpld2 +sff_cpld_reg.addr_68_8=0x3d +sff_cpld_reg.len_68_8=1 +sff_cpld_reg.bit_offset_68_8=5 + +sff_cpld_reg.mode_69_8=config +sff_cpld_reg.src_69_8=logic_file +sff_cpld_reg.frmt_69_8=bit +sff_cpld_reg.pola_69_8=negative +sff_cpld_reg.fpath_69_8=/dev/cpld2 +sff_cpld_reg.addr_69_8=0x3d +sff_cpld_reg.len_69_8=1 +sff_cpld_reg.bit_offset_69_8=6 + +sff_cpld_reg.mode_70_8=config +sff_cpld_reg.src_70_8=logic_file +sff_cpld_reg.frmt_70_8=bit +sff_cpld_reg.pola_70_8=negative +sff_cpld_reg.fpath_70_8=/dev/cpld2 +sff_cpld_reg.addr_70_8=0x3d +sff_cpld_reg.len_70_8=1 +sff_cpld_reg.bit_offset_70_8=7 + +sff_cpld_reg.mode_71_8=config +sff_cpld_reg.src_71_8=logic_file +sff_cpld_reg.frmt_71_8=bit +sff_cpld_reg.pola_71_8=negative +sff_cpld_reg.fpath_71_8=/dev/cpld2 +sff_cpld_reg.addr_71_8=0x3e +sff_cpld_reg.len_71_8=1 +sff_cpld_reg.bit_offset_71_8=0 + +sff_cpld_reg.mode_72_8=config +sff_cpld_reg.src_72_8=logic_file +sff_cpld_reg.frmt_72_8=bit +sff_cpld_reg.pola_72_8=negative +sff_cpld_reg.fpath_72_8=/dev/cpld2 +sff_cpld_reg.addr_72_8=0x3e +sff_cpld_reg.len_72_8=1 +sff_cpld_reg.bit_offset_72_8=1 + +sff_cpld_reg.mode_73_8=config +sff_cpld_reg.src_73_8=logic_file +sff_cpld_reg.frmt_73_8=bit +sff_cpld_reg.pola_73_8=negative +sff_cpld_reg.fpath_73_8=/dev/cpld2 +sff_cpld_reg.addr_73_8=0x3e +sff_cpld_reg.len_73_8=1 +sff_cpld_reg.bit_offset_73_8=2 + +sff_cpld_reg.mode_74_8=config +sff_cpld_reg.src_74_8=logic_file +sff_cpld_reg.frmt_74_8=bit +sff_cpld_reg.pola_74_8=negative +sff_cpld_reg.fpath_74_8=/dev/cpld2 +sff_cpld_reg.addr_74_8=0x3e +sff_cpld_reg.len_74_8=1 +sff_cpld_reg.bit_offset_74_8=3 + +sff_cpld_reg.mode_75_8=config +sff_cpld_reg.src_75_8=logic_file +sff_cpld_reg.frmt_75_8=bit +sff_cpld_reg.pola_75_8=negative +sff_cpld_reg.fpath_75_8=/dev/cpld3 +sff_cpld_reg.addr_75_8=0x23 +sff_cpld_reg.len_75_8=1 +sff_cpld_reg.bit_offset_75_8=6 + +sff_cpld_reg.mode_76_8=config +sff_cpld_reg.src_76_8=logic_file +sff_cpld_reg.frmt_76_8=bit +sff_cpld_reg.pola_76_8=negative +sff_cpld_reg.fpath_76_8=/dev/cpld3 +sff_cpld_reg.addr_76_8=0x23 +sff_cpld_reg.len_76_8=1 +sff_cpld_reg.bit_offset_76_8=7 + +sff_cpld_reg.mode_77_8=config +sff_cpld_reg.src_77_8=logic_file +sff_cpld_reg.frmt_77_8=bit +sff_cpld_reg.pola_77_8=negative +sff_cpld_reg.fpath_77_8=/dev/cpld3 +sff_cpld_reg.addr_77_8=0x24 +sff_cpld_reg.len_77_8=1 +sff_cpld_reg.bit_offset_77_8=0 + +sff_cpld_reg.mode_78_8=config +sff_cpld_reg.src_78_8=logic_file +sff_cpld_reg.frmt_78_8=bit +sff_cpld_reg.pola_78_8=negative +sff_cpld_reg.fpath_78_8=/dev/cpld3 +sff_cpld_reg.addr_78_8=0x24 +sff_cpld_reg.len_78_8=1 +sff_cpld_reg.bit_offset_78_8=1 + +sff_cpld_reg.mode_79_8=config +sff_cpld_reg.src_79_8=logic_file +sff_cpld_reg.frmt_79_8=bit +sff_cpld_reg.pola_79_8=negative +sff_cpld_reg.fpath_79_8=/dev/cpld3 +sff_cpld_reg.addr_79_8=0x24 +sff_cpld_reg.len_79_8=1 +sff_cpld_reg.bit_offset_79_8=2 + +sff_cpld_reg.mode_80_8=config +sff_cpld_reg.src_80_8=logic_file +sff_cpld_reg.frmt_80_8=bit +sff_cpld_reg.pola_80_8=negative +sff_cpld_reg.fpath_80_8=/dev/cpld3 +sff_cpld_reg.addr_80_8=0x24 +sff_cpld_reg.len_80_8=1 +sff_cpld_reg.bit_offset_80_8=3 + +sff_cpld_reg.mode_81_8=config +sff_cpld_reg.src_81_8=logic_file +sff_cpld_reg.frmt_81_8=bit +sff_cpld_reg.pola_81_8=negative +sff_cpld_reg.fpath_81_8=/dev/cpld3 +sff_cpld_reg.addr_81_8=0x24 +sff_cpld_reg.len_81_8=1 +sff_cpld_reg.bit_offset_81_8=4 + +sff_cpld_reg.mode_82_8=config +sff_cpld_reg.src_82_8=logic_file +sff_cpld_reg.frmt_82_8=bit +sff_cpld_reg.pola_82_8=negative +sff_cpld_reg.fpath_82_8=/dev/cpld3 +sff_cpld_reg.addr_82_8=0x24 +sff_cpld_reg.len_82_8=1 +sff_cpld_reg.bit_offset_82_8=5 + +sff_cpld_reg.mode_83_8=config +sff_cpld_reg.src_83_8=logic_file +sff_cpld_reg.frmt_83_8=bit +sff_cpld_reg.pola_83_8=negative +sff_cpld_reg.fpath_83_8=/dev/cpld3 +sff_cpld_reg.addr_83_8=0x24 +sff_cpld_reg.len_83_8=1 +sff_cpld_reg.bit_offset_83_8=6 + +sff_cpld_reg.mode_84_8=config +sff_cpld_reg.src_84_8=logic_file +sff_cpld_reg.frmt_84_8=bit +sff_cpld_reg.pola_84_8=negative +sff_cpld_reg.fpath_84_8=/dev/cpld3 +sff_cpld_reg.addr_84_8=0x24 +sff_cpld_reg.len_84_8=1 +sff_cpld_reg.bit_offset_84_8=7 + +sff_cpld_reg.mode_85_8=config +sff_cpld_reg.src_85_8=logic_file +sff_cpld_reg.frmt_85_8=bit +sff_cpld_reg.pola_85_8=negative +sff_cpld_reg.fpath_85_8=/dev/cpld3 +sff_cpld_reg.addr_85_8=0x25 +sff_cpld_reg.len_85_8=1 +sff_cpld_reg.bit_offset_85_8=0 + +sff_cpld_reg.mode_86_8=config +sff_cpld_reg.src_86_8=logic_file +sff_cpld_reg.frmt_86_8=bit +sff_cpld_reg.pola_86_8=negative +sff_cpld_reg.fpath_86_8=/dev/cpld3 +sff_cpld_reg.addr_86_8=0x25 +sff_cpld_reg.len_86_8=1 +sff_cpld_reg.bit_offset_86_8=1 + +sff_cpld_reg.mode_87_8=config +sff_cpld_reg.src_87_8=logic_file +sff_cpld_reg.frmt_87_8=bit +sff_cpld_reg.pola_87_8=negative +sff_cpld_reg.fpath_87_8=/dev/cpld3 +sff_cpld_reg.addr_87_8=0x25 +sff_cpld_reg.len_87_8=1 +sff_cpld_reg.bit_offset_87_8=2 + +sff_cpld_reg.mode_88_8=config +sff_cpld_reg.src_88_8=logic_file +sff_cpld_reg.frmt_88_8=bit +sff_cpld_reg.pola_88_8=negative +sff_cpld_reg.fpath_88_8=/dev/cpld3 +sff_cpld_reg.addr_88_8=0x25 +sff_cpld_reg.len_88_8=1 +sff_cpld_reg.bit_offset_88_8=3 + +sff_cpld_reg.mode_89_8=config +sff_cpld_reg.src_89_8=logic_file +sff_cpld_reg.frmt_89_8=bit +sff_cpld_reg.pola_89_8=negative +sff_cpld_reg.fpath_89_8=/dev/cpld3 +sff_cpld_reg.addr_89_8=0x25 +sff_cpld_reg.len_89_8=1 +sff_cpld_reg.bit_offset_89_8=4 + +sff_cpld_reg.mode_90_8=config +sff_cpld_reg.src_90_8=logic_file +sff_cpld_reg.frmt_90_8=bit +sff_cpld_reg.pola_90_8=negative +sff_cpld_reg.fpath_90_8=/dev/cpld3 +sff_cpld_reg.addr_90_8=0x25 +sff_cpld_reg.len_90_8=1 +sff_cpld_reg.bit_offset_90_8=5 + +sff_cpld_reg.mode_91_8=config +sff_cpld_reg.src_91_8=logic_file +sff_cpld_reg.frmt_91_8=bit +sff_cpld_reg.pola_91_8=negative +sff_cpld_reg.fpath_91_8=/dev/cpld3 +sff_cpld_reg.addr_91_8=0x25 +sff_cpld_reg.len_91_8=1 +sff_cpld_reg.bit_offset_91_8=6 + +sff_cpld_reg.mode_92_8=config +sff_cpld_reg.src_92_8=logic_file +sff_cpld_reg.frmt_92_8=bit +sff_cpld_reg.pola_92_8=negative +sff_cpld_reg.fpath_92_8=/dev/cpld3 +sff_cpld_reg.addr_92_8=0x25 +sff_cpld_reg.len_92_8=1 +sff_cpld_reg.bit_offset_92_8=7 + +sff_cpld_reg.mode_93_8=config +sff_cpld_reg.src_93_8=logic_file +sff_cpld_reg.frmt_93_8=bit +sff_cpld_reg.pola_93_8=negative +sff_cpld_reg.fpath_93_8=/dev/cpld3 +sff_cpld_reg.addr_93_8=0x26 +sff_cpld_reg.len_93_8=1 +sff_cpld_reg.bit_offset_93_8=0 + +sff_cpld_reg.mode_94_8=config +sff_cpld_reg.src_94_8=logic_file +sff_cpld_reg.frmt_94_8=bit +sff_cpld_reg.pola_94_8=negative +sff_cpld_reg.fpath_94_8=/dev/cpld3 +sff_cpld_reg.addr_94_8=0x26 +sff_cpld_reg.len_94_8=1 +sff_cpld_reg.bit_offset_94_8=1 + +sff_cpld_reg.mode_95_8=config +sff_cpld_reg.src_95_8=logic_file +sff_cpld_reg.frmt_95_8=bit +sff_cpld_reg.pola_95_8=negative +sff_cpld_reg.fpath_95_8=/dev/cpld3 +sff_cpld_reg.addr_95_8=0x26 +sff_cpld_reg.len_95_8=1 +sff_cpld_reg.bit_offset_95_8=2 + +sff_cpld_reg.mode_96_8=config +sff_cpld_reg.src_96_8=logic_file +sff_cpld_reg.frmt_96_8=bit +sff_cpld_reg.pola_96_8=negative +sff_cpld_reg.fpath_96_8=/dev/cpld3 +sff_cpld_reg.addr_96_8=0x26 +sff_cpld_reg.len_96_8=1 +sff_cpld_reg.bit_offset_96_8=3 + +sff_cpld_reg.mode_97_8=config +sff_cpld_reg.src_97_8=logic_file +sff_cpld_reg.frmt_97_8=bit +sff_cpld_reg.pola_97_8=negative +sff_cpld_reg.fpath_97_8=/dev/cpld6 +sff_cpld_reg.addr_97_8=0x38 +sff_cpld_reg.len_97_8=1 +sff_cpld_reg.bit_offset_97_8=0 + +sff_cpld_reg.mode_98_8=config +sff_cpld_reg.src_98_8=logic_file +sff_cpld_reg.frmt_98_8=bit +sff_cpld_reg.pola_98_8=negative +sff_cpld_reg.fpath_98_8=/dev/cpld6 +sff_cpld_reg.addr_98_8=0x38 +sff_cpld_reg.len_98_8=1 +sff_cpld_reg.bit_offset_98_8=1 + +sff_cpld_reg.mode_99_8=config +sff_cpld_reg.src_99_8=logic_file +sff_cpld_reg.frmt_99_8=bit +sff_cpld_reg.pola_99_8=negative +sff_cpld_reg.fpath_99_8=/dev/cpld6 +sff_cpld_reg.addr_99_8=0x38 +sff_cpld_reg.len_99_8=1 +sff_cpld_reg.bit_offset_99_8=2 + +sff_cpld_reg.mode_100_8=config +sff_cpld_reg.src_100_8=logic_file +sff_cpld_reg.frmt_100_8=bit +sff_cpld_reg.pola_100_8=negative +sff_cpld_reg.fpath_100_8=/dev/cpld6 +sff_cpld_reg.addr_100_8=0x38 +sff_cpld_reg.len_100_8=1 +sff_cpld_reg.bit_offset_100_8=3 + +sff_cpld_reg.mode_101_8=config +sff_cpld_reg.src_101_8=logic_file +sff_cpld_reg.frmt_101_8=bit +sff_cpld_reg.pola_101_8=negative +sff_cpld_reg.fpath_101_8=/dev/cpld6 +sff_cpld_reg.addr_101_8=0x38 +sff_cpld_reg.len_101_8=1 +sff_cpld_reg.bit_offset_101_8=4 + +sff_cpld_reg.mode_102_8=config +sff_cpld_reg.src_102_8=logic_file +sff_cpld_reg.frmt_102_8=bit +sff_cpld_reg.pola_102_8=negative +sff_cpld_reg.fpath_102_8=/dev/cpld6 +sff_cpld_reg.addr_102_8=0x38 +sff_cpld_reg.len_102_8=1 +sff_cpld_reg.bit_offset_102_8=5 + +sff_cpld_reg.mode_103_8=config +sff_cpld_reg.src_103_8=logic_file +sff_cpld_reg.frmt_103_8=bit +sff_cpld_reg.pola_103_8=negative +sff_cpld_reg.fpath_103_8=/dev/cpld6 +sff_cpld_reg.addr_103_8=0x38 +sff_cpld_reg.len_103_8=1 +sff_cpld_reg.bit_offset_103_8=6 + +sff_cpld_reg.mode_104_8=config +sff_cpld_reg.src_104_8=logic_file +sff_cpld_reg.frmt_104_8=bit +sff_cpld_reg.pola_104_8=negative +sff_cpld_reg.fpath_104_8=/dev/cpld6 +sff_cpld_reg.addr_104_8=0x38 +sff_cpld_reg.len_104_8=1 +sff_cpld_reg.bit_offset_104_8=7 + +sff_cpld_reg.mode_105_8=config +sff_cpld_reg.src_105_8=logic_file +sff_cpld_reg.frmt_105_8=bit +sff_cpld_reg.pola_105_8=negative +sff_cpld_reg.fpath_105_8=/dev/cpld6 +sff_cpld_reg.addr_105_8=0x39 +sff_cpld_reg.len_105_8=1 +sff_cpld_reg.bit_offset_105_8=0 + +sff_cpld_reg.mode_106_8=config +sff_cpld_reg.src_106_8=logic_file +sff_cpld_reg.frmt_106_8=bit +sff_cpld_reg.pola_106_8=negative +sff_cpld_reg.fpath_106_8=/dev/cpld6 +sff_cpld_reg.addr_106_8=0x39 +sff_cpld_reg.len_106_8=1 +sff_cpld_reg.bit_offset_106_8=1 + +sff_cpld_reg.mode_107_8=config +sff_cpld_reg.src_107_8=logic_file +sff_cpld_reg.frmt_107_8=bit +sff_cpld_reg.pola_107_8=negative +sff_cpld_reg.fpath_107_8=/dev/cpld6 +sff_cpld_reg.addr_107_8=0x39 +sff_cpld_reg.len_107_8=1 +sff_cpld_reg.bit_offset_107_8=2 + +sff_cpld_reg.mode_108_8=config +sff_cpld_reg.src_108_8=logic_file +sff_cpld_reg.frmt_108_8=bit +sff_cpld_reg.pola_108_8=negative +sff_cpld_reg.fpath_108_8=/dev/cpld6 +sff_cpld_reg.addr_108_8=0x39 +sff_cpld_reg.len_108_8=1 +sff_cpld_reg.bit_offset_108_8=3 + +sff_cpld_reg.mode_109_8=config +sff_cpld_reg.src_109_8=logic_file +sff_cpld_reg.frmt_109_8=bit +sff_cpld_reg.pola_109_8=negative +sff_cpld_reg.fpath_109_8=/dev/cpld6 +sff_cpld_reg.addr_109_8=0x39 +sff_cpld_reg.len_109_8=1 +sff_cpld_reg.bit_offset_109_8=4 + +sff_cpld_reg.mode_110_8=config +sff_cpld_reg.src_110_8=logic_file +sff_cpld_reg.frmt_110_8=bit +sff_cpld_reg.pola_110_8=negative +sff_cpld_reg.fpath_110_8=/dev/cpld6 +sff_cpld_reg.addr_110_8=0x39 +sff_cpld_reg.len_110_8=1 +sff_cpld_reg.bit_offset_110_8=5 + +sff_cpld_reg.mode_111_8=config +sff_cpld_reg.src_111_8=logic_file +sff_cpld_reg.frmt_111_8=bit +sff_cpld_reg.pola_111_8=negative +sff_cpld_reg.fpath_111_8=/dev/cpld6 +sff_cpld_reg.addr_111_8=0x39 +sff_cpld_reg.len_111_8=1 +sff_cpld_reg.bit_offset_111_8=6 + +sff_cpld_reg.mode_112_8=config +sff_cpld_reg.src_112_8=logic_file +sff_cpld_reg.frmt_112_8=bit +sff_cpld_reg.pola_112_8=negative +sff_cpld_reg.fpath_112_8=/dev/cpld6 +sff_cpld_reg.addr_112_8=0x39 +sff_cpld_reg.len_112_8=1 +sff_cpld_reg.bit_offset_112_8=7 + +sff_cpld_reg.mode_113_8=config +sff_cpld_reg.src_113_8=logic_file +sff_cpld_reg.frmt_113_8=bit +sff_cpld_reg.pola_113_8=negative +sff_cpld_reg.fpath_113_8=/dev/cpld6 +sff_cpld_reg.addr_113_8=0x3a +sff_cpld_reg.len_113_8=1 +sff_cpld_reg.bit_offset_113_8=0 + +sff_cpld_reg.mode_114_8=config +sff_cpld_reg.src_114_8=logic_file +sff_cpld_reg.frmt_114_8=bit +sff_cpld_reg.pola_114_8=negative +sff_cpld_reg.fpath_114_8=/dev/cpld6 +sff_cpld_reg.addr_114_8=0x3a +sff_cpld_reg.len_114_8=1 +sff_cpld_reg.bit_offset_114_8=1 + +sff_cpld_reg.mode_115_8=config +sff_cpld_reg.src_115_8=logic_file +sff_cpld_reg.frmt_115_8=bit +sff_cpld_reg.pola_115_8=negative +sff_cpld_reg.fpath_115_8=/dev/cpld6 +sff_cpld_reg.addr_115_8=0x3a +sff_cpld_reg.len_115_8=1 +sff_cpld_reg.bit_offset_115_8=2 + +sff_cpld_reg.mode_116_8=config +sff_cpld_reg.src_116_8=logic_file +sff_cpld_reg.frmt_116_8=bit +sff_cpld_reg.pola_116_8=negative +sff_cpld_reg.fpath_116_8=/dev/cpld6 +sff_cpld_reg.addr_116_8=0x3a +sff_cpld_reg.len_116_8=1 +sff_cpld_reg.bit_offset_116_8=3 + +sff_cpld_reg.mode_117_8=config +sff_cpld_reg.src_117_8=logic_file +sff_cpld_reg.frmt_117_8=bit +sff_cpld_reg.pola_117_8=negative +sff_cpld_reg.fpath_117_8=/dev/cpld6 +sff_cpld_reg.addr_117_8=0x3a +sff_cpld_reg.len_117_8=1 +sff_cpld_reg.bit_offset_117_8=4 + +sff_cpld_reg.mode_118_8=config +sff_cpld_reg.src_118_8=logic_file +sff_cpld_reg.frmt_118_8=bit +sff_cpld_reg.pola_118_8=negative +sff_cpld_reg.fpath_118_8=/dev/cpld6 +sff_cpld_reg.addr_118_8=0x3a +sff_cpld_reg.len_118_8=1 +sff_cpld_reg.bit_offset_118_8=5 + +sff_cpld_reg.mode_119_8=config +sff_cpld_reg.src_119_8=logic_file +sff_cpld_reg.frmt_119_8=bit +sff_cpld_reg.pola_119_8=negative +sff_cpld_reg.fpath_119_8=/dev/cpld6 +sff_cpld_reg.addr_119_8=0x3a +sff_cpld_reg.len_119_8=1 +sff_cpld_reg.bit_offset_119_8=6 + +sff_cpld_reg.mode_120_8=config +sff_cpld_reg.src_120_8=logic_file +sff_cpld_reg.frmt_120_8=bit +sff_cpld_reg.pola_120_8=negative +sff_cpld_reg.fpath_120_8=/dev/cpld6 +sff_cpld_reg.addr_120_8=0x3a +sff_cpld_reg.len_120_8=1 +sff_cpld_reg.bit_offset_120_8=7 + +sff_cpld_reg.mode_121_8=config +sff_cpld_reg.src_121_8=logic_file +sff_cpld_reg.frmt_121_8=bit +sff_cpld_reg.pola_121_8=negative +sff_cpld_reg.fpath_121_8=/dev/cpld6 +sff_cpld_reg.addr_121_8=0x3b +sff_cpld_reg.len_121_8=1 +sff_cpld_reg.bit_offset_121_8=0 + +sff_cpld_reg.mode_122_8=config +sff_cpld_reg.src_122_8=logic_file +sff_cpld_reg.frmt_122_8=bit +sff_cpld_reg.pola_122_8=negative +sff_cpld_reg.fpath_122_8=/dev/cpld6 +sff_cpld_reg.addr_122_8=0x3b +sff_cpld_reg.len_122_8=1 +sff_cpld_reg.bit_offset_122_8=1 + +sff_cpld_reg.mode_123_8=config +sff_cpld_reg.src_123_8=logic_file +sff_cpld_reg.frmt_123_8=bit +sff_cpld_reg.pola_123_8=negative +sff_cpld_reg.fpath_123_8=/dev/cpld6 +sff_cpld_reg.addr_123_8=0x3b +sff_cpld_reg.len_123_8=1 +sff_cpld_reg.bit_offset_123_8=2 + +sff_cpld_reg.mode_124_8=config +sff_cpld_reg.src_124_8=logic_file +sff_cpld_reg.frmt_124_8=bit +sff_cpld_reg.pola_124_8=negative +sff_cpld_reg.fpath_124_8=/dev/cpld6 +sff_cpld_reg.addr_124_8=0x3b +sff_cpld_reg.len_124_8=1 +sff_cpld_reg.bit_offset_124_8=3 + +sff_cpld_reg.mode_125_8=config +sff_cpld_reg.src_125_8=logic_file +sff_cpld_reg.frmt_125_8=bit +sff_cpld_reg.pola_125_8=negative +sff_cpld_reg.fpath_125_8=/dev/cpld6 +sff_cpld_reg.addr_125_8=0x3b +sff_cpld_reg.len_125_8=1 +sff_cpld_reg.bit_offset_125_8=4 + +sff_cpld_reg.mode_126_8=config +sff_cpld_reg.src_126_8=logic_file +sff_cpld_reg.frmt_126_8=bit +sff_cpld_reg.pola_126_8=negative +sff_cpld_reg.fpath_126_8=/dev/cpld6 +sff_cpld_reg.addr_126_8=0x3b +sff_cpld_reg.len_126_8=1 +sff_cpld_reg.bit_offset_126_8=5 + +sff_cpld_reg.mode_127_8=config +sff_cpld_reg.src_127_8=logic_file +sff_cpld_reg.frmt_127_8=bit +sff_cpld_reg.pola_127_8=negative +sff_cpld_reg.fpath_127_8=/dev/cpld6 +sff_cpld_reg.addr_127_8=0x3b +sff_cpld_reg.len_127_8=1 +sff_cpld_reg.bit_offset_127_8=6 + +sff_cpld_reg.mode_128_8=config +sff_cpld_reg.src_128_8=logic_file +sff_cpld_reg.frmt_128_8=bit +sff_cpld_reg.pola_128_8=negative +sff_cpld_reg.fpath_128_8=/dev/cpld6 +sff_cpld_reg.addr_128_8=0x3b +sff_cpld_reg.len_128_8=1 +sff_cpld_reg.bit_offset_128_8=7 + +sff_cpld_reg.mode_129_8=config +sff_cpld_reg.src_129_8=logic_file +sff_cpld_reg.frmt_129_8=bit +sff_cpld_reg.pola_129_8=negative +sff_cpld_reg.fpath_129_8=/dev/cpld1 +sff_cpld_reg.addr_129_8=0xa2 +sff_cpld_reg.len_129_8=1 +sff_cpld_reg.bit_offset_129_8=4 + +sff_cpld_reg.mode_130_8=config +sff_cpld_reg.src_130_8=logic_file +sff_cpld_reg.frmt_130_8=bit +sff_cpld_reg.pola_130_8=negative +sff_cpld_reg.fpath_130_8=/dev/cpld1 +sff_cpld_reg.addr_130_8=0xa2 +sff_cpld_reg.len_130_8=1 +sff_cpld_reg.bit_offset_130_8=5 + +# optoe type +sff_optoe_type.mode_1=config +sff_optoe_type.int_cons_1= +sff_optoe_type.src_1=logic_file +sff_optoe_type.frmt_1=byte +sff_optoe_type.fpath_1=/sys/bus/i2c/devices/201-0050/dev_class +sff_optoe_type.addr_1=0 +sff_optoe_type.len_1=1 +sff_optoe_type.bit_offset_1= + +sff_optoe_type.mode_2=config +sff_optoe_type.int_cons_2= +sff_optoe_type.src_2=logic_file +sff_optoe_type.frmt_2=byte +sff_optoe_type.fpath_2=/sys/bus/i2c/devices/202-0050/dev_class +sff_optoe_type.addr_2=0 +sff_optoe_type.len_2=1 +sff_optoe_type.bit_offset_2= + +sff_optoe_type.mode_3=config +sff_optoe_type.int_cons_3= +sff_optoe_type.src_3=logic_file +sff_optoe_type.frmt_3=byte +sff_optoe_type.fpath_3=/sys/bus/i2c/devices/203-0050/dev_class +sff_optoe_type.addr_3=0 +sff_optoe_type.len_3=1 +sff_optoe_type.bit_offset_3= + +sff_optoe_type.mode_4=config +sff_optoe_type.int_cons_4= +sff_optoe_type.src_4=logic_file +sff_optoe_type.frmt_4=byte +sff_optoe_type.fpath_4=/sys/bus/i2c/devices/204-0050/dev_class +sff_optoe_type.addr_4=0 +sff_optoe_type.len_4=1 +sff_optoe_type.bit_offset_4= + +sff_optoe_type.mode_5=config +sff_optoe_type.int_cons_5= +sff_optoe_type.src_5=logic_file +sff_optoe_type.frmt_5=byte +sff_optoe_type.fpath_5=/sys/bus/i2c/devices/205-0050/dev_class +sff_optoe_type.addr_5=0 +sff_optoe_type.len_5=1 +sff_optoe_type.bit_offset_5= + +sff_optoe_type.mode_6=config +sff_optoe_type.int_cons_6= +sff_optoe_type.src_6=logic_file +sff_optoe_type.frmt_6=byte +sff_optoe_type.fpath_6=/sys/bus/i2c/devices/206-0050/dev_class +sff_optoe_type.addr_6=0 +sff_optoe_type.len_6=1 +sff_optoe_type.bit_offset_6= + +sff_optoe_type.mode_7=config +sff_optoe_type.int_cons_7= +sff_optoe_type.src_7=logic_file +sff_optoe_type.frmt_7=byte +sff_optoe_type.fpath_7=/sys/bus/i2c/devices/207-0050/dev_class +sff_optoe_type.addr_7=0 +sff_optoe_type.len_7=1 +sff_optoe_type.bit_offset_7= + +sff_optoe_type.mode_8=config +sff_optoe_type.int_cons_8= +sff_optoe_type.src_8=logic_file +sff_optoe_type.frmt_8=byte +sff_optoe_type.fpath_8=/sys/bus/i2c/devices/208-0050/dev_class +sff_optoe_type.addr_8=0 +sff_optoe_type.len_8=1 +sff_optoe_type.bit_offset_8= + +sff_optoe_type.mode_9=config +sff_optoe_type.int_cons_9= +sff_optoe_type.src_9=logic_file +sff_optoe_type.frmt_9=byte +sff_optoe_type.fpath_9=/sys/bus/i2c/devices/209-0050/dev_class +sff_optoe_type.addr_9=0 +sff_optoe_type.len_9=1 +sff_optoe_type.bit_offset_9= + +sff_optoe_type.mode_10=config +sff_optoe_type.int_cons_10= +sff_optoe_type.src_10=logic_file +sff_optoe_type.frmt_10=byte +sff_optoe_type.fpath_10=/sys/bus/i2c/devices/210-0050/dev_class +sff_optoe_type.addr_10=0 +sff_optoe_type.len_10=1 +sff_optoe_type.bit_offset_10= + +sff_optoe_type.mode_11=config +sff_optoe_type.int_cons_11= +sff_optoe_type.src_11=logic_file +sff_optoe_type.frmt_11=byte +sff_optoe_type.fpath_11=/sys/bus/i2c/devices/211-0050/dev_class +sff_optoe_type.addr_11=0 +sff_optoe_type.len_11=1 +sff_optoe_type.bit_offset_11= + +sff_optoe_type.mode_12=config +sff_optoe_type.int_cons_12= +sff_optoe_type.src_12=logic_file +sff_optoe_type.frmt_12=byte +sff_optoe_type.fpath_12=/sys/bus/i2c/devices/212-0050/dev_class +sff_optoe_type.addr_12=0 +sff_optoe_type.len_12=1 +sff_optoe_type.bit_offset_12= + +sff_optoe_type.mode_13=config +sff_optoe_type.int_cons_13= +sff_optoe_type.src_13=logic_file +sff_optoe_type.frmt_13=byte +sff_optoe_type.fpath_13=/sys/bus/i2c/devices/213-0050/dev_class +sff_optoe_type.addr_13=0 +sff_optoe_type.len_13=1 +sff_optoe_type.bit_offset_13= + +sff_optoe_type.mode_14=config +sff_optoe_type.int_cons_14= +sff_optoe_type.src_14=logic_file +sff_optoe_type.frmt_14=byte +sff_optoe_type.fpath_14=/sys/bus/i2c/devices/214-0050/dev_class +sff_optoe_type.addr_14=0 +sff_optoe_type.len_14=1 +sff_optoe_type.bit_offset_14= + +sff_optoe_type.mode_15=config +sff_optoe_type.int_cons_15= +sff_optoe_type.src_15=logic_file +sff_optoe_type.frmt_15=byte +sff_optoe_type.fpath_15=/sys/bus/i2c/devices/215-0050/dev_class +sff_optoe_type.addr_15=0 +sff_optoe_type.len_15=1 +sff_optoe_type.bit_offset_15= + +sff_optoe_type.mode_16=config +sff_optoe_type.int_cons_16= +sff_optoe_type.src_16=logic_file +sff_optoe_type.frmt_16=byte +sff_optoe_type.fpath_16=/sys/bus/i2c/devices/216-0050/dev_class +sff_optoe_type.addr_16=0 +sff_optoe_type.len_16=1 +sff_optoe_type.bit_offset_16= + +sff_optoe_type.mode_17=config +sff_optoe_type.int_cons_17= +sff_optoe_type.src_17=logic_file +sff_optoe_type.frmt_17=byte +sff_optoe_type.fpath_17=/sys/bus/i2c/devices/217-0050/dev_class +sff_optoe_type.addr_17=0 +sff_optoe_type.len_17=1 +sff_optoe_type.bit_offset_17= + +sff_optoe_type.mode_18=config +sff_optoe_type.int_cons_18= +sff_optoe_type.src_18=logic_file +sff_optoe_type.frmt_18=byte +sff_optoe_type.fpath_18=/sys/bus/i2c/devices/218-0050/dev_class +sff_optoe_type.addr_18=0 +sff_optoe_type.len_18=1 +sff_optoe_type.bit_offset_18= + +sff_optoe_type.mode_19=config +sff_optoe_type.int_cons_19= +sff_optoe_type.src_19=logic_file +sff_optoe_type.frmt_19=byte +sff_optoe_type.fpath_19=/sys/bus/i2c/devices/219-0050/dev_class +sff_optoe_type.addr_19=0 +sff_optoe_type.len_19=1 +sff_optoe_type.bit_offset_19= + +sff_optoe_type.mode_20=config +sff_optoe_type.int_cons_20= +sff_optoe_type.src_20=logic_file +sff_optoe_type.frmt_20=byte +sff_optoe_type.fpath_20=/sys/bus/i2c/devices/220-0050/dev_class +sff_optoe_type.addr_20=0 +sff_optoe_type.len_20=1 +sff_optoe_type.bit_offset_20= + +sff_optoe_type.mode_21=config +sff_optoe_type.int_cons_21= +sff_optoe_type.src_21=logic_file +sff_optoe_type.frmt_21=byte +sff_optoe_type.fpath_21=/sys/bus/i2c/devices/221-0050/dev_class +sff_optoe_type.addr_21=0 +sff_optoe_type.len_21=1 +sff_optoe_type.bit_offset_21= + +sff_optoe_type.mode_22=config +sff_optoe_type.int_cons_22= +sff_optoe_type.src_22=logic_file +sff_optoe_type.frmt_22=byte +sff_optoe_type.fpath_22=/sys/bus/i2c/devices/222-0050/dev_class +sff_optoe_type.addr_22=0 +sff_optoe_type.len_22=1 +sff_optoe_type.bit_offset_22= + +sff_optoe_type.mode_23=config +sff_optoe_type.int_cons_23= +sff_optoe_type.src_23=logic_file +sff_optoe_type.frmt_23=byte +sff_optoe_type.fpath_23=/sys/bus/i2c/devices/223-0050/dev_class +sff_optoe_type.addr_23=0 +sff_optoe_type.len_23=1 +sff_optoe_type.bit_offset_23= + +sff_optoe_type.mode_24=config +sff_optoe_type.int_cons_24= +sff_optoe_type.src_24=logic_file +sff_optoe_type.frmt_24=byte +sff_optoe_type.fpath_24=/sys/bus/i2c/devices/224-0050/dev_class +sff_optoe_type.addr_24=0 +sff_optoe_type.len_24=1 +sff_optoe_type.bit_offset_24= + +sff_optoe_type.mode_25=config +sff_optoe_type.int_cons_25= +sff_optoe_type.src_25=logic_file +sff_optoe_type.frmt_25=byte +sff_optoe_type.fpath_25=/sys/bus/i2c/devices/225-0050/dev_class +sff_optoe_type.addr_25=0 +sff_optoe_type.len_25=1 +sff_optoe_type.bit_offset_25= + +sff_optoe_type.mode_26=config +sff_optoe_type.int_cons_26= +sff_optoe_type.src_26=logic_file +sff_optoe_type.frmt_26=byte +sff_optoe_type.fpath_26=/sys/bus/i2c/devices/226-0050/dev_class +sff_optoe_type.addr_26=0 +sff_optoe_type.len_26=1 +sff_optoe_type.bit_offset_26= + +sff_optoe_type.mode_27=config +sff_optoe_type.int_cons_27= +sff_optoe_type.src_27=logic_file +sff_optoe_type.frmt_27=byte +sff_optoe_type.fpath_27=/sys/bus/i2c/devices/227-0050/dev_class +sff_optoe_type.addr_27=0 +sff_optoe_type.len_27=1 +sff_optoe_type.bit_offset_27= + +sff_optoe_type.mode_28=config +sff_optoe_type.int_cons_28= +sff_optoe_type.src_28=logic_file +sff_optoe_type.frmt_28=byte +sff_optoe_type.fpath_28=/sys/bus/i2c/devices/228-0050/dev_class +sff_optoe_type.addr_28=0 +sff_optoe_type.len_28=1 +sff_optoe_type.bit_offset_28= + +sff_optoe_type.mode_29=config +sff_optoe_type.int_cons_29= +sff_optoe_type.src_29=logic_file +sff_optoe_type.frmt_29=byte +sff_optoe_type.fpath_29=/sys/bus/i2c/devices/229-0050/dev_class +sff_optoe_type.addr_29=0 +sff_optoe_type.len_29=1 +sff_optoe_type.bit_offset_29= + +sff_optoe_type.mode_30=config +sff_optoe_type.int_cons_30= +sff_optoe_type.src_30=logic_file +sff_optoe_type.frmt_30=byte +sff_optoe_type.fpath_30=/sys/bus/i2c/devices/230-0050/dev_class +sff_optoe_type.addr_30=0 +sff_optoe_type.len_30=1 +sff_optoe_type.bit_offset_30= + +sff_optoe_type.mode_31=config +sff_optoe_type.int_cons_31= +sff_optoe_type.src_31=logic_file +sff_optoe_type.frmt_31=byte +sff_optoe_type.fpath_31=/sys/bus/i2c/devices/231-0050/dev_class +sff_optoe_type.addr_31=0 +sff_optoe_type.len_31=1 +sff_optoe_type.bit_offset_31= + +sff_optoe_type.mode_32=config +sff_optoe_type.int_cons_32= +sff_optoe_type.src_32=logic_file +sff_optoe_type.frmt_32=byte +sff_optoe_type.fpath_32=/sys/bus/i2c/devices/232-0050/dev_class +sff_optoe_type.addr_32=0 +sff_optoe_type.len_32=1 +sff_optoe_type.bit_offset_32= + +sff_optoe_type.mode_33=config +sff_optoe_type.int_cons_33= +sff_optoe_type.src_33=logic_file +sff_optoe_type.frmt_33=byte +sff_optoe_type.fpath_33=/sys/bus/i2c/devices/233-0050/dev_class +sff_optoe_type.addr_33=0 +sff_optoe_type.len_33=1 +sff_optoe_type.bit_offset_33= + +sff_optoe_type.mode_34=config +sff_optoe_type.int_cons_34= +sff_optoe_type.src_34=logic_file +sff_optoe_type.frmt_34=byte +sff_optoe_type.fpath_34=/sys/bus/i2c/devices/234-0050/dev_class +sff_optoe_type.addr_34=0 +sff_optoe_type.len_34=1 +sff_optoe_type.bit_offset_34= + +sff_optoe_type.mode_35=config +sff_optoe_type.int_cons_35= +sff_optoe_type.src_35=logic_file +sff_optoe_type.frmt_35=byte +sff_optoe_type.fpath_35=/sys/bus/i2c/devices/235-0050/dev_class +sff_optoe_type.addr_35=0 +sff_optoe_type.len_35=1 +sff_optoe_type.bit_offset_35= + +sff_optoe_type.mode_36=config +sff_optoe_type.int_cons_36= +sff_optoe_type.src_36=logic_file +sff_optoe_type.frmt_36=byte +sff_optoe_type.fpath_36=/sys/bus/i2c/devices/236-0050/dev_class +sff_optoe_type.addr_36=0 +sff_optoe_type.len_36=1 +sff_optoe_type.bit_offset_36= + +sff_optoe_type.mode_37=config +sff_optoe_type.int_cons_37= +sff_optoe_type.src_37=logic_file +sff_optoe_type.frmt_37=byte +sff_optoe_type.fpath_37=/sys/bus/i2c/devices/237-0050/dev_class +sff_optoe_type.addr_37=0 +sff_optoe_type.len_37=1 +sff_optoe_type.bit_offset_37= + +sff_optoe_type.mode_38=config +sff_optoe_type.int_cons_38= +sff_optoe_type.src_38=logic_file +sff_optoe_type.frmt_38=byte +sff_optoe_type.fpath_38=/sys/bus/i2c/devices/238-0050/dev_class +sff_optoe_type.addr_38=0 +sff_optoe_type.len_38=1 +sff_optoe_type.bit_offset_38= + +sff_optoe_type.mode_39=config +sff_optoe_type.int_cons_39= +sff_optoe_type.src_39=logic_file +sff_optoe_type.frmt_39=byte +sff_optoe_type.fpath_39=/sys/bus/i2c/devices/239-0050/dev_class +sff_optoe_type.addr_39=0 +sff_optoe_type.len_39=1 +sff_optoe_type.bit_offset_39= + +sff_optoe_type.mode_40=config +sff_optoe_type.int_cons_40= +sff_optoe_type.src_40=logic_file +sff_optoe_type.frmt_40=byte +sff_optoe_type.fpath_40=/sys/bus/i2c/devices/240-0050/dev_class +sff_optoe_type.addr_40=0 +sff_optoe_type.len_40=1 +sff_optoe_type.bit_offset_40= + +sff_optoe_type.mode_41=config +sff_optoe_type.int_cons_41= +sff_optoe_type.src_41=logic_file +sff_optoe_type.frmt_41=byte +sff_optoe_type.fpath_41=/sys/bus/i2c/devices/241-0050/dev_class +sff_optoe_type.addr_41=0 +sff_optoe_type.len_41=1 +sff_optoe_type.bit_offset_41= + +sff_optoe_type.mode_42=config +sff_optoe_type.int_cons_42= +sff_optoe_type.src_42=logic_file +sff_optoe_type.frmt_42=byte +sff_optoe_type.fpath_42=/sys/bus/i2c/devices/242-0050/dev_class +sff_optoe_type.addr_42=0 +sff_optoe_type.len_42=1 +sff_optoe_type.bit_offset_42= + +sff_optoe_type.mode_43=config +sff_optoe_type.int_cons_43= +sff_optoe_type.src_43=logic_file +sff_optoe_type.frmt_43=byte +sff_optoe_type.fpath_43=/sys/bus/i2c/devices/243-0050/dev_class +sff_optoe_type.addr_43=0 +sff_optoe_type.len_43=1 +sff_optoe_type.bit_offset_43= + +sff_optoe_type.mode_44=config +sff_optoe_type.int_cons_44= +sff_optoe_type.src_44=logic_file +sff_optoe_type.frmt_44=byte +sff_optoe_type.fpath_44=/sys/bus/i2c/devices/244-0050/dev_class +sff_optoe_type.addr_44=0 +sff_optoe_type.len_44=1 +sff_optoe_type.bit_offset_44= + +sff_optoe_type.mode_45=config +sff_optoe_type.int_cons_45= +sff_optoe_type.src_45=logic_file +sff_optoe_type.frmt_45=byte +sff_optoe_type.fpath_45=/sys/bus/i2c/devices/245-0050/dev_class +sff_optoe_type.addr_45=0 +sff_optoe_type.len_45=1 +sff_optoe_type.bit_offset_45= + +sff_optoe_type.mode_46=config +sff_optoe_type.int_cons_46= +sff_optoe_type.src_46=logic_file +sff_optoe_type.frmt_46=byte +sff_optoe_type.fpath_46=/sys/bus/i2c/devices/246-0050/dev_class +sff_optoe_type.addr_46=0 +sff_optoe_type.len_46=1 +sff_optoe_type.bit_offset_46= + +sff_optoe_type.mode_47=config +sff_optoe_type.int_cons_47= +sff_optoe_type.src_47=logic_file +sff_optoe_type.frmt_47=byte +sff_optoe_type.fpath_47=/sys/bus/i2c/devices/247-0050/dev_class +sff_optoe_type.addr_47=0 +sff_optoe_type.len_47=1 +sff_optoe_type.bit_offset_47= + +sff_optoe_type.mode_48=config +sff_optoe_type.int_cons_48= +sff_optoe_type.src_48=logic_file +sff_optoe_type.frmt_48=byte +sff_optoe_type.fpath_48=/sys/bus/i2c/devices/248-0050/dev_class +sff_optoe_type.addr_48=0 +sff_optoe_type.len_48=1 +sff_optoe_type.bit_offset_48= + +sff_optoe_type.mode_49=config +sff_optoe_type.int_cons_49= +sff_optoe_type.src_49=logic_file +sff_optoe_type.frmt_49=byte +sff_optoe_type.fpath_49=/sys/bus/i2c/devices/249-0050/dev_class +sff_optoe_type.addr_49=0 +sff_optoe_type.len_49=1 +sff_optoe_type.bit_offset_49= + +sff_optoe_type.mode_50=config +sff_optoe_type.int_cons_50= +sff_optoe_type.src_50=logic_file +sff_optoe_type.frmt_50=byte +sff_optoe_type.fpath_50=/sys/bus/i2c/devices/250-0050/dev_class +sff_optoe_type.addr_50=0 +sff_optoe_type.len_50=1 +sff_optoe_type.bit_offset_50= + +sff_optoe_type.mode_51=config +sff_optoe_type.int_cons_51= +sff_optoe_type.src_51=logic_file +sff_optoe_type.frmt_51=byte +sff_optoe_type.fpath_51=/sys/bus/i2c/devices/251-0050/dev_class +sff_optoe_type.addr_51=0 +sff_optoe_type.len_51=1 +sff_optoe_type.bit_offset_51= + +sff_optoe_type.mode_52=config +sff_optoe_type.int_cons_52= +sff_optoe_type.src_52=logic_file +sff_optoe_type.frmt_52=byte +sff_optoe_type.fpath_52=/sys/bus/i2c/devices/252-0050/dev_class +sff_optoe_type.addr_52=0 +sff_optoe_type.len_52=1 +sff_optoe_type.bit_offset_52= + +sff_optoe_type.mode_53=config +sff_optoe_type.int_cons_53= +sff_optoe_type.src_53=logic_file +sff_optoe_type.frmt_53=byte +sff_optoe_type.fpath_53=/sys/bus/i2c/devices/253-0050/dev_class +sff_optoe_type.addr_53=0 +sff_optoe_type.len_53=1 +sff_optoe_type.bit_offset_53= + +sff_optoe_type.mode_54=config +sff_optoe_type.int_cons_54= +sff_optoe_type.src_54=logic_file +sff_optoe_type.frmt_54=byte +sff_optoe_type.fpath_54=/sys/bus/i2c/devices/254-0050/dev_class +sff_optoe_type.addr_54=0 +sff_optoe_type.len_54=1 +sff_optoe_type.bit_offset_54= + +sff_optoe_type.mode_55=config +sff_optoe_type.int_cons_55= +sff_optoe_type.src_55=logic_file +sff_optoe_type.frmt_55=byte +sff_optoe_type.fpath_55=/sys/bus/i2c/devices/255-0050/dev_class +sff_optoe_type.addr_55=0 +sff_optoe_type.len_55=1 +sff_optoe_type.bit_offset_55= + +sff_optoe_type.mode_56=config +sff_optoe_type.int_cons_56= +sff_optoe_type.src_56=logic_file +sff_optoe_type.frmt_56=byte +sff_optoe_type.fpath_56=/sys/bus/i2c/devices/256-0050/dev_class +sff_optoe_type.addr_56=0 +sff_optoe_type.len_56=1 +sff_optoe_type.bit_offset_56= + +sff_optoe_type.mode_57=config +sff_optoe_type.int_cons_57= +sff_optoe_type.src_57=logic_file +sff_optoe_type.frmt_57=byte +sff_optoe_type.fpath_57=/sys/bus/i2c/devices/257-0050/dev_class +sff_optoe_type.addr_57=0 +sff_optoe_type.len_57=1 +sff_optoe_type.bit_offset_57= + +sff_optoe_type.mode_58=config +sff_optoe_type.int_cons_58= +sff_optoe_type.src_58=logic_file +sff_optoe_type.frmt_58=byte +sff_optoe_type.fpath_58=/sys/bus/i2c/devices/258-0050/dev_class +sff_optoe_type.addr_58=0 +sff_optoe_type.len_58=1 +sff_optoe_type.bit_offset_58= + +sff_optoe_type.mode_59=config +sff_optoe_type.int_cons_59= +sff_optoe_type.src_59=logic_file +sff_optoe_type.frmt_59=byte +sff_optoe_type.fpath_59=/sys/bus/i2c/devices/259-0050/dev_class +sff_optoe_type.addr_59=0 +sff_optoe_type.len_59=1 +sff_optoe_type.bit_offset_59= + +sff_optoe_type.mode_60=config +sff_optoe_type.int_cons_60= +sff_optoe_type.src_60=logic_file +sff_optoe_type.frmt_60=byte +sff_optoe_type.fpath_60=/sys/bus/i2c/devices/260-0050/dev_class +sff_optoe_type.addr_60=0 +sff_optoe_type.len_60=1 +sff_optoe_type.bit_offset_60= + +sff_optoe_type.mode_61=config +sff_optoe_type.int_cons_61= +sff_optoe_type.src_61=logic_file +sff_optoe_type.frmt_61=byte +sff_optoe_type.fpath_61=/sys/bus/i2c/devices/261-0050/dev_class +sff_optoe_type.addr_61=0 +sff_optoe_type.len_61=1 +sff_optoe_type.bit_offset_61= + +sff_optoe_type.mode_62=config +sff_optoe_type.int_cons_62= +sff_optoe_type.src_62=logic_file +sff_optoe_type.frmt_62=byte +sff_optoe_type.fpath_62=/sys/bus/i2c/devices/262-0050/dev_class +sff_optoe_type.addr_62=0 +sff_optoe_type.len_62=1 +sff_optoe_type.bit_offset_62= + +sff_optoe_type.mode_63=config +sff_optoe_type.int_cons_63= +sff_optoe_type.src_63=logic_file +sff_optoe_type.frmt_63=byte +sff_optoe_type.fpath_63=/sys/bus/i2c/devices/263-0050/dev_class +sff_optoe_type.addr_63=0 +sff_optoe_type.len_63=1 +sff_optoe_type.bit_offset_63= + +sff_optoe_type.mode_64=config +sff_optoe_type.int_cons_64= +sff_optoe_type.src_64=logic_file +sff_optoe_type.frmt_64=byte +sff_optoe_type.fpath_64=/sys/bus/i2c/devices/264-0050/dev_class +sff_optoe_type.addr_64=0 +sff_optoe_type.len_64=1 +sff_optoe_type.bit_offset_64= + +sff_optoe_type.mode_65=config +sff_optoe_type.int_cons_65= +sff_optoe_type.src_65=logic_file +sff_optoe_type.frmt_65=byte +sff_optoe_type.fpath_65=/sys/bus/i2c/devices/265-0050/dev_class +sff_optoe_type.addr_65=0 +sff_optoe_type.len_65=1 +sff_optoe_type.bit_offset_65= + +sff_optoe_type.mode_66=config +sff_optoe_type.int_cons_66= +sff_optoe_type.src_66=logic_file +sff_optoe_type.frmt_66=byte +sff_optoe_type.fpath_66=/sys/bus/i2c/devices/266-0050/dev_class +sff_optoe_type.addr_66=0 +sff_optoe_type.len_66=1 +sff_optoe_type.bit_offset_66= + +sff_optoe_type.mode_67=config +sff_optoe_type.int_cons_67= +sff_optoe_type.src_67=logic_file +sff_optoe_type.frmt_67=byte +sff_optoe_type.fpath_67=/sys/bus/i2c/devices/267-0050/dev_class +sff_optoe_type.addr_67=0 +sff_optoe_type.len_67=1 +sff_optoe_type.bit_offset_67= + +sff_optoe_type.mode_68=config +sff_optoe_type.int_cons_68= +sff_optoe_type.src_68=logic_file +sff_optoe_type.frmt_68=byte +sff_optoe_type.fpath_68=/sys/bus/i2c/devices/268-0050/dev_class +sff_optoe_type.addr_68=0 +sff_optoe_type.len_68=1 +sff_optoe_type.bit_offset_68= + +sff_optoe_type.mode_69=config +sff_optoe_type.int_cons_69= +sff_optoe_type.src_69=logic_file +sff_optoe_type.frmt_69=byte +sff_optoe_type.fpath_69=/sys/bus/i2c/devices/269-0050/dev_class +sff_optoe_type.addr_69=0 +sff_optoe_type.len_69=1 +sff_optoe_type.bit_offset_69= + +sff_optoe_type.mode_70=config +sff_optoe_type.int_cons_70= +sff_optoe_type.src_70=logic_file +sff_optoe_type.frmt_70=byte +sff_optoe_type.fpath_70=/sys/bus/i2c/devices/270-0050/dev_class +sff_optoe_type.addr_70=0 +sff_optoe_type.len_70=1 +sff_optoe_type.bit_offset_70= + +sff_optoe_type.mode_71=config +sff_optoe_type.int_cons_71= +sff_optoe_type.src_71=logic_file +sff_optoe_type.frmt_71=byte +sff_optoe_type.fpath_71=/sys/bus/i2c/devices/271-0050/dev_class +sff_optoe_type.addr_71=0 +sff_optoe_type.len_71=1 +sff_optoe_type.bit_offset_71= + +sff_optoe_type.mode_72=config +sff_optoe_type.int_cons_72= +sff_optoe_type.src_72=logic_file +sff_optoe_type.frmt_72=byte +sff_optoe_type.fpath_72=/sys/bus/i2c/devices/272-0050/dev_class +sff_optoe_type.addr_72=0 +sff_optoe_type.len_72=1 +sff_optoe_type.bit_offset_72= + +sff_optoe_type.mode_73=config +sff_optoe_type.int_cons_73= +sff_optoe_type.src_73=logic_file +sff_optoe_type.frmt_73=byte +sff_optoe_type.fpath_73=/sys/bus/i2c/devices/273-0050/dev_class +sff_optoe_type.addr_73=0 +sff_optoe_type.len_73=1 +sff_optoe_type.bit_offset_73= + +sff_optoe_type.mode_74=config +sff_optoe_type.int_cons_74= +sff_optoe_type.src_74=logic_file +sff_optoe_type.frmt_74=byte +sff_optoe_type.fpath_74=/sys/bus/i2c/devices/274-0050/dev_class +sff_optoe_type.addr_74=0 +sff_optoe_type.len_74=1 +sff_optoe_type.bit_offset_74= + +sff_optoe_type.mode_75=config +sff_optoe_type.int_cons_75= +sff_optoe_type.src_75=logic_file +sff_optoe_type.frmt_75=byte +sff_optoe_type.fpath_75=/sys/bus/i2c/devices/275-0050/dev_class +sff_optoe_type.addr_75=0 +sff_optoe_type.len_75=1 +sff_optoe_type.bit_offset_75= + +sff_optoe_type.mode_76=config +sff_optoe_type.int_cons_76= +sff_optoe_type.src_76=logic_file +sff_optoe_type.frmt_76=byte +sff_optoe_type.fpath_76=/sys/bus/i2c/devices/276-0050/dev_class +sff_optoe_type.addr_76=0 +sff_optoe_type.len_76=1 +sff_optoe_type.bit_offset_76= + +sff_optoe_type.mode_77=config +sff_optoe_type.int_cons_77= +sff_optoe_type.src_77=logic_file +sff_optoe_type.frmt_77=byte +sff_optoe_type.fpath_77=/sys/bus/i2c/devices/277-0050/dev_class +sff_optoe_type.addr_77=0 +sff_optoe_type.len_77=1 +sff_optoe_type.bit_offset_77= + +sff_optoe_type.mode_78=config +sff_optoe_type.int_cons_78= +sff_optoe_type.src_78=logic_file +sff_optoe_type.frmt_78=byte +sff_optoe_type.fpath_78=/sys/bus/i2c/devices/278-0050/dev_class +sff_optoe_type.addr_78=0 +sff_optoe_type.len_78=1 +sff_optoe_type.bit_offset_78= + +sff_optoe_type.mode_79=config +sff_optoe_type.int_cons_79= +sff_optoe_type.src_79=logic_file +sff_optoe_type.frmt_79=byte +sff_optoe_type.fpath_79=/sys/bus/i2c/devices/279-0050/dev_class +sff_optoe_type.addr_79=0 +sff_optoe_type.len_79=1 +sff_optoe_type.bit_offset_79= + +sff_optoe_type.mode_80=config +sff_optoe_type.int_cons_80= +sff_optoe_type.src_80=logic_file +sff_optoe_type.frmt_80=byte +sff_optoe_type.fpath_80=/sys/bus/i2c/devices/280-0050/dev_class +sff_optoe_type.addr_80=0 +sff_optoe_type.len_80=1 +sff_optoe_type.bit_offset_80= + +sff_optoe_type.mode_81=config +sff_optoe_type.int_cons_81= +sff_optoe_type.src_81=logic_file +sff_optoe_type.frmt_81=byte +sff_optoe_type.fpath_81=/sys/bus/i2c/devices/281-0050/dev_class +sff_optoe_type.addr_81=0 +sff_optoe_type.len_81=1 +sff_optoe_type.bit_offset_81= + +sff_optoe_type.mode_82=config +sff_optoe_type.int_cons_82= +sff_optoe_type.src_82=logic_file +sff_optoe_type.frmt_82=byte +sff_optoe_type.fpath_82=/sys/bus/i2c/devices/282-0050/dev_class +sff_optoe_type.addr_82=0 +sff_optoe_type.len_82=1 +sff_optoe_type.bit_offset_82= + +sff_optoe_type.mode_83=config +sff_optoe_type.int_cons_83= +sff_optoe_type.src_83=logic_file +sff_optoe_type.frmt_83=byte +sff_optoe_type.fpath_83=/sys/bus/i2c/devices/283-0050/dev_class +sff_optoe_type.addr_83=0 +sff_optoe_type.len_83=1 +sff_optoe_type.bit_offset_83= + +sff_optoe_type.mode_84=config +sff_optoe_type.int_cons_84= +sff_optoe_type.src_84=logic_file +sff_optoe_type.frmt_84=byte +sff_optoe_type.fpath_84=/sys/bus/i2c/devices/284-0050/dev_class +sff_optoe_type.addr_84=0 +sff_optoe_type.len_84=1 +sff_optoe_type.bit_offset_84= + +sff_optoe_type.mode_85=config +sff_optoe_type.int_cons_85= +sff_optoe_type.src_85=logic_file +sff_optoe_type.frmt_85=byte +sff_optoe_type.fpath_85=/sys/bus/i2c/devices/285-0050/dev_class +sff_optoe_type.addr_85=0 +sff_optoe_type.len_85=1 +sff_optoe_type.bit_offset_85= + +sff_optoe_type.mode_86=config +sff_optoe_type.int_cons_86= +sff_optoe_type.src_86=logic_file +sff_optoe_type.frmt_86=byte +sff_optoe_type.fpath_86=/sys/bus/i2c/devices/286-0050/dev_class +sff_optoe_type.addr_86=0 +sff_optoe_type.len_86=1 +sff_optoe_type.bit_offset_86= + +sff_optoe_type.mode_87=config +sff_optoe_type.int_cons_87= +sff_optoe_type.src_87=logic_file +sff_optoe_type.frmt_87=byte +sff_optoe_type.fpath_87=/sys/bus/i2c/devices/287-0050/dev_class +sff_optoe_type.addr_87=0 +sff_optoe_type.len_87=1 +sff_optoe_type.bit_offset_87= + +sff_optoe_type.mode_88=config +sff_optoe_type.int_cons_88= +sff_optoe_type.src_88=logic_file +sff_optoe_type.frmt_88=byte +sff_optoe_type.fpath_88=/sys/bus/i2c/devices/288-0050/dev_class +sff_optoe_type.addr_88=0 +sff_optoe_type.len_88=1 +sff_optoe_type.bit_offset_88= + +sff_optoe_type.mode_89=config +sff_optoe_type.int_cons_89= +sff_optoe_type.src_89=logic_file +sff_optoe_type.frmt_89=byte +sff_optoe_type.fpath_89=/sys/bus/i2c/devices/289-0050/dev_class +sff_optoe_type.addr_89=0 +sff_optoe_type.len_89=1 +sff_optoe_type.bit_offset_89= + +sff_optoe_type.mode_90=config +sff_optoe_type.int_cons_90= +sff_optoe_type.src_90=logic_file +sff_optoe_type.frmt_90=byte +sff_optoe_type.fpath_90=/sys/bus/i2c/devices/290-0050/dev_class +sff_optoe_type.addr_90=0 +sff_optoe_type.len_90=1 +sff_optoe_type.bit_offset_90= + +sff_optoe_type.mode_91=config +sff_optoe_type.int_cons_91= +sff_optoe_type.src_91=logic_file +sff_optoe_type.frmt_91=byte +sff_optoe_type.fpath_91=/sys/bus/i2c/devices/291-0050/dev_class +sff_optoe_type.addr_91=0 +sff_optoe_type.len_91=1 +sff_optoe_type.bit_offset_91= + +sff_optoe_type.mode_92=config +sff_optoe_type.int_cons_92= +sff_optoe_type.src_92=logic_file +sff_optoe_type.frmt_92=byte +sff_optoe_type.fpath_92=/sys/bus/i2c/devices/292-0050/dev_class +sff_optoe_type.addr_92=0 +sff_optoe_type.len_92=1 +sff_optoe_type.bit_offset_92= + +sff_optoe_type.mode_93=config +sff_optoe_type.int_cons_93= +sff_optoe_type.src_93=logic_file +sff_optoe_type.frmt_93=byte +sff_optoe_type.fpath_93=/sys/bus/i2c/devices/293-0050/dev_class +sff_optoe_type.addr_93=0 +sff_optoe_type.len_93=1 +sff_optoe_type.bit_offset_93= + +sff_optoe_type.mode_94=config +sff_optoe_type.int_cons_94= +sff_optoe_type.src_94=logic_file +sff_optoe_type.frmt_94=byte +sff_optoe_type.fpath_94=/sys/bus/i2c/devices/294-0050/dev_class +sff_optoe_type.addr_94=0 +sff_optoe_type.len_94=1 +sff_optoe_type.bit_offset_94= + +sff_optoe_type.mode_95=config +sff_optoe_type.int_cons_95= +sff_optoe_type.src_95=logic_file +sff_optoe_type.frmt_95=byte +sff_optoe_type.fpath_95=/sys/bus/i2c/devices/295-0050/dev_class +sff_optoe_type.addr_95=0 +sff_optoe_type.len_95=1 +sff_optoe_type.bit_offset_95= + +sff_optoe_type.mode_96=config +sff_optoe_type.int_cons_96= +sff_optoe_type.src_96=logic_file +sff_optoe_type.frmt_96=byte +sff_optoe_type.fpath_96=/sys/bus/i2c/devices/296-0050/dev_class +sff_optoe_type.addr_96=0 +sff_optoe_type.len_96=1 +sff_optoe_type.bit_offset_96= + +sff_optoe_type.mode_97=config +sff_optoe_type.int_cons_97= +sff_optoe_type.src_97=logic_file +sff_optoe_type.frmt_97=byte +sff_optoe_type.fpath_97=/sys/bus/i2c/devices/297-0050/dev_class +sff_optoe_type.addr_97=0 +sff_optoe_type.len_97=1 +sff_optoe_type.bit_offset_97= + +sff_optoe_type.mode_98=config +sff_optoe_type.int_cons_98= +sff_optoe_type.src_98=logic_file +sff_optoe_type.frmt_98=byte +sff_optoe_type.fpath_98=/sys/bus/i2c/devices/298-0050/dev_class +sff_optoe_type.addr_98=0 +sff_optoe_type.len_98=1 +sff_optoe_type.bit_offset_98= + +sff_optoe_type.mode_99=config +sff_optoe_type.int_cons_99= +sff_optoe_type.src_99=logic_file +sff_optoe_type.frmt_99=byte +sff_optoe_type.fpath_99=/sys/bus/i2c/devices/299-0050/dev_class +sff_optoe_type.addr_99=0 +sff_optoe_type.len_99=1 +sff_optoe_type.bit_offset_99= + +sff_optoe_type.mode_100=config +sff_optoe_type.int_cons_100= +sff_optoe_type.src_100=logic_file +sff_optoe_type.frmt_100=byte +sff_optoe_type.fpath_100=/sys/bus/i2c/devices/300-0050/dev_class +sff_optoe_type.addr_100=0 +sff_optoe_type.len_100=1 +sff_optoe_type.bit_offset_100= + +sff_optoe_type.mode_101=config +sff_optoe_type.int_cons_101= +sff_optoe_type.src_101=logic_file +sff_optoe_type.frmt_101=byte +sff_optoe_type.fpath_101=/sys/bus/i2c/devices/301-0050/dev_class +sff_optoe_type.addr_101=0 +sff_optoe_type.len_101=1 +sff_optoe_type.bit_offset_101= + +sff_optoe_type.mode_102=config +sff_optoe_type.int_cons_102= +sff_optoe_type.src_102=logic_file +sff_optoe_type.frmt_102=byte +sff_optoe_type.fpath_102=/sys/bus/i2c/devices/302-0050/dev_class +sff_optoe_type.addr_102=0 +sff_optoe_type.len_102=1 +sff_optoe_type.bit_offset_102= + +sff_optoe_type.mode_103=config +sff_optoe_type.int_cons_103= +sff_optoe_type.src_103=logic_file +sff_optoe_type.frmt_103=byte +sff_optoe_type.fpath_103=/sys/bus/i2c/devices/303-0050/dev_class +sff_optoe_type.addr_103=0 +sff_optoe_type.len_103=1 +sff_optoe_type.bit_offset_103= + +sff_optoe_type.mode_104=config +sff_optoe_type.int_cons_104= +sff_optoe_type.src_104=logic_file +sff_optoe_type.frmt_104=byte +sff_optoe_type.fpath_104=/sys/bus/i2c/devices/304-0050/dev_class +sff_optoe_type.addr_104=0 +sff_optoe_type.len_104=1 +sff_optoe_type.bit_offset_104= + +sff_optoe_type.mode_105=config +sff_optoe_type.int_cons_105= +sff_optoe_type.src_105=logic_file +sff_optoe_type.frmt_105=byte +sff_optoe_type.fpath_105=/sys/bus/i2c/devices/305-0050/dev_class +sff_optoe_type.addr_105=0 +sff_optoe_type.len_105=1 +sff_optoe_type.bit_offset_105= + +sff_optoe_type.mode_106=config +sff_optoe_type.int_cons_106= +sff_optoe_type.src_106=logic_file +sff_optoe_type.frmt_106=byte +sff_optoe_type.fpath_106=/sys/bus/i2c/devices/306-0050/dev_class +sff_optoe_type.addr_106=0 +sff_optoe_type.len_106=1 +sff_optoe_type.bit_offset_106= + +sff_optoe_type.mode_107=config +sff_optoe_type.int_cons_107= +sff_optoe_type.src_107=logic_file +sff_optoe_type.frmt_107=byte +sff_optoe_type.fpath_107=/sys/bus/i2c/devices/307-0050/dev_class +sff_optoe_type.addr_107=0 +sff_optoe_type.len_107=1 +sff_optoe_type.bit_offset_107= + +sff_optoe_type.mode_108=config +sff_optoe_type.int_cons_108= +sff_optoe_type.src_108=logic_file +sff_optoe_type.frmt_108=byte +sff_optoe_type.fpath_108=/sys/bus/i2c/devices/308-0050/dev_class +sff_optoe_type.addr_108=0 +sff_optoe_type.len_108=1 +sff_optoe_type.bit_offset_108= + +sff_optoe_type.mode_109=config +sff_optoe_type.int_cons_109= +sff_optoe_type.src_109=logic_file +sff_optoe_type.frmt_109=byte +sff_optoe_type.fpath_109=/sys/bus/i2c/devices/309-0050/dev_class +sff_optoe_type.addr_109=0 +sff_optoe_type.len_109=1 +sff_optoe_type.bit_offset_109= + +sff_optoe_type.mode_110=config +sff_optoe_type.int_cons_110= +sff_optoe_type.src_110=logic_file +sff_optoe_type.frmt_110=byte +sff_optoe_type.fpath_110=/sys/bus/i2c/devices/310-0050/dev_class +sff_optoe_type.addr_110=0 +sff_optoe_type.len_110=1 +sff_optoe_type.bit_offset_110= + +sff_optoe_type.mode_111=config +sff_optoe_type.int_cons_111= +sff_optoe_type.src_111=logic_file +sff_optoe_type.frmt_111=byte +sff_optoe_type.fpath_111=/sys/bus/i2c/devices/311-0050/dev_class +sff_optoe_type.addr_111=0 +sff_optoe_type.len_111=1 +sff_optoe_type.bit_offset_111= + +sff_optoe_type.mode_112=config +sff_optoe_type.int_cons_112= +sff_optoe_type.src_112=logic_file +sff_optoe_type.frmt_112=byte +sff_optoe_type.fpath_112=/sys/bus/i2c/devices/312-0050/dev_class +sff_optoe_type.addr_112=0 +sff_optoe_type.len_112=1 +sff_optoe_type.bit_offset_112= + +sff_optoe_type.mode_113=config +sff_optoe_type.int_cons_113= +sff_optoe_type.src_113=logic_file +sff_optoe_type.frmt_113=byte +sff_optoe_type.fpath_113=/sys/bus/i2c/devices/313-0050/dev_class +sff_optoe_type.addr_113=0 +sff_optoe_type.len_113=1 +sff_optoe_type.bit_offset_113= + +sff_optoe_type.mode_114=config +sff_optoe_type.int_cons_114= +sff_optoe_type.src_114=logic_file +sff_optoe_type.frmt_114=byte +sff_optoe_type.fpath_114=/sys/bus/i2c/devices/314-0050/dev_class +sff_optoe_type.addr_114=0 +sff_optoe_type.len_114=1 +sff_optoe_type.bit_offset_114= + +sff_optoe_type.mode_115=config +sff_optoe_type.int_cons_115= +sff_optoe_type.src_115=logic_file +sff_optoe_type.frmt_115=byte +sff_optoe_type.fpath_115=/sys/bus/i2c/devices/315-0050/dev_class +sff_optoe_type.addr_115=0 +sff_optoe_type.len_115=1 +sff_optoe_type.bit_offset_115= + +sff_optoe_type.mode_116=config +sff_optoe_type.int_cons_116= +sff_optoe_type.src_116=logic_file +sff_optoe_type.frmt_116=byte +sff_optoe_type.fpath_116=/sys/bus/i2c/devices/316-0050/dev_class +sff_optoe_type.addr_116=0 +sff_optoe_type.len_116=1 +sff_optoe_type.bit_offset_116= + +sff_optoe_type.mode_117=config +sff_optoe_type.int_cons_117= +sff_optoe_type.src_117=logic_file +sff_optoe_type.frmt_117=byte +sff_optoe_type.fpath_117=/sys/bus/i2c/devices/317-0050/dev_class +sff_optoe_type.addr_117=0 +sff_optoe_type.len_117=1 +sff_optoe_type.bit_offset_117= + +sff_optoe_type.mode_118=config +sff_optoe_type.int_cons_118= +sff_optoe_type.src_118=logic_file +sff_optoe_type.frmt_118=byte +sff_optoe_type.fpath_118=/sys/bus/i2c/devices/318-0050/dev_class +sff_optoe_type.addr_118=0 +sff_optoe_type.len_118=1 +sff_optoe_type.bit_offset_118= + +sff_optoe_type.mode_119=config +sff_optoe_type.int_cons_119= +sff_optoe_type.src_119=logic_file +sff_optoe_type.frmt_119=byte +sff_optoe_type.fpath_119=/sys/bus/i2c/devices/319-0050/dev_class +sff_optoe_type.addr_119=0 +sff_optoe_type.len_119=1 +sff_optoe_type.bit_offset_119= + +sff_optoe_type.mode_120=config +sff_optoe_type.int_cons_120= +sff_optoe_type.src_120=logic_file +sff_optoe_type.frmt_120=byte +sff_optoe_type.fpath_120=/sys/bus/i2c/devices/320-0050/dev_class +sff_optoe_type.addr_120=0 +sff_optoe_type.len_120=1 +sff_optoe_type.bit_offset_120= + +sff_optoe_type.mode_121=config +sff_optoe_type.int_cons_121= +sff_optoe_type.src_121=logic_file +sff_optoe_type.frmt_121=byte +sff_optoe_type.fpath_121=/sys/bus/i2c/devices/321-0050/dev_class +sff_optoe_type.addr_121=0 +sff_optoe_type.len_121=1 +sff_optoe_type.bit_offset_121= + +sff_optoe_type.mode_122=config +sff_optoe_type.int_cons_122= +sff_optoe_type.src_122=logic_file +sff_optoe_type.frmt_122=byte +sff_optoe_type.fpath_122=/sys/bus/i2c/devices/322-0050/dev_class +sff_optoe_type.addr_122=0 +sff_optoe_type.len_122=1 +sff_optoe_type.bit_offset_122= + +sff_optoe_type.mode_123=config +sff_optoe_type.int_cons_123= +sff_optoe_type.src_123=logic_file +sff_optoe_type.frmt_123=byte +sff_optoe_type.fpath_123=/sys/bus/i2c/devices/323-0050/dev_class +sff_optoe_type.addr_123=0 +sff_optoe_type.len_123=1 +sff_optoe_type.bit_offset_123= + +sff_optoe_type.mode_124=config +sff_optoe_type.int_cons_124= +sff_optoe_type.src_124=logic_file +sff_optoe_type.frmt_124=byte +sff_optoe_type.fpath_124=/sys/bus/i2c/devices/324-0050/dev_class +sff_optoe_type.addr_124=0 +sff_optoe_type.len_124=1 +sff_optoe_type.bit_offset_124= + +sff_optoe_type.mode_125=config +sff_optoe_type.int_cons_125= +sff_optoe_type.src_125=logic_file +sff_optoe_type.frmt_125=byte +sff_optoe_type.fpath_125=/sys/bus/i2c/devices/325-0050/dev_class +sff_optoe_type.addr_125=0 +sff_optoe_type.len_125=1 +sff_optoe_type.bit_offset_125= + +sff_optoe_type.mode_126=config +sff_optoe_type.int_cons_126= +sff_optoe_type.src_126=logic_file +sff_optoe_type.frmt_126=byte +sff_optoe_type.fpath_126=/sys/bus/i2c/devices/326-0050/dev_class +sff_optoe_type.addr_126=0 +sff_optoe_type.len_126=1 +sff_optoe_type.bit_offset_126= + +sff_optoe_type.mode_127=config +sff_optoe_type.int_cons_127= +sff_optoe_type.src_127=logic_file +sff_optoe_type.frmt_127=byte +sff_optoe_type.fpath_127=/sys/bus/i2c/devices/327-0050/dev_class +sff_optoe_type.addr_127=0 +sff_optoe_type.len_127=1 +sff_optoe_type.bit_offset_127= + +sff_optoe_type.mode_128=config +sff_optoe_type.int_cons_128= +sff_optoe_type.src_128=logic_file +sff_optoe_type.frmt_128=byte +sff_optoe_type.fpath_128=/sys/bus/i2c/devices/328-0050/dev_class +sff_optoe_type.addr_128=0 +sff_optoe_type.len_128=1 +sff_optoe_type.bit_offset_128= + +sff_optoe_type.mode_129=config +sff_optoe_type.int_cons_129= +sff_optoe_type.src_129=logic_file +sff_optoe_type.frmt_129=byte +sff_optoe_type.fpath_129=/sys/bus/i2c/devices/329-0050/dev_class +sff_optoe_type.addr_129=0 +sff_optoe_type.len_129=1 +sff_optoe_type.bit_offset_129= + +sff_optoe_type.mode_130=config +sff_optoe_type.int_cons_130= +sff_optoe_type.src_130=logic_file +sff_optoe_type.frmt_130=byte +sff_optoe_type.fpath_130=/sys/bus/i2c/devices/330-0050/dev_class +sff_optoe_type.addr_130=0 +sff_optoe_type.len_130=1 +sff_optoe_type.bit_offset_130= + +# Power On Group Signal Configuration +# Group 1 Configuration +port_power_group_reg.mode_1=config +port_power_group_reg.src_1=logic_file +port_power_group_reg.frmt_1=bit +port_power_group_reg.fpath_1=/dev/fpga1 +port_power_group_reg.addr_1=0x58 +port_power_group_reg.val_len_1=4 +port_power_group_reg.val_pola_1=negative +port_power_group_reg.len_1=1 +port_power_group_reg.bit_offset_1=0 + +# Group 2 Configuration +port_power_group_reg.mode_2=config +port_power_group_reg.src_2=logic_file +port_power_group_reg.frmt_2=bit +port_power_group_reg.fpath_2=/dev/fpga1 +port_power_group_reg.addr_2=0x58 +port_power_group_reg.val_len_2=4 +port_power_group_reg.val_pola_2=negative +port_power_group_reg.len_2=1 +port_power_group_reg.bit_offset_2=1 + +# Group 3 Configuration +port_power_group_reg.mode_3=config +port_power_group_reg.src_3=logic_file +port_power_group_reg.frmt_3=bit +port_power_group_reg.fpath_3=/dev/fpga1 +port_power_group_reg.addr_3=0x58 +port_power_group_reg.val_len_3=4 +port_power_group_reg.val_pola_3=negative +port_power_group_reg.len_3=1 +port_power_group_reg.bit_offset_3=2 + +# Group 4 Configuration +port_power_group_reg.mode_4=config +port_power_group_reg.src_4=logic_file +port_power_group_reg.frmt_4=bit +port_power_group_reg.fpath_4=/dev/fpga1 +port_power_group_reg.addr_4=0x58 +port_power_group_reg.val_len_4=4 +port_power_group_reg.val_pola_4=negative +port_power_group_reg.len_4=1 +port_power_group_reg.bit_offset_4=3 + +# Group 5 Configuration +port_power_group_reg.mode_5=config +port_power_group_reg.src_5=logic_file +port_power_group_reg.frmt_5=bit +port_power_group_reg.fpath_5=/dev/fpga1 +port_power_group_reg.addr_5=0x58 +port_power_group_reg.val_len_5=4 +port_power_group_reg.val_pola_5=negative +port_power_group_reg.len_5=1 +port_power_group_reg.bit_offset_5=4 + +# Group 6 Configuration +port_power_group_reg.mode_6=config +port_power_group_reg.src_6=logic_file +port_power_group_reg.frmt_6=bit +port_power_group_reg.fpath_6=/dev/fpga1 +port_power_group_reg.addr_6=0x58 +port_power_group_reg.val_len_6=4 +port_power_group_reg.val_pola_6=negative +port_power_group_reg.len_6=1 +port_power_group_reg.bit_offset_6=5 + +# Group 7 Configuration +port_power_group_reg.mode_7=config +port_power_group_reg.src_7=logic_file +port_power_group_reg.frmt_7=bit +port_power_group_reg.fpath_7=/dev/fpga1 +port_power_group_reg.addr_7=0x58 +port_power_group_reg.val_len_7=4 +port_power_group_reg.val_pola_7=negative +port_power_group_reg.len_7=1 +port_power_group_reg.bit_offset_7=6 + +# Group 8 Configuration +port_power_group_reg.mode_8=config +port_power_group_reg.src_8=logic_file +port_power_group_reg.frmt_8=bit +port_power_group_reg.fpath_8=/dev/fpga1 +port_power_group_reg.addr_8=0x58 +port_power_group_reg.val_len_8=4 +port_power_group_reg.val_pola_8=negative +port_power_group_reg.len_8=1 +port_power_group_reg.bit_offset_8=7 + +# Group 9 Configuration +port_power_group_reg.mode_9=config +port_power_group_reg.src_9=logic_file +port_power_group_reg.frmt_9=bit +port_power_group_reg.fpath_9=/dev/fpga1 +port_power_group_reg.addr_9=0x58 +port_power_group_reg.val_len_9=4 +port_power_group_reg.val_pola_9=negative +port_power_group_reg.len_9=1 +port_power_group_reg.bit_offset_9=8 + +# Group 10 Configuration +port_power_group_reg.mode_10=config +port_power_group_reg.src_10=logic_file +port_power_group_reg.frmt_10=bit +port_power_group_reg.fpath_10=/dev/fpga1 +port_power_group_reg.addr_10=0x58 +port_power_group_reg.val_len_10=4 +port_power_group_reg.val_pola_10=negative +port_power_group_reg.len_10=1 +port_power_group_reg.bit_offset_10=9 + +# Group 11 Configuration +port_power_group_reg.mode_11=config +port_power_group_reg.src_11=logic_file +port_power_group_reg.frmt_11=bit +port_power_group_reg.fpath_11=/dev/fpga1 +port_power_group_reg.addr_11=0x58 +port_power_group_reg.val_len_11=4 +port_power_group_reg.val_pola_11=negative +port_power_group_reg.len_11=1 +port_power_group_reg.bit_offset_11=10 + +# Group 12 Configuration +port_power_group_reg.mode_12=config +port_power_group_reg.src_12=logic_file +port_power_group_reg.frmt_12=bit +port_power_group_reg.fpath_12=/dev/fpga1 +port_power_group_reg.addr_12=0x58 +port_power_group_reg.val_len_12=4 +port_power_group_reg.val_pola_12=negative +port_power_group_reg.len_12=1 +port_power_group_reg.bit_offset_12=11 + +# Group 13 Configuration +port_power_group_reg.mode_13=config +port_power_group_reg.src_13=logic_file +port_power_group_reg.frmt_13=bit +port_power_group_reg.fpath_13=/dev/fpga1 +port_power_group_reg.addr_13=0x58 +port_power_group_reg.val_len_13=4 +port_power_group_reg.val_pola_13=negative +port_power_group_reg.len_13=1 +port_power_group_reg.bit_offset_13=12 + +# Group 14 Configuration +port_power_group_reg.mode_14=config +port_power_group_reg.src_14=logic_file +port_power_group_reg.frmt_14=bit +port_power_group_reg.fpath_14=/dev/fpga1 +port_power_group_reg.addr_14=0x58 +port_power_group_reg.val_len_14=4 +port_power_group_reg.val_pola_14=negative +port_power_group_reg.len_14=1 +port_power_group_reg.bit_offset_14=13 + +# Group 15 Configuration +port_power_group_reg.mode_15=config +port_power_group_reg.src_15=logic_file +port_power_group_reg.frmt_15=bit +port_power_group_reg.fpath_15=/dev/fpga1 +port_power_group_reg.addr_15=0x58 +port_power_group_reg.val_len_15=4 +port_power_group_reg.val_pola_15=negative +port_power_group_reg.len_15=1 +port_power_group_reg.bit_offset_15=14 + +# Group 16 Configuration +port_power_group_reg.mode_16=config +port_power_group_reg.src_16=logic_file +port_power_group_reg.frmt_16=bit +port_power_group_reg.fpath_16=/dev/fpga1 +port_power_group_reg.addr_16=0x58 +port_power_group_reg.val_len_16=4 +port_power_group_reg.val_pola_16=negative +port_power_group_reg.len_16=1 +port_power_group_reg.bit_offset_16=15 + +# Group 17 Configuration +port_power_group_reg.mode_17=config +port_power_group_reg.src_17=logic_file +port_power_group_reg.frmt_17=bit +port_power_group_reg.fpath_17=/dev/fpga1 +port_power_group_reg.addr_17=0x58 +port_power_group_reg.val_len_17=4 +port_power_group_reg.val_pola_17=negative +port_power_group_reg.len_17=1 +port_power_group_reg.bit_offset_17=16 + +# Group 18 Configuration +port_power_group_reg.mode_18=config +port_power_group_reg.src_18=logic_file +port_power_group_reg.frmt_18=bit +port_power_group_reg.fpath_18=/dev/fpga1 +port_power_group_reg.addr_18=0x58 +port_power_group_reg.val_len_18=4 +port_power_group_reg.val_pola_18=negative +port_power_group_reg.len_18=1 +port_power_group_reg.bit_offset_18=17 + +# Group 19 Configuration +port_power_group_reg.mode_19=config +port_power_group_reg.src_19=logic_file +port_power_group_reg.frmt_19=bit +port_power_group_reg.fpath_19=/dev/fpga1 +port_power_group_reg.addr_19=0x58 +port_power_group_reg.val_len_19=4 +port_power_group_reg.val_pola_19=negative +port_power_group_reg.len_19=1 +port_power_group_reg.bit_offset_19=18 + +# Group 20 Configuration +port_power_group_reg.mode_20=config +port_power_group_reg.src_20=logic_file +port_power_group_reg.frmt_20=bit +port_power_group_reg.fpath_20=/dev/fpga1 +port_power_group_reg.addr_20=0x58 +port_power_group_reg.val_len_20=4 +port_power_group_reg.val_pola_20=negative +port_power_group_reg.len_20=1 +port_power_group_reg.bit_offset_20=19 + +# Group 21 Configuration +port_power_group_reg.mode_21=config +port_power_group_reg.src_21=logic_file +port_power_group_reg.frmt_21=bit +port_power_group_reg.fpath_21=/dev/fpga1 +port_power_group_reg.addr_21=0x58 +port_power_group_reg.val_len_21=4 +port_power_group_reg.val_pola_21=negative +port_power_group_reg.len_21=1 +port_power_group_reg.bit_offset_21=20 + +# Group 22 Configuration +port_power_group_reg.mode_22=config +port_power_group_reg.src_22=logic_file +port_power_group_reg.frmt_22=bit +port_power_group_reg.fpath_22=/dev/fpga1 +port_power_group_reg.addr_22=0x58 +port_power_group_reg.val_len_22=4 +port_power_group_reg.val_pola_22=negative +port_power_group_reg.len_22=1 +port_power_group_reg.bit_offset_22=21 + +# Group 23 Configuration +port_power_group_reg.mode_23=config +port_power_group_reg.src_23=logic_file +port_power_group_reg.frmt_23=bit +port_power_group_reg.fpath_23=/dev/fpga1 +port_power_group_reg.addr_23=0x58 +port_power_group_reg.val_len_23=4 +port_power_group_reg.val_pola_23=negative +port_power_group_reg.len_23=1 +port_power_group_reg.bit_offset_23=22 + +# Group 24 Configuration +port_power_group_reg.mode_24=config +port_power_group_reg.src_24=logic_file +port_power_group_reg.frmt_24=bit +port_power_group_reg.fpath_24=/dev/fpga1 +port_power_group_reg.addr_24=0x58 +port_power_group_reg.val_len_24=4 +port_power_group_reg.val_pola_24=negative +port_power_group_reg.len_24=1 +port_power_group_reg.bit_offset_24=23 + +# Group 25 Configuration +port_power_group_reg.mode_25=config +port_power_group_reg.src_25=logic_file +port_power_group_reg.frmt_25=bit +port_power_group_reg.fpath_25=/dev/fpga1 +port_power_group_reg.addr_25=0x58 +port_power_group_reg.val_len_25=4 +port_power_group_reg.val_pola_25=negative +port_power_group_reg.len_25=1 +port_power_group_reg.bit_offset_25=24 + +# Group 26 Configuration +port_power_group_reg.mode_26=config +port_power_group_reg.src_26=logic_file +port_power_group_reg.frmt_26=bit +port_power_group_reg.fpath_26=/dev/fpga1 +port_power_group_reg.addr_26=0x58 +port_power_group_reg.val_len_26=4 +port_power_group_reg.val_pola_26=negative +port_power_group_reg.len_26=1 +port_power_group_reg.bit_offset_26=25 + +# Group 27 Configuration +port_power_group_reg.mode_27=config +port_power_group_reg.src_27=logic_file +port_power_group_reg.frmt_27=bit +port_power_group_reg.fpath_27=/dev/fpga1 +port_power_group_reg.addr_27=0x58 +port_power_group_reg.val_len_27=4 +port_power_group_reg.val_pola_27=negative +port_power_group_reg.len_27=1 +port_power_group_reg.bit_offset_27=26 + +# Group 28 Configuration +port_power_group_reg.mode_28=config +port_power_group_reg.src_28=logic_file +port_power_group_reg.frmt_28=bit +port_power_group_reg.fpath_28=/dev/fpga1 +port_power_group_reg.addr_28=0x58 +port_power_group_reg.val_len_28=4 +port_power_group_reg.val_pola_28=negative +port_power_group_reg.len_28=1 +port_power_group_reg.bit_offset_28=27 + +# Group 29 Configuration +port_power_group_reg.mode_29=config +port_power_group_reg.src_29=logic_file +port_power_group_reg.frmt_29=bit +port_power_group_reg.fpath_29=/dev/fpga1 +port_power_group_reg.addr_29=0x58 +port_power_group_reg.val_len_29=4 +port_power_group_reg.val_pola_29=negative +port_power_group_reg.len_29=1 +port_power_group_reg.bit_offset_29=28 + +# Group 30 Configuration +port_power_group_reg.mode_30=config +port_power_group_reg.src_30=logic_file +port_power_group_reg.frmt_30=bit +port_power_group_reg.fpath_30=/dev/fpga1 +port_power_group_reg.addr_30=0x58 +port_power_group_reg.val_len_30=4 +port_power_group_reg.val_pola_30=negative +port_power_group_reg.len_30=1 +port_power_group_reg.bit_offset_30=29 + +# Group 31 Configuration +port_power_group_reg.mode_31=config +port_power_group_reg.src_31=logic_file +port_power_group_reg.frmt_31=bit +port_power_group_reg.fpath_31=/dev/fpga1 +port_power_group_reg.addr_31=0x58 +port_power_group_reg.val_len_31=4 +port_power_group_reg.val_pola_31=negative +port_power_group_reg.len_31=1 +port_power_group_reg.bit_offset_31=30 + +# Group 32 Configuration +port_power_group_reg.mode_32=config +port_power_group_reg.src_32=logic_file +port_power_group_reg.frmt_32=bit +port_power_group_reg.fpath_32=/dev/fpga1 +port_power_group_reg.addr_32=0x58 +port_power_group_reg.val_len_32=4 +port_power_group_reg.val_pola_32=negative +port_power_group_reg.len_32=1 +port_power_group_reg.bit_offset_32=31 + +# Group 33 Configuration +port_power_group_reg.mode_33=config +port_power_group_reg.src_33=logic_file +port_power_group_reg.frmt_33=byte +port_power_group_reg.fpath_33=/dev/cpld9 +port_power_group_reg.addr_33=0x20 +port_power_group_reg.len_33=1 +port_power_group_reg.val_type_33=nega_key + +# Group 34 Configuration +port_power_group_reg.mode_34=config +port_power_group_reg.src_34=logic_file +port_power_group_reg.frmt_34=byte +port_power_group_reg.fpath_34=/dev/cpld9 +port_power_group_reg.addr_34=0x21 +port_power_group_reg.len_34=1 +port_power_group_reg.val_type_34=nega_key + +# Group 35 Configuration +port_power_group_reg.mode_35=config +port_power_group_reg.src_35=logic_file +port_power_group_reg.frmt_35=byte +port_power_group_reg.fpath_35=/dev/cpld9 +port_power_group_reg.addr_35=0x22 +port_power_group_reg.len_35=1 +port_power_group_reg.val_type_35=nega_key + +# Group 36 Configuration +port_power_group_reg.mode_36=config +port_power_group_reg.src_36=logic_file +port_power_group_reg.frmt_36=byte +port_power_group_reg.fpath_36=/dev/cpld9 +port_power_group_reg.addr_36=0x23 +port_power_group_reg.len_36=1 +port_power_group_reg.val_type_36=nega_key + +# Group 37 Configuration +port_power_group_reg.mode_37=config +port_power_group_reg.src_37=logic_file +port_power_group_reg.frmt_37=byte +port_power_group_reg.fpath_37=/dev/cpld9 +port_power_group_reg.addr_37=0x24 +port_power_group_reg.len_37=1 +port_power_group_reg.val_type_37=nega_key + +# Group 38 Configuration +port_power_group_reg.mode_38=config +port_power_group_reg.src_38=logic_file +port_power_group_reg.frmt_38=byte +port_power_group_reg.fpath_38=/dev/cpld9 +port_power_group_reg.addr_38=0x25 +port_power_group_reg.len_38=1 +port_power_group_reg.val_type_38=nega_key + +# Group 39 Configuration +port_power_group_reg.mode_39=config +port_power_group_reg.src_39=logic_file +port_power_group_reg.frmt_39=byte +port_power_group_reg.fpath_39=/dev/cpld9 +port_power_group_reg.addr_39=0x26 +port_power_group_reg.len_39=1 +port_power_group_reg.val_type_39=nega_key + +# Group 40 Configuration +port_power_group_reg.mode_40=config +port_power_group_reg.src_40=logic_file +port_power_group_reg.frmt_40=byte +port_power_group_reg.fpath_40=/dev/cpld9 +port_power_group_reg.addr_40=0x27 +port_power_group_reg.len_40=1 +port_power_group_reg.val_type_40=nega_key + +# Group 41 Configuration +port_power_group_reg.mode_41=config +port_power_group_reg.src_41=logic_file +port_power_group_reg.frmt_41=byte +port_power_group_reg.fpath_41=/dev/cpld9 +port_power_group_reg.addr_41=0x28 +port_power_group_reg.len_41=1 +port_power_group_reg.val_type_41=nega_key + +# Group 42 Configuration +port_power_group_reg.mode_42=config +port_power_group_reg.src_42=logic_file +port_power_group_reg.frmt_42=byte +port_power_group_reg.fpath_42=/dev/cpld9 +port_power_group_reg.addr_42=0x29 +port_power_group_reg.len_42=1 +port_power_group_reg.val_type_42=nega_key + +# Group 43 Configuration +port_power_group_reg.mode_43=config +port_power_group_reg.src_43=logic_file +port_power_group_reg.frmt_43=byte +port_power_group_reg.fpath_43=/dev/cpld9 +port_power_group_reg.addr_43=0x2a +port_power_group_reg.len_43=1 +port_power_group_reg.val_type_43=nega_key + +# Group 44 Configuration +port_power_group_reg.mode_44=config +port_power_group_reg.src_44=logic_file +port_power_group_reg.frmt_44=byte +port_power_group_reg.fpath_44=/dev/cpld9 +port_power_group_reg.addr_44=0x2b +port_power_group_reg.len_44=1 +port_power_group_reg.val_type_44=nega_key + +# Group 45 Configuration +port_power_group_reg.mode_45=config +port_power_group_reg.src_45=logic_file +port_power_group_reg.frmt_45=byte +port_power_group_reg.fpath_45=/dev/cpld9 +port_power_group_reg.addr_45=0x2c +port_power_group_reg.len_45=1 +port_power_group_reg.val_type_45=nega_key + +# Group 46 Configuration +port_power_group_reg.mode_46=config +port_power_group_reg.src_46=logic_file +port_power_group_reg.frmt_46=byte +port_power_group_reg.fpath_46=/dev/cpld9 +port_power_group_reg.addr_46=0x2d +port_power_group_reg.len_46=1 +port_power_group_reg.val_type_46=nega_key + +# Group 47 Configuration +port_power_group_reg.mode_47=config +port_power_group_reg.src_47=logic_file +port_power_group_reg.frmt_47=byte +port_power_group_reg.fpath_47=/dev/cpld9 +port_power_group_reg.addr_47=0x2e +port_power_group_reg.len_47=1 +port_power_group_reg.val_type_47=nega_key + +# Group 48 Configuration +port_power_group_reg.mode_48=config +port_power_group_reg.src_48=logic_file +port_power_group_reg.frmt_48=byte +port_power_group_reg.fpath_48=/dev/cpld9 +port_power_group_reg.addr_48=0x2f +port_power_group_reg.len_48=1 +port_power_group_reg.val_type_48=nega_key + +# Group 49 Configuration +port_power_group_reg.mode_49=config +port_power_group_reg.src_49=logic_file +port_power_group_reg.frmt_49=byte +port_power_group_reg.fpath_49=/dev/cpld9 +port_power_group_reg.addr_49=0x30 +port_power_group_reg.len_49=1 +port_power_group_reg.val_type_49=nega_key + +# Group 50 Configuration +port_power_group_reg.mode_50=config +port_power_group_reg.src_50=logic_file +port_power_group_reg.frmt_50=byte +port_power_group_reg.fpath_50=/dev/cpld9 +port_power_group_reg.addr_50=0x31 +port_power_group_reg.len_50=1 +port_power_group_reg.val_type_50=nega_key + +# Group 51 Configuration +port_power_group_reg.mode_51=config +port_power_group_reg.src_51=logic_file +port_power_group_reg.frmt_51=byte +port_power_group_reg.fpath_51=/dev/cpld9 +port_power_group_reg.addr_51=0x32 +port_power_group_reg.len_51=1 +port_power_group_reg.val_type_51=nega_key + +# Group 52 Configuration +port_power_group_reg.mode_52=config +port_power_group_reg.src_52=logic_file +port_power_group_reg.frmt_52=byte +port_power_group_reg.fpath_52=/dev/cpld9 +port_power_group_reg.addr_52=0x33 +port_power_group_reg.len_52=1 +port_power_group_reg.val_type_52=nega_key + +# Group 53 Configuration +port_power_group_reg.mode_53=config +port_power_group_reg.src_53=logic_file +port_power_group_reg.frmt_53=byte +port_power_group_reg.fpath_53=/dev/cpld9 +port_power_group_reg.addr_53=0x34 +port_power_group_reg.len_53=1 +port_power_group_reg.val_type_53=nega_key + +# Group 54 Configuration +port_power_group_reg.mode_54=config +port_power_group_reg.src_54=logic_file +port_power_group_reg.frmt_54=byte +port_power_group_reg.fpath_54=/dev/cpld9 +port_power_group_reg.addr_54=0x35 +port_power_group_reg.len_54=1 +port_power_group_reg.val_type_54=nega_key + +# Group 55 Configuration +port_power_group_reg.mode_55=config +port_power_group_reg.src_55=logic_file +port_power_group_reg.frmt_55=byte +port_power_group_reg.fpath_55=/dev/cpld9 +port_power_group_reg.addr_55=0x36 +port_power_group_reg.len_55=1 +port_power_group_reg.val_type_55=nega_key + +# Group 56 Configuration +port_power_group_reg.mode_56=config +port_power_group_reg.src_56=logic_file +port_power_group_reg.frmt_56=byte +port_power_group_reg.fpath_56=/dev/cpld9 +port_power_group_reg.addr_56=0x37 +port_power_group_reg.len_56=1 +port_power_group_reg.val_type_56=nega_key + +# Group 57 Configuration +port_power_group_reg.mode_57=config +port_power_group_reg.src_57=logic_file +port_power_group_reg.frmt_57=byte +port_power_group_reg.fpath_57=/dev/cpld9 +port_power_group_reg.addr_57=0x38 +port_power_group_reg.len_57=1 +port_power_group_reg.val_type_57=nega_key + +# Group 58 Configuration +port_power_group_reg.mode_58=config +port_power_group_reg.src_58=logic_file +port_power_group_reg.frmt_58=byte +port_power_group_reg.fpath_58=/dev/cpld9 +port_power_group_reg.addr_58=0x39 +port_power_group_reg.len_58=1 +port_power_group_reg.val_type_58=nega_key + +# Group 59 Configuration +port_power_group_reg.mode_59=config +port_power_group_reg.src_59=logic_file +port_power_group_reg.frmt_59=byte +port_power_group_reg.fpath_59=/dev/cpld9 +port_power_group_reg.addr_59=0x3a +port_power_group_reg.len_59=1 +port_power_group_reg.val_type_59=nega_key + +# Group 60 Configuration +port_power_group_reg.mode_60=config +port_power_group_reg.src_60=logic_file +port_power_group_reg.frmt_60=byte +port_power_group_reg.fpath_60=/dev/cpld9 +port_power_group_reg.addr_60=0x3b +port_power_group_reg.len_60=1 +port_power_group_reg.val_type_60=nega_key + +# Group 61 Configuration +port_power_group_reg.mode_61=config +port_power_group_reg.src_61=logic_file +port_power_group_reg.frmt_61=byte +port_power_group_reg.fpath_61=/dev/cpld9 +port_power_group_reg.addr_61=0x3c +port_power_group_reg.len_61=1 +port_power_group_reg.val_type_61=nega_key + +# Group 62 Configuration +port_power_group_reg.mode_62=config +port_power_group_reg.src_62=logic_file +port_power_group_reg.frmt_62=byte +port_power_group_reg.fpath_62=/dev/cpld9 +port_power_group_reg.addr_62=0x3d +port_power_group_reg.len_62=1 +port_power_group_reg.val_type_62=nega_key + +# Group 63 Configuration +port_power_group_reg.mode_63=config +port_power_group_reg.src_63=logic_file +port_power_group_reg.frmt_63=byte +port_power_group_reg.fpath_63=/dev/cpld9 +port_power_group_reg.addr_63=0x3e +port_power_group_reg.len_63=1 +port_power_group_reg.val_type_63=nega_key + +# Group 64 Configuration +port_power_group_reg.mode_64=config +port_power_group_reg.src_64=logic_file +port_power_group_reg.frmt_64=byte +port_power_group_reg.fpath_64=/dev/cpld9 +port_power_group_reg.addr_64=0x3f +port_power_group_reg.len_64=1 +port_power_group_reg.val_type_64=nega_key + +# Group 65 Configuration +port_power_group_reg.mode_65=config +port_power_group_reg.src_65=logic_file +port_power_group_reg.frmt_65=byte +port_power_group_reg.fpath_65=/dev/cpld9 +port_power_group_reg.addr_65=0x40 +port_power_group_reg.len_65=1 +port_power_group_reg.val_type_65=nega_key + +# Group 66 Configuration +port_power_group_reg.mode_66=config +port_power_group_reg.src_66=logic_file +port_power_group_reg.frmt_66=byte +port_power_group_reg.fpath_66=/dev/cpld9 +port_power_group_reg.addr_66=0x41 +port_power_group_reg.len_66=1 +port_power_group_reg.val_type_66=nega_key + +# Group 67 Configuration +port_power_group_reg.mode_67=config +port_power_group_reg.src_67=logic_file +port_power_group_reg.frmt_67=byte +port_power_group_reg.fpath_67=/dev/cpld9 +port_power_group_reg.addr_67=0x42 +port_power_group_reg.len_67=1 +port_power_group_reg.val_type_67=nega_key + +# Group 68 Configuration +port_power_group_reg.mode_68=config +port_power_group_reg.src_68=logic_file +port_power_group_reg.frmt_68=byte +port_power_group_reg.fpath_68=/dev/cpld9 +port_power_group_reg.addr_68=0x43 +port_power_group_reg.len_68=1 +port_power_group_reg.val_type_68=nega_key + +# Group 69 Configuration +port_power_group_reg.mode_69=config +port_power_group_reg.src_69=logic_file +port_power_group_reg.frmt_69=byte +port_power_group_reg.fpath_69=/dev/cpld9 +port_power_group_reg.addr_69=0x44 +port_power_group_reg.len_69=1 +port_power_group_reg.val_type_69=nega_key + +# Group 70 Configuration +port_power_group_reg.mode_70=config +port_power_group_reg.src_70=logic_file +port_power_group_reg.frmt_70=byte +port_power_group_reg.fpath_70=/dev/cpld9 +port_power_group_reg.addr_70=0x45 +port_power_group_reg.len_70=1 +port_power_group_reg.val_type_70=nega_key + +# Group 71 Configuration +port_power_group_reg.mode_71=config +port_power_group_reg.src_71=logic_file +port_power_group_reg.frmt_71=byte +port_power_group_reg.fpath_71=/dev/cpld9 +port_power_group_reg.addr_71=0x46 +port_power_group_reg.len_71=1 +port_power_group_reg.val_type_71=nega_key + +# Group 72 Configuration +port_power_group_reg.mode_72=config +port_power_group_reg.src_72=logic_file +port_power_group_reg.frmt_72=byte +port_power_group_reg.fpath_72=/dev/cpld9 +port_power_group_reg.addr_72=0x47 +port_power_group_reg.len_72=1 +port_power_group_reg.val_type_72=nega_key + +# Group 73 Configuration +port_power_group_reg.mode_73=config +port_power_group_reg.src_73=logic_file +port_power_group_reg.frmt_73=byte +port_power_group_reg.fpath_73=/dev/cpld9 +port_power_group_reg.addr_73=0x48 +port_power_group_reg.len_73=1 +port_power_group_reg.val_type_73=nega_key + +# Group 74 Configuration +port_power_group_reg.mode_74=config +port_power_group_reg.src_74=logic_file +port_power_group_reg.frmt_74=byte +port_power_group_reg.fpath_74=/dev/cpld9 +port_power_group_reg.addr_74=0x49 +port_power_group_reg.len_74=1 +port_power_group_reg.val_type_74=nega_key + +# Group 75 Configuration +port_power_group_reg.mode_75=config +port_power_group_reg.src_75=logic_file +port_power_group_reg.frmt_75=byte +port_power_group_reg.fpath_75=/dev/cpld9 +port_power_group_reg.addr_75=0x4a +port_power_group_reg.len_75=1 +port_power_group_reg.val_type_75=nega_key + +# Group 76 Configuration +port_power_group_reg.mode_76=config +port_power_group_reg.src_76=logic_file +port_power_group_reg.frmt_76=byte +port_power_group_reg.fpath_76=/dev/cpld9 +port_power_group_reg.addr_76=0x4b +port_power_group_reg.len_76=1 +port_power_group_reg.val_type_76=nega_key + +# Group 77 Configuration +port_power_group_reg.mode_77=config +port_power_group_reg.src_77=logic_file +port_power_group_reg.frmt_77=byte +port_power_group_reg.fpath_77=/dev/cpld9 +port_power_group_reg.addr_77=0x4c +port_power_group_reg.len_77=1 +port_power_group_reg.val_type_77=nega_key + +# Group 78 Configuration +port_power_group_reg.mode_78=config +port_power_group_reg.src_78=logic_file +port_power_group_reg.frmt_78=byte +port_power_group_reg.fpath_78=/dev/cpld9 +port_power_group_reg.addr_78=0x4d +port_power_group_reg.len_78=1 +port_power_group_reg.val_type_78=nega_key + +# Group 79 Configuration +port_power_group_reg.mode_79=config +port_power_group_reg.src_79=logic_file +port_power_group_reg.frmt_79=byte +port_power_group_reg.fpath_79=/dev/cpld9 +port_power_group_reg.addr_79=0x4e +port_power_group_reg.len_79=1 +port_power_group_reg.val_type_79=nega_key + +# Group 80 Configuration +port_power_group_reg.mode_80=config +port_power_group_reg.src_80=logic_file +port_power_group_reg.frmt_80=byte +port_power_group_reg.fpath_80=/dev/cpld9 +port_power_group_reg.addr_80=0x4f +port_power_group_reg.len_80=1 +port_power_group_reg.val_type_80=nega_key + +# Group 81 Configuration +port_power_group_reg.mode_81=config +port_power_group_reg.src_81=logic_file +port_power_group_reg.frmt_81=byte +port_power_group_reg.fpath_81=/dev/cpld9 +port_power_group_reg.addr_81=0x50 +port_power_group_reg.len_81=1 +port_power_group_reg.val_type_81=nega_key + +# Group 82 Configuration +port_power_group_reg.mode_82=config +port_power_group_reg.src_82=logic_file +port_power_group_reg.frmt_82=byte +port_power_group_reg.fpath_82=/dev/cpld9 +port_power_group_reg.addr_82=0x51 +port_power_group_reg.len_82=1 +port_power_group_reg.val_type_82=nega_key + +# Group 83 Configuration +port_power_group_reg.mode_83=config +port_power_group_reg.src_83=logic_file +port_power_group_reg.frmt_83=byte +port_power_group_reg.fpath_83=/dev/cpld9 +port_power_group_reg.addr_83=0x52 +port_power_group_reg.len_83=1 +port_power_group_reg.val_type_83=nega_key + +# Group 84 Configuration +port_power_group_reg.mode_84=config +port_power_group_reg.src_84=logic_file +port_power_group_reg.frmt_84=byte +port_power_group_reg.fpath_84=/dev/cpld9 +port_power_group_reg.addr_84=0x53 +port_power_group_reg.len_84=1 +port_power_group_reg.val_type_84=nega_key + +# Group 85 Configuration +port_power_group_reg.mode_85=config +port_power_group_reg.src_85=logic_file +port_power_group_reg.frmt_85=byte +port_power_group_reg.fpath_85=/dev/cpld9 +port_power_group_reg.addr_85=0x54 +port_power_group_reg.len_85=1 +port_power_group_reg.val_type_85=nega_key + +# Group 86 Configuration +port_power_group_reg.mode_86=config +port_power_group_reg.src_86=logic_file +port_power_group_reg.frmt_86=byte +port_power_group_reg.fpath_86=/dev/cpld9 +port_power_group_reg.addr_86=0x55 +port_power_group_reg.len_86=1 +port_power_group_reg.val_type_86=nega_key + +# Group 87 Configuration +port_power_group_reg.mode_87=config +port_power_group_reg.src_87=logic_file +port_power_group_reg.frmt_87=byte +port_power_group_reg.fpath_87=/dev/cpld9 +port_power_group_reg.addr_87=0x56 +port_power_group_reg.len_87=1 +port_power_group_reg.val_type_87=nega_key + +# Group 88 Configuration +port_power_group_reg.mode_88=config +port_power_group_reg.src_88=logic_file +port_power_group_reg.frmt_88=byte +port_power_group_reg.fpath_88=/dev/cpld9 +port_power_group_reg.addr_88=0x57 +port_power_group_reg.len_88=1 +port_power_group_reg.val_type_88=nega_key + +# Group 89 Configuration +port_power_group_reg.mode_89=config +port_power_group_reg.src_89=logic_file +port_power_group_reg.frmt_89=byte +port_power_group_reg.fpath_89=/dev/cpld9 +port_power_group_reg.addr_89=0x58 +port_power_group_reg.len_89=1 +port_power_group_reg.val_type_89=nega_key + +# Group 90 Configuration +port_power_group_reg.mode_90=config +port_power_group_reg.src_90=logic_file +port_power_group_reg.frmt_90=byte +port_power_group_reg.fpath_90=/dev/cpld9 +port_power_group_reg.addr_90=0x59 +port_power_group_reg.len_90=1 +port_power_group_reg.val_type_90=nega_key + +# Group 91 Configuration +port_power_group_reg.mode_91=config +port_power_group_reg.src_91=logic_file +port_power_group_reg.frmt_91=byte +port_power_group_reg.fpath_91=/dev/cpld9 +port_power_group_reg.addr_91=0x5a +port_power_group_reg.len_91=1 +port_power_group_reg.val_type_91=nega_key + +# Group 92 Configuration +port_power_group_reg.mode_92=config +port_power_group_reg.src_92=logic_file +port_power_group_reg.frmt_92=byte +port_power_group_reg.fpath_92=/dev/cpld9 +port_power_group_reg.addr_92=0x5b +port_power_group_reg.len_92=1 +port_power_group_reg.val_type_92=nega_key + +# Group 93 Configuration +port_power_group_reg.mode_93=config +port_power_group_reg.src_93=logic_file +port_power_group_reg.frmt_93=byte +port_power_group_reg.fpath_93=/dev/cpld9 +port_power_group_reg.addr_93=0x5c +port_power_group_reg.len_93=1 +port_power_group_reg.val_type_93=nega_key + +# Group 94 Configuration +port_power_group_reg.mode_94=config +port_power_group_reg.src_94=logic_file +port_power_group_reg.frmt_94=byte +port_power_group_reg.fpath_94=/dev/cpld9 +port_power_group_reg.addr_94=0x5d +port_power_group_reg.len_94=1 +port_power_group_reg.val_type_94=nega_key + +# Group 95 Configuration +port_power_group_reg.mode_95=config +port_power_group_reg.src_95=logic_file +port_power_group_reg.frmt_95=byte +port_power_group_reg.fpath_95=/dev/cpld9 +port_power_group_reg.addr_95=0x5e +port_power_group_reg.len_95=1 +port_power_group_reg.val_type_95=nega_key + +# Group 96 Configuration +port_power_group_reg.mode_96=config +port_power_group_reg.src_96=logic_file +port_power_group_reg.frmt_96=byte +port_power_group_reg.fpath_96=/dev/cpld9 +port_power_group_reg.addr_96=0x5f +port_power_group_reg.len_96=1 +port_power_group_reg.val_type_96=nega_key + +# Group 97 Configuration +port_power_group_reg.mode_97=config +port_power_group_reg.src_97=logic_file +port_power_group_reg.frmt_97=bit +port_power_group_reg.fpath_97=/dev/fpga2 +port_power_group_reg.addr_97=0x58 +port_power_group_reg.val_len_97=4 +port_power_group_reg.val_pola_97=negative +port_power_group_reg.len_97=1 +port_power_group_reg.bit_offset_97=0 + +# Group 98 Configuration +port_power_group_reg.mode_98=config +port_power_group_reg.src_98=logic_file +port_power_group_reg.frmt_98=bit +port_power_group_reg.fpath_98=/dev/fpga2 +port_power_group_reg.addr_98=0x58 +port_power_group_reg.val_len_98=4 +port_power_group_reg.val_pola_98=negative +port_power_group_reg.len_98=1 +port_power_group_reg.bit_offset_98=1 + +# Group 99 Configuration +port_power_group_reg.mode_99=config +port_power_group_reg.src_99=logic_file +port_power_group_reg.frmt_99=bit +port_power_group_reg.fpath_99=/dev/fpga2 +port_power_group_reg.addr_99=0x58 +port_power_group_reg.val_len_99=4 +port_power_group_reg.val_pola_99=negative +port_power_group_reg.len_99=1 +port_power_group_reg.bit_offset_99=2 + +# Group 100 Configuration +port_power_group_reg.mode_100=config +port_power_group_reg.src_100=logic_file +port_power_group_reg.frmt_100=bit +port_power_group_reg.fpath_100=/dev/fpga2 +port_power_group_reg.addr_100=0x58 +port_power_group_reg.val_len_100=4 +port_power_group_reg.val_pola_100=negative +port_power_group_reg.len_100=1 +port_power_group_reg.bit_offset_100=3 + +# Group 101 Configuration +port_power_group_reg.mode_101=config +port_power_group_reg.src_101=logic_file +port_power_group_reg.frmt_101=bit +port_power_group_reg.fpath_101=/dev/fpga2 +port_power_group_reg.addr_101=0x58 +port_power_group_reg.val_len_101=4 +port_power_group_reg.val_pola_101=negative +port_power_group_reg.len_101=1 +port_power_group_reg.bit_offset_101=4 + +# Group 102 Configuration +port_power_group_reg.mode_102=config +port_power_group_reg.src_102=logic_file +port_power_group_reg.frmt_102=bit +port_power_group_reg.fpath_102=/dev/fpga2 +port_power_group_reg.addr_102=0x58 +port_power_group_reg.val_len_102=4 +port_power_group_reg.val_pola_102=negative +port_power_group_reg.len_102=1 +port_power_group_reg.bit_offset_102=5 + +# Group 103 Configuration +port_power_group_reg.mode_103=config +port_power_group_reg.src_103=logic_file +port_power_group_reg.frmt_103=bit +port_power_group_reg.fpath_103=/dev/fpga2 +port_power_group_reg.addr_103=0x58 +port_power_group_reg.val_len_103=4 +port_power_group_reg.val_pola_103=negative +port_power_group_reg.len_103=1 +port_power_group_reg.bit_offset_103=6 + +# Group 104 Configuration +port_power_group_reg.mode_104=config +port_power_group_reg.src_104=logic_file +port_power_group_reg.frmt_104=bit +port_power_group_reg.fpath_104=/dev/fpga2 +port_power_group_reg.addr_104=0x58 +port_power_group_reg.val_len_104=4 +port_power_group_reg.val_pola_104=negative +port_power_group_reg.len_104=1 +port_power_group_reg.bit_offset_104=7 + +# Group 105 Configuration +port_power_group_reg.mode_105=config +port_power_group_reg.src_105=logic_file +port_power_group_reg.frmt_105=bit +port_power_group_reg.fpath_105=/dev/fpga2 +port_power_group_reg.addr_105=0x58 +port_power_group_reg.val_len_105=4 +port_power_group_reg.val_pola_105=negative +port_power_group_reg.len_105=1 +port_power_group_reg.bit_offset_105=8 + +# Group 106 Configuration +port_power_group_reg.mode_106=config +port_power_group_reg.src_106=logic_file +port_power_group_reg.frmt_106=bit +port_power_group_reg.fpath_106=/dev/fpga2 +port_power_group_reg.addr_106=0x58 +port_power_group_reg.val_len_106=4 +port_power_group_reg.val_pola_106=negative +port_power_group_reg.len_106=1 +port_power_group_reg.bit_offset_106=9 + +# Group 107 Configuration +port_power_group_reg.mode_107=config +port_power_group_reg.src_107=logic_file +port_power_group_reg.frmt_107=bit +port_power_group_reg.fpath_107=/dev/fpga2 +port_power_group_reg.addr_107=0x58 +port_power_group_reg.val_len_107=4 +port_power_group_reg.val_pola_107=negative +port_power_group_reg.len_107=1 +port_power_group_reg.bit_offset_107=10 + +# Group 108 Configuration +port_power_group_reg.mode_108=config +port_power_group_reg.src_108=logic_file +port_power_group_reg.frmt_108=bit +port_power_group_reg.fpath_108=/dev/fpga2 +port_power_group_reg.addr_108=0x58 +port_power_group_reg.val_len_108=4 +port_power_group_reg.val_pola_108=negative +port_power_group_reg.len_108=1 +port_power_group_reg.bit_offset_108=11 + +# Group 109 Configuration +port_power_group_reg.mode_109=config +port_power_group_reg.src_109=logic_file +port_power_group_reg.frmt_109=bit +port_power_group_reg.fpath_109=/dev/fpga2 +port_power_group_reg.addr_109=0x58 +port_power_group_reg.val_len_109=4 +port_power_group_reg.val_pola_109=negative +port_power_group_reg.len_109=1 +port_power_group_reg.bit_offset_109=12 + +# Group 110 Configuration +port_power_group_reg.mode_110=config +port_power_group_reg.src_110=logic_file +port_power_group_reg.frmt_110=bit +port_power_group_reg.fpath_110=/dev/fpga2 +port_power_group_reg.addr_110=0x58 +port_power_group_reg.val_len_110=4 +port_power_group_reg.val_pola_110=negative +port_power_group_reg.len_110=1 +port_power_group_reg.bit_offset_110=13 + +# Group 111 Configuration +port_power_group_reg.mode_111=config +port_power_group_reg.src_111=logic_file +port_power_group_reg.frmt_111=bit +port_power_group_reg.fpath_111=/dev/fpga2 +port_power_group_reg.addr_111=0x58 +port_power_group_reg.val_len_111=4 +port_power_group_reg.val_pola_111=negative +port_power_group_reg.len_111=1 +port_power_group_reg.bit_offset_111=14 + +# Group 112 Configuration +port_power_group_reg.mode_112=config +port_power_group_reg.src_112=logic_file +port_power_group_reg.frmt_112=bit +port_power_group_reg.fpath_112=/dev/fpga2 +port_power_group_reg.addr_112=0x58 +port_power_group_reg.val_len_112=4 +port_power_group_reg.val_pola_112=negative +port_power_group_reg.len_112=1 +port_power_group_reg.bit_offset_112=15 + +# Group 113 Configuration +port_power_group_reg.mode_113=config +port_power_group_reg.src_113=logic_file +port_power_group_reg.frmt_113=bit +port_power_group_reg.fpath_113=/dev/fpga2 +port_power_group_reg.addr_113=0x58 +port_power_group_reg.val_len_113=4 +port_power_group_reg.val_pola_113=negative +port_power_group_reg.len_113=1 +port_power_group_reg.bit_offset_113=16 + +# Group 114 Configuration +port_power_group_reg.mode_114=config +port_power_group_reg.src_114=logic_file +port_power_group_reg.frmt_114=bit +port_power_group_reg.fpath_114=/dev/fpga2 +port_power_group_reg.addr_114=0x58 +port_power_group_reg.val_len_114=4 +port_power_group_reg.val_pola_114=negative +port_power_group_reg.len_114=1 +port_power_group_reg.bit_offset_114=17 + +# Group 115 Configuration +port_power_group_reg.mode_115=config +port_power_group_reg.src_115=logic_file +port_power_group_reg.frmt_115=bit +port_power_group_reg.fpath_115=/dev/fpga2 +port_power_group_reg.addr_115=0x58 +port_power_group_reg.val_len_115=4 +port_power_group_reg.val_pola_115=negative +port_power_group_reg.len_115=1 +port_power_group_reg.bit_offset_115=18 + +# Group 116 Configuration +port_power_group_reg.mode_116=config +port_power_group_reg.src_116=logic_file +port_power_group_reg.frmt_116=bit +port_power_group_reg.fpath_116=/dev/fpga2 +port_power_group_reg.addr_116=0x58 +port_power_group_reg.val_len_116=4 +port_power_group_reg.val_pola_116=negative +port_power_group_reg.len_116=1 +port_power_group_reg.bit_offset_116=19 + +# Group 117 Configuration +port_power_group_reg.mode_117=config +port_power_group_reg.src_117=logic_file +port_power_group_reg.frmt_117=bit +port_power_group_reg.fpath_117=/dev/fpga2 +port_power_group_reg.addr_117=0x58 +port_power_group_reg.val_len_117=4 +port_power_group_reg.val_pola_117=negative +port_power_group_reg.len_117=1 +port_power_group_reg.bit_offset_117=20 + +# Group 118 Configuration +port_power_group_reg.mode_118=config +port_power_group_reg.src_118=logic_file +port_power_group_reg.frmt_118=bit +port_power_group_reg.fpath_118=/dev/fpga2 +port_power_group_reg.addr_118=0x58 +port_power_group_reg.val_len_118=4 +port_power_group_reg.val_pola_118=negative +port_power_group_reg.len_118=1 +port_power_group_reg.bit_offset_118=21 + +# Group 119 Configuration +port_power_group_reg.mode_119=config +port_power_group_reg.src_119=logic_file +port_power_group_reg.frmt_119=bit +port_power_group_reg.fpath_119=/dev/fpga2 +port_power_group_reg.addr_119=0x58 +port_power_group_reg.val_len_119=4 +port_power_group_reg.val_pola_119=negative +port_power_group_reg.len_119=1 +port_power_group_reg.bit_offset_119=22 + +# Group 120 Configuration +port_power_group_reg.mode_120=config +port_power_group_reg.src_120=logic_file +port_power_group_reg.frmt_120=bit +port_power_group_reg.fpath_120=/dev/fpga2 +port_power_group_reg.addr_120=0x58 +port_power_group_reg.val_len_120=4 +port_power_group_reg.val_pola_120=negative +port_power_group_reg.len_120=1 +port_power_group_reg.bit_offset_120=23 + +# Group 121 Configuration +port_power_group_reg.mode_121=config +port_power_group_reg.src_121=logic_file +port_power_group_reg.frmt_121=bit +port_power_group_reg.fpath_121=/dev/fpga2 +port_power_group_reg.addr_121=0x58 +port_power_group_reg.val_len_121=4 +port_power_group_reg.val_pola_121=negative +port_power_group_reg.len_121=1 +port_power_group_reg.bit_offset_121=24 + +# Group 122 Configuration +port_power_group_reg.mode_122=config +port_power_group_reg.src_122=logic_file +port_power_group_reg.frmt_122=bit +port_power_group_reg.fpath_122=/dev/fpga2 +port_power_group_reg.addr_122=0x58 +port_power_group_reg.val_len_122=4 +port_power_group_reg.val_pola_122=negative +port_power_group_reg.len_122=1 +port_power_group_reg.bit_offset_122=25 + +# Group 123 Configuration +port_power_group_reg.mode_123=config +port_power_group_reg.src_123=logic_file +port_power_group_reg.frmt_123=bit +port_power_group_reg.fpath_123=/dev/fpga2 +port_power_group_reg.addr_123=0x58 +port_power_group_reg.val_len_123=4 +port_power_group_reg.val_pola_123=negative +port_power_group_reg.len_123=1 +port_power_group_reg.bit_offset_123=26 + +# Group 124 Configuration +port_power_group_reg.mode_124=config +port_power_group_reg.src_124=logic_file +port_power_group_reg.frmt_124=bit +port_power_group_reg.fpath_124=/dev/fpga2 +port_power_group_reg.addr_124=0x58 +port_power_group_reg.val_len_124=4 +port_power_group_reg.val_pola_124=negative +port_power_group_reg.len_124=1 +port_power_group_reg.bit_offset_124=27 + +# Group 125 Configuration +port_power_group_reg.mode_125=config +port_power_group_reg.src_125=logic_file +port_power_group_reg.frmt_125=bit +port_power_group_reg.fpath_125=/dev/fpga2 +port_power_group_reg.addr_125=0x58 +port_power_group_reg.val_len_125=4 +port_power_group_reg.val_pola_125=negative +port_power_group_reg.len_125=1 +port_power_group_reg.bit_offset_125=28 + +# Group 126 Configuration +port_power_group_reg.mode_126=config +port_power_group_reg.src_126=logic_file +port_power_group_reg.frmt_126=bit +port_power_group_reg.fpath_126=/dev/fpga2 +port_power_group_reg.addr_126=0x58 +port_power_group_reg.val_len_126=4 +port_power_group_reg.val_pola_126=negative +port_power_group_reg.len_126=1 +port_power_group_reg.bit_offset_126=29 + +# Group 127 Configuration +port_power_group_reg.mode_127=config +port_power_group_reg.src_127=logic_file +port_power_group_reg.frmt_127=bit +port_power_group_reg.fpath_127=/dev/fpga2 +port_power_group_reg.addr_127=0x58 +port_power_group_reg.val_len_127=4 +port_power_group_reg.val_pola_127=negative +port_power_group_reg.len_127=1 +port_power_group_reg.bit_offset_127=30 + +# Group 128 Configuration +port_power_group_reg.mode_128=config +port_power_group_reg.src_128=logic_file +port_power_group_reg.frmt_128=bit +port_power_group_reg.fpath_128=/dev/fpga2 +port_power_group_reg.addr_128=0x58 +port_power_group_reg.val_len_128=4 +port_power_group_reg.val_pola_128=negative +port_power_group_reg.len_128=1 +port_power_group_reg.bit_offset_128=31 + +# Group 129 Configuration +port_power_group_reg.mode_129=config +port_power_group_reg.src_129=logic_file +port_power_group_reg.frmt_129=byte +port_power_group_reg.fpath_129=/dev/cpld1 +port_power_group_reg.addr_129=0x5d +port_power_group_reg.len_129=1 +port_power_group_reg.val_type_129=nega_key + +# Group 130 Configuration +port_power_group_reg.mode_130=config +port_power_group_reg.src_130=logic_file +port_power_group_reg.frmt_130=byte +port_power_group_reg.fpath_130=/dev/cpld1 +port_power_group_reg.addr_130=0x5d +port_power_group_reg.len_130=1 +port_power_group_reg.val_type_130=nega_key + +# Configuration item: sff group +# Description: Format sff_power_group_[sff_index] +sff_power_group_1=1 +sff_power_group_2=2 +sff_power_group_3=3 +sff_power_group_4=4 +sff_power_group_5=5 +sff_power_group_6=6 +sff_power_group_7=7 +sff_power_group_8=8 +sff_power_group_9=9 +sff_power_group_10=10 +sff_power_group_11=11 +sff_power_group_12=12 +sff_power_group_13=13 +sff_power_group_14=14 +sff_power_group_15=15 +sff_power_group_16=16 +sff_power_group_17=17 +sff_power_group_18=18 +sff_power_group_19=19 +sff_power_group_20=20 +sff_power_group_21=21 +sff_power_group_22=22 +sff_power_group_23=23 +sff_power_group_24=24 +sff_power_group_25=25 +sff_power_group_26=26 +sff_power_group_27=27 +sff_power_group_28=28 +sff_power_group_29=29 +sff_power_group_30=30 +sff_power_group_31=31 +sff_power_group_32=32 +sff_power_group_33=33 +sff_power_group_34=34 +sff_power_group_35=35 +sff_power_group_36=36 +sff_power_group_37=37 +sff_power_group_38=38 +sff_power_group_39=39 +sff_power_group_40=40 +sff_power_group_41=41 +sff_power_group_42=42 +sff_power_group_43=43 +sff_power_group_44=44 +sff_power_group_45=45 +sff_power_group_46=46 +sff_power_group_47=47 +sff_power_group_48=48 +sff_power_group_49=49 +sff_power_group_50=50 +sff_power_group_51=51 +sff_power_group_52=52 +sff_power_group_53=53 +sff_power_group_54=54 +sff_power_group_55=55 +sff_power_group_56=56 +sff_power_group_57=57 +sff_power_group_58=58 +sff_power_group_59=59 +sff_power_group_60=60 +sff_power_group_61=61 +sff_power_group_62=62 +sff_power_group_63=63 +sff_power_group_64=64 +sff_power_group_65=65 +sff_power_group_66=66 +sff_power_group_67=67 +sff_power_group_68=68 +sff_power_group_69=69 +sff_power_group_70=70 +sff_power_group_71=71 +sff_power_group_72=72 +sff_power_group_73=73 +sff_power_group_74=74 +sff_power_group_75=75 +sff_power_group_76=76 +sff_power_group_77=77 +sff_power_group_78=78 +sff_power_group_79=79 +sff_power_group_80=80 +sff_power_group_81=81 +sff_power_group_82=82 +sff_power_group_83=83 +sff_power_group_84=84 +sff_power_group_85=85 +sff_power_group_86=86 +sff_power_group_87=87 +sff_power_group_88=88 +sff_power_group_89=89 +sff_power_group_90=90 +sff_power_group_91=91 +sff_power_group_92=92 +sff_power_group_93=93 +sff_power_group_94=94 +sff_power_group_95=95 +sff_power_group_96=96 +sff_power_group_97=97 +sff_power_group_98=98 +sff_power_group_99=99 +sff_power_group_100=100 +sff_power_group_101=101 +sff_power_group_102=102 +sff_power_group_103=103 +sff_power_group_104=104 +sff_power_group_105=105 +sff_power_group_106=106 +sff_power_group_107=107 +sff_power_group_108=108 +sff_power_group_109=109 +sff_power_group_110=110 +sff_power_group_111=111 +sff_power_group_112=112 +sff_power_group_113=113 +sff_power_group_114=114 +sff_power_group_115=115 +sff_power_group_116=116 +sff_power_group_117=117 +sff_power_group_118=118 +sff_power_group_119=119 +sff_power_group_120=120 +sff_power_group_121=121 +sff_power_group_122=122 +sff_power_group_123=123 +sff_power_group_124=124 +sff_power_group_125=125 +sff_power_group_126=126 +sff_power_group_127=127 +sff_power_group_128=128 +sff_power_group_129=129 +sff_power_group_130=130 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg new file mode 100644 index 0000000000..cdd750beb9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg @@ -0,0 +1,20 @@ + +# Configuration item: watchdog number +# Description: Format watchdog_id_[index] +watchdog_id_0=0 + +# Configuration item: watchdog device name +# Description: Format watchdog_name_[index]_[type] +watchdog_name_0_0=identity +watchdog_name_0_1=state +watchdog_name_0_2=timeleft +watchdog_name_0_3=timeout + +# enable +watchdog_dev.mode_0_4=config +watchdog_dev.src_0_4=file +watchdog_dev.frmt_0_4=bit +watchdog_dev.fpath_0_4=/dev/cpld1 +watchdog_dev.addr_0_4=0x40 +watchdog_dev.len_0_4=1 +watchdog_dev.bit_offset_0_4=0 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/file_name/0x414e b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/file_name/0x414e new file mode 100644 index 0000000000..0032cdd9cb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/s3ip_sysfs_cfg/file_name/0x414e @@ -0,0 +1,7 @@ +CPLD +FAN +LED +PSU +SENSOR +SFF +FPGA diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/setup.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/setup.py new file mode 100644 index 0000000000..6c3916921a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6950-128oc/setup.py @@ -0,0 +1,39 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation', + license='Apache 2.0', + author='SONiC Team', + author_email='support', + url='', + maintainer='support', + maintainer_email='', + packages=[ + 'sonic_platform', + 'plat_hal', + 'wbutil', + 'eepromutil', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/Makefile new file mode 100644 index 0000000000..d6066a67a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/Makefile @@ -0,0 +1,29 @@ +PWD = $(shell pwd) +DIR_KERNEL_SRC = $(PWD)/modules/driver +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +SUB_BUILD_DIR = $(PWD)/build +INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) +INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_S3IP_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/s3ip_sysfs_cfg +INSTALL_S3IP_CONFIG_DIR = $(SUB_BUILD_DIR)/etc/s3ip + +all: + $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules + @if [ ! -d ${INSTALL_DIR} ]; then mkdir -p ${INSTALL_DIR} ;fi + cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) + @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi + cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/.upgrade_test/ ]; then cp -r $(PWD)/.upgrade_test/* ${INSTALL_UPGRADE_TEST_DIR} ;fi + @if [ ! -d ${INSTALL_S3IP_CONFIG_DIR} ]; then mkdir -p ${INSTALL_S3IP_CONFIG_DIR} ;fi + @if [ -d $(PWD)/s3ip_config/ ]; then cp -r $(PWD)/s3ip_config/* ${INSTALL_S3IP_CONFIG_DIR} ;fi + @if [ ! -d ${INSTALL_S3IP_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_S3IP_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/s3ip_sysfs_cfg/ ]; then cp -r $(PWD)/s3ip_sysfs_cfg/* ${INSTALL_S3IP_SYSFS_CFG_DIR} ;fi +clean: + rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd ${DIR_KERNEL_SRC}/*.mod + rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order + rm -rf ${DIR_KERNEL_SRC}/.tmp_versions + rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_config.py new file mode 100644 index 0000000000..811c3a11bc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_config.py @@ -0,0 +1,1511 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- +from platform_common import * + +STARTMODULE = { + "hal_fanctrl": 1, + "hal_ledctrl": 1, + "avscontrol": 1, + "tty_console": 1, + "dev_monitor": 1, + "pmon_syslog": 1, + "sff_temp_polling": 1, + "reboot_cause": 1, + "generate_airflow": 0, +} + +DEV_MONITOR_PARAM = { + "polling_time": 10, + "psus": [ + { + "name": "psu1", + "present": {"gettype": "direct_config", "value": 0, "okval": 0}, + "device": [ + {"id": "psu1pmbus", "name": "wb_fsp1200", "bus": 53, "loc": 0x60, "attr": "hwmon"} + ], + }, + { + "name": "psu2", + "present": {"gettype": "direct_config", "value": 0, "okval": 0}, + "device": [ + {"id": "psu2pmbus", "name": "wb_fsp1200", "bus": 54, "loc": 0x60, "attr": "hwmon"} + ], + }, + { + "name": "psu3", + "present": {"gettype": "direct_config", "value": 0, "okval": 0}, + "device": [ + {"id": "psu3pmbus", "name": "wb_fsp1200", "bus": 55, "loc": 0x60, "attr": "hwmon"} + ], + }, + { + "name": "psu4", + "present": {"gettype": "direct_config", "value": 0, "okval": 0}, + "device": [ + {"id": "psu4pmbus", "name": "wb_fsp1200", "bus": 56, "loc": 0x60, "attr": "hwmon"} + ], + }, + ], + "fans": [ + { + "name": "fan1", + "present": {"gettype": "devfile", "path": "/dev/cpld10", "offset": 0xda, "read_len":1, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "fan1frue2", "name": "wb_24c64", "bus": 59, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan2", + "present": {"gettype": "devfile", "path": "/dev/cpld10", "offset": 0xda, "read_len":1, "presentbit": 1, "okval": 0}, + "device": [ + {"id": "fan2frue2", "name": "wb_24c64", "bus": 60, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan3", + "present": {"gettype": "devfile", "path": "/dev/cpld10", "offset": 0xda, "read_len":1, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan3frue2", "name": "wb_24c64", "bus": 61, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan4", + "present": {"gettype": "devfile", "path": "/dev/cpld10", "offset": 0xda, "read_len":1, "presentbit": 3, "okval": 0}, + "device": [ + {"id": "fan4frue2", "name": "wb_24c64", "bus": 62, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan5", + "present": {"gettype": "devfile", "path": "/dev/cpld10", "offset": 0xda, "read_len":1, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "fan5frue2", "name": "wb_24c64", "bus": 63, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan6", + "present": {"gettype": "devfile", "path": "/dev/cpld10", "offset": 0xda, "read_len":1, "presentbit": 5, "okval": 0}, + "device": [ + {"id": "fan6frue2", "name": "wb_24c64", "bus": 64, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "24c02", "bus": 1, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "lm75", "bus": 65, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_2", "name": "lm75", "bus": 66, "loc": 0x4e, "attr": "hwmon"}, + {"id": "lm75_3", "name": "lm75", "bus": 76, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_4", "name": "lm75", "bus": 77, "loc": 0x4f, "attr": "hwmon"}, + {"id": "lm75_5", "name": "lm75", "bus": 111, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_6", "name": "lm75", "bus": 112, "loc": 0x4f, "attr": "hwmon"}, + ], + }, + { + "name":"ct7318", + "device":[ + {"id":"ct7318_1", "name":"ct7318","bus":78, "loc":0x4c, "attr":"hwmon"}, + {"id":"ct7318_2", "name":"ct7318","bus":79, "loc":0x4c, "attr":"hwmon"}, + {"id":"ct7318_3", "name":"ct7318","bus":80, "loc":0x4c, "attr":"hwmon"}, + ], + }, + { + "name": "ucd90160", + "device": [ + {"id": "ucd90160_1", "name": "ucd90160", "bus": 69, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_2", "name": "ucd90160", "bus": 70, "loc": 0x5f, "attr": "hwmon"}, + {"id": "ucd90160_3", "name": "ucd90160", "bus": 83, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_4", "name": "ucd90160", "bus": 84, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_5", "name": "ucd90160", "bus": 73, "loc": 0x68, "attr": "hwmon"}, + ], + }, + { + "name": "ads7828", + "device": [ + {"id": "ads7828_1", "name": "ads7828", "bus": 97, "loc": 0x48, "attr": "hwmon"}, + {"id": "ads7828_2", "name": "ads7828", "bus": 97, "loc": 0x4A, "attr": "hwmon"}, + {"id": "ads7828_3", "name": "ads7828", "bus": 13, "loc": 0x48, "attr": "hwmon"}, + {"id": "ads7828_4", "name": "ads7828", "bus": 14, "loc": 0x48, "attr": "hwmon"}, + ], + }, + { + "name": "ina3221", + "device": [ + {"id": "ina3221_1", "name": "ina3221", "bus": 98, "loc": 0x40, "attr": "hwmon"}, + ], + }, + { + "name": "isl68137", + "device": [ + {"id": "raa228228", "name": "isl68137", "bus": 85, "loc": 0x60, "attr": "hwmon"}, + {"id": "raa228228_1", "name": "isl68137", "bus": 70, "loc": 0x72, "attr": "hwmon"}, + {"id": "raa228228_2", "name": "isl68137", "bus": 70, "loc": 0x74, "attr": "hwmon"}, + {"id": "isl69260_1", "name": "isl68137", "bus": 85, "loc": 0x62, "attr": "hwmon"}, + {"id": "isl69260_2", "name": "isl68137", "bus": 85, "loc": 0x74, "attr": "hwmon"}, + {"id": "isl69260_3", "name": "isl68137", "bus": 87, "loc": 0x60, "attr": "hwmon"}, + {"id": "isl69260_4", "name": "isl68137", "bus": 87, "loc": 0x62, "attr": "hwmon"}, + {"id": "isl69260_5", "name": "isl68137", "bus": 87, "loc": 0x74, "attr": "hwmon"}, + {"id": "isl69260_6", "name": "isl68137", "bus": 89, "loc": 0x74, "attr": "hwmon"}, + {"id": "isl69260_7", "name": "isl68137", "bus": 89, "loc": 0x60, "attr": "hwmon"}, + {"id": "isl69260_8", "name": "isl68137", "bus": 90, "loc": 0x60, "attr": "hwmon"}, + {"id": "isl69260_9", "name": "isl68137", "bus": 91, "loc": 0x62, "attr": "hwmon"}, + {"id": "isl69260_10", "name": "isl68137", "bus": 91, "loc": 0x60, "attr": "hwmon"}, + {"id": "isl69260_11", "name": "isl68137", "bus": 92, "loc": 0x60, "attr": "hwmon"}, + {"id": "isl69260_12", "name": "isl68137", "bus": 92, "loc": 0x62, "attr": "hwmon"}, + {"id": "isl69260_13", "name": "isl68137", "bus": 95, "loc": 0x60, "attr": "hwmon"}, + ], + }, + ], +} + +MANUINFO_CONF = { #tocheck + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, + + "cpu": { + "key": "CPU", + "next": "ssd" + }, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, + }, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, + }, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, + }, + "ssd": { + "key": "SSD", + "next": "cpld" + }, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, + }, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, + }, + + "cpld": { + "key": "CPLD", + "next": "psu" + }, + + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "devfile": { + "loc": "/dev/cpld0", + "offset":0, + "len":4, + "bit_width":1 + }, + "arrt_index": 4, + }, + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-4300C-6BG324I", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "BASE_CPLD", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "devfile": { + "loc": "/dev/cpld1", + "offset":0, + "len":4, + "bit_width":1 + }, + "arrt_index": 4, + }, + + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-4300C-6BG324I", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "MAC_CPLDA", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "devfile": { + "loc": "/dev/cpld6", + "offset":0, + "len":4, + "bit_width":1 + }, + "arrt_index": 4, + }, + + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO3LF-4300C-6BG324I", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "MAC_CPLDB", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "devfile": { + "loc": "/dev/cpld7", + "offset":0, + "len":4, + "bit_width":1 + }, + "arrt_index": 4, + }, + + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO3LF-4300C-6BG324I", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "IO_CPLD", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "devfile": { + "loc": "/dev/cpld8", + "offset":0, + "len":4, + "bit_width":1 + }, + "arrt_index": 4, + }, + + "cpld6": { + "key": "CPLD6", + "parent": "cpld", + "arrt_index": 6, + }, + "cpld6_model": { + "key": "Device Model", + "parent": "cpld6", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld6_vender": { + "key": "Vendor", + "parent": "cpld6", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld6_desc": { + "key": "Description", + "parent": "cpld6", + "config": "FAN_CPLD", + "arrt_index": 3, + }, + "cpld6_version": { + "key": "Firmware Version", + "parent": "cpld6", + "devfile": { + "loc": "/dev/cpld10", + "offset":0, + "len":4, + "bit_width":1 + }, + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, + + "e610": { + "key": "NIC", + "next": "fpga" + }, + "i210_model": { + "parent": "e610", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "e610", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "e610", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, + + "fpga": { + "key": "FPGA", + "next": "others" + }, + + "fpga1": { + "key": "FPGA1", + "parent": "fpga", + "arrt_index": 1, + }, + "fpga1_model": { + "parent": "fpga1", + "devfile": { + "loc": "/dev/fpga0", + "offset":0x10, + "len":4, + "bit_width":4 + }, + "decode": { + "00000050": "XC7A50T_2FGG484C", + "00000100": "XC7A100T_2FGG484C" + }, + "key": "Device Model", + "arrt_index": 1, + }, + "fpga1_vender": { + "parent": "fpga1", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga1_desc": { + "key": "Description", + "parent": "fpga1", + "config": "MAC_FPGA", + "arrt_index": 3, + }, + "fpga1_hw_version": { + "parent": "fpga1", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga1_fw_version": { + "parent": "fpga1", + "devfile": { + "loc": "/dev/fpga0", + "offset":0, + "len":4, + "bit_width":4 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga1_date": { + "parent": "fpga1", + "devfile": { + "loc": "/dev/fpga0", + "offset":4, + "len":4, + "bit_width":4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + + "fpga2": { + "key": "FPGA2", + "parent": "fpga", + "arrt_index": 2, + }, + "fpga2_model": { + "parent": "fpga2", + "devfile": { + "loc": "/dev/fpga1", + "offset":0x10, + "len":4, + "bit_width":4 + }, + "decode": { + "00000050": "XC7A50T_2FGG484C", + "00000100": "XC7A100T_2FGG484C" + }, + "key": "Device Model", + "arrt_index": 2, + }, + "fpga2_vender": { + "parent": "fpga2", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga2_desc": { + "key": "Description", + "parent": "fpga2", + "config": "IO_FPGA", + "arrt_index": 3, + }, + "fpga2_hw_version": { + "parent": "fpga2", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga2_fw_version": { + "parent": "fpga2", + "devfile": { + "loc": "/dev/fpga1", + "offset":0, + "len":4, + "bit_width":4 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga2_date": { + "parent": "fpga2", + "devfile": { + "loc": "/dev/fpga1", + "offset":4, + "len":4, + "bit_width":4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + + "others": { + "key": "OTHERS", + }, + "53134": { + "parent": "others", + "key": "CPU-BMC-SWITCH", + "arrt_index": 1, + }, + "53134_model": { + "parent": "53134", + "config": "BCM53134O", + "key": "Device Model", + "arrt_index": 1, + }, + "53134_vendor": { + "parent": "53134", + "config": "Broadcom", + "key": "Vendor", + "arrt_index": 2, + }, + "53134_hw_version": { + "parent": "53134", + "key": "Hardware Version", + "func": { + "funcname": "get_bcm5387_version", + "params": { + "before": [ + # OE high + {"gettype": "cmd", "cmd": "echo 10051 > /sys/class/gpio/export"}, + {"gettype": "cmd", "cmd": "echo high > /sys/class/gpio/gpio10051/direction"}, + # SEL1 high + {"gettype": "cmd", "cmd": "echo 10052 > /sys/class/gpio/export"}, + {"gettype": "cmd", "cmd": "echo high > /sys/class/gpio/gpio10052/direction"}, + #enable 53134 update + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0xe9, "value": 0x16}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0xe1, "value": 0x01}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0xe2, "value": 0x05}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio_device sck=55 mosi=54 miso=52 cs=53 bus=0 gpio_chip_name=INTC3001:00"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_93xx46"}, + ], + "get_version": "md5sum /sys/bus/spi/devices/spi0.0/eeprom | awk '{print $1}'", + "after": [ + {"gettype": "cmd", "cmd": "echo 0 > /sys/class/gpio/gpio10052/value"}, + {"gettype": "cmd", "cmd": "echo 10052 > /sys/class/gpio/unexport"}, + {"gettype": "cmd", "cmd": "echo 0 > /sys/class/gpio/gpio10051/value"}, + {"gettype": "cmd", "cmd": "echo 10051 > /sys/class/gpio/unexport"}, + ], + "finally": [ + {"gettype": "cmd", "cmd": "rmmod wb_spi_93xx46"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio_device"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio"}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0xe2, "value": 0x00}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0xe1, "value": 0x00}, + {"gettype": "devfile", "path": "/dev/cpld1", "offset": 0xe9, "value": 0x17}, + ], + }, + }, + "arrt_index": 3, + }, +} + +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/s3ip/transceiver/*/present"], "ABSENT": 0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "sff1": "Ethernet1", + "sff2": "Ethernet2", + "sff3": "Ethernet3", + "sff4": "Ethernet4", + "sff5": "Ethernet5", + "sff6": "Ethernet6", + "sff7": "Ethernet7", + "sff8": "Ethernet8", + "sff9": "Ethernet9", + "sff10": "Ethernet10", + "sff11": "Ethernet11", + "sff12": "Ethernet12", + "sff13": "Ethernet13", + "sff14": "Ethernet14", + "sff15": "Ethernet15", + "sff16": "Ethernet16", + "sff17": "Ethernet17", + "sff18": "Ethernet18", + "sff19": "Ethernet19", + "sff20": "Ethernet20", + "sff21": "Ethernet21", + "sff22": "Ethernet22", + "sff23": "Ethernet23", + "sff24": "Ethernet24", + "sff25": "Ethernet25", + "sff26": "Ethernet26", + "sff27": "Ethernet27", + "sff28": "Ethernet28", + "sff29": "Ethernet29", + "sff30": "Ethernet30", + "sff31": "Ethernet31", + "sff32": "Ethernet32", + "sff33": "Ethernet33", + "sff34": "Ethernet34", + "sff35": "Ethernet35", + "sff36": "Ethernet36", + "sff37": "Ethernet37", + "sff38": "Ethernet38", + "sff39": "Ethernet39", + "sff40": "Ethernet40", + "sff41": "Ethernet41", + "sff42": "Ethernet42", + "sff43": "Ethernet43", + "sff44": "Ethernet44", + "sff45": "Ethernet45", + "sff46": "Ethernet46", + "sff47": "Ethernet47", + "sff48": "Ethernet48", + "sff49": "Ethernet49", + "sff50": "Ethernet50", + "sff51": "Ethernet51", + "sff52": "Ethernet52", + "sff53": "Ethernet53", + "sff54": "Ethernet54", + "sff55": "Ethernet55", + "sff56": "Ethernet56", + "sff57": "Ethernet57", + "sff58": "Ethernet58", + "sff59": "Ethernet59", + "sff60": "Ethernet60", + "sff61": "Ethernet61", + "sff62": "Ethernet62", + "sff63": "Ethernet63", + "sff64": "Ethernet64", + "sff65": "Ethernet65", + "sff66": "Ethernet66", + } + }, + "fans": { + "present": {"path": ["/sys/s3ip/fan/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/s3ip/fan/%s/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4", + "fan5": "FAN5", + "fan6": "FAN6" + } + }, + "psus": { + "present": {"path": ["/sys/s3ip/psu/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/s3ip/psu/%s/out_status", "okval":1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2", + "psu3": "PSU3", + "psu4": "PSU4" + } + } +} + +REBOOT_CAUSE_PARA = { + "reboot_cause_list": [ + { + "name": "cold_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x3a, "read_len":1, "okval":0x01}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Power Loss, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Power Loss, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ] + }, + { + "name": "wdt_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x3a, "read_len":1, "okval":0x07}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Watchdog, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Watchdog, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "bmc_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x3a, "read_len":1, "okval":0x08}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC reboot, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC reboot, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "cpu_reboot", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x3a, "read_len":1, "okval":0x06}, + "record": [ + {"record_type":"file", "mode":"cover", "log":"CPU reboot, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "CPU reboot, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "bmc_powerdown", + "monitor_point": {"gettype":"devfile", "path":"/dev/cpld1", "offset":0x3a, "read_len":1, "okval":[0x04, 0x02, 0x09]}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC powerdown, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC powerdown, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + }, + { + "name": "otp_switch_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_switch_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: ASIC, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: ASIC, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_switch_reboot_flag"}, + ] + }, + { + "name": "otp_other_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_other_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: Other, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: Other, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_other_reboot_flag"}, + ] + }, + ], + "other_reboot_cause_record": [ + {"record_type": "file", "mode": "cover", "log": "Other, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Other, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], +} + +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "MAC_CORE_V", # AVS name + "type": 0, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x8a, # default value, if rov value not in range + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"path": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs1", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/85-0060/hwmon/hwmon*/avs0_vout", "gettype": "sysfs", "formula": "int((%f)*1000000)"}, + "mac_avs_param": { + 0x8c: 0.7375, + 0x8a: 0.75, + 0x88: 0.7625, + 0x86: 0.775, + 0x84: 0.7875, + 0x82: 0.8, + 0x80: 0.8125, + 0x7f: 0.825 + } + }, + { + "name": "MAC_PT0_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs2", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/87-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT1_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs3", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/87-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT2_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs4", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/89-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT3_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs5", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/89-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT4_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs6", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/90-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT5_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs7", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/90-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT6_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs8", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/95-0060/hwmon/hwmon*/avs0_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, + { + "name": "MAC_PT7_VDDC_V", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default" : 0x8e, + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + # bsc unsupport, use default value 725000 + "cpld_avs": {"loc": "/sys/bus/i2c/devices/75-0044/hwmon/hwmon*/avs9", "gettype": "sysfs"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/95-0060/hwmon/hwmon*/avs1_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x8e : 0.725, + }, + }, +] + +DRIVERLISTS = [ + {"name": "wb_ixgbe", "delay": 0, "removable": 0}, + {"name": "ice", "delay": 0, "removable": 0}, + {"name": "ads7828", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "wb_i2c_designware_core", "delay": 0}, #temp, driver has not moved + {"name": "wb_i2c_designware_platform sda_fall_ns=320 scl_fall_ns=1006 bus_freq_hz=100000", "delay": 0}, #temp, driver has not moved + {"name": "i2c_algo_bit", "delay": 0}, + {"name": "i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=116 gpio_scl=115 gpio_chip_name=AMDI0030:00 bus_num=21", "delay": 0}, + {"name": "platform_common dfd_my_type=0x414c", "delay": 0}, + {"name": "wb_logic_dev_common", "delay":0}, + {"name": "wb_fpga_pcie", "delay": 0}, + {"name": "wb_pcie_dev", "delay": 0}, + {"name": "wb_pcie_dev_device", "delay": 0}, + #{"name": "wb_io_dev", "delay": 0}, + #{"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_spi_dev", "delay": 0}, + {"name": "wb_spi_ocores", "delay": 0}, + {"name": "wb_spi_ocores_device", "delay": 0}, + {"name": "wb_spi_dev_device", "delay": 0}, + {"name": "wb_indirect_dev", "delay": 0}, + {"name": "wb_indirect_dev_device", "delay": 0}, + {"name": "wb_fpga_i2c_bus_drv", "delay": 0}, + {"name": "wb_fpga_i2c_bus_device", "delay": 0}, + {"name": "wb_i2c_mux_pca954x", "delay": 0}, + {"name": "wb_i2c_mux_pca954x_device", "delay": 0}, + {"name": "wb_fpga_pca954x_drv", "delay": 0}, + {"name": "wb_fpga_pca954x_device", "delay": 0}, + {"name": "wb_i2c_dev_device", "delay": 0}, + {"name": "i2c_piix4", "delay": 1}, + {"name": "mdio_bitbang", "delay": 0}, + {"name": "mdio_gpio", "delay": 0}, + {"name": "wb_mdio_gpio_device gpio_mdc=131 gpio_mdio=132 gpio_chip_name=AMDI0030:00", "delay": 0}, + {"name": "wb_wdt", "delay": 0}, + {"name": "wb_wdt_device", "delay": 0}, + {"name": "lm75", "delay": 0}, + {"name": "tmp401", "delay": 0}, + {"name": "ct7148", "delay": 0}, + {"name": "wb_rc32312", "delay": 0}, + {"name": "optoe", "delay": 0}, + {"name": "at24", "delay": 0}, + {"name": "pmbus_core", "delay": 0}, + {"name": "ina238", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "ina3221", "delay": 0}, + {"name": "tps53679", "delay": 0}, + {"name": "ucd9000", "delay": 0}, + {"name": "wb_ucd9081", "delay": 0}, + {"name": "xdpe12284", "delay": 0}, + {"name": "wb_xdpe132g5c_pmbus", "delay":0}, + {"name": "wb_xdpe132g5c", "delay": 0}, + {"name": "hw_test", "delay": 0}, + #{"name": "firmware_driver_cpld", "delay": 0}, + #{"name": "firmware_driver_ispvme", "delay": 0}, + #{"name": "firmware_driver_sysfs", "delay": 0}, + #{"name": "wb_firmware_upgrade_device", "delay": 0}, + {"name": "isl68137", "delay": 0}, + {"name": "s3ip_sysfs", "delay": 0}, + {"name": "wb_switch_driver", "delay": 0}, + {"name": "syseeprom_device_driver", "delay": 0}, + {"name": "fan_device_driver", "delay": 0}, + {"name": "cpld_device_driver", "delay": 0}, + {"name": "sysled_device_driver", "delay": 0}, + {"name": "psu_device_driver", "delay": 0}, + {"name": "transceiver_device_driver", "delay": 0}, + {"name": "temp_sensor_device_driver", "delay": 0}, + {"name": "vol_sensor_device_driver", "delay": 0}, + {"name": "curr_sensor_device_driver", "delay": 0}, + {"name": "fpga_device_driver", "delay": 0}, + {"name": "watchdog_device_driver", "delay": 0}, +] + +DEVICE = [ + # SYS E2 + {"name": "24c02", "bus": 1, "loc": 0x56}, + {"name": "24c02", "bus": 1, "loc": 0x57}, + # IO board E2 + {"name": "24c02", "bus": 12, "loc": 0x54}, + # FAN board E2 + {"name": "24c02", "bus": 427, "loc": 0x57}, + # BASE board E2 + {"name": "24c02", "bus": 67, "loc": 0x57}, + # MAC board E2 + {"name": "24c02", "bus": 105, "loc": 0x57}, + # fan + {"name": "24c64", "bus": 59, "loc": 0x50}, + {"name": "24c64", "bus": 60, "loc": 0x50}, + {"name": "24c64", "bus": 61, "loc": 0x50}, + {"name": "24c64", "bus": 62, "loc": 0x50}, + {"name": "24c64", "bus": 63, "loc": 0x50}, + {"name": "24c64", "bus": 64, "loc": 0x50}, + # psu + {"name": "wb_fsp1200", "bus": 53, "loc": 0x60}, + {"name": "wb_fsp1200", "bus": 54, "loc": 0x60}, + {"name": "wb_fsp1200", "bus": 55, "loc": 0x60}, + {"name": "wb_fsp1200", "bus": 56, "loc": 0x60}, + # temp + {"name": "lm75", "bus": 65, "loc": 0x4b}, + {"name": "lm75", "bus": 66, "loc": 0x4e}, + {"name": "lm75", "bus": 76, "loc": 0x4b}, + {"name": "lm75", "bus": 77, "loc": 0x4f}, + {"name": "lm75", "bus": 111, "loc": 0x4b}, + {"name": "lm75", "bus": 112, "loc": 0x4f}, + {"name": "ct7318", "bus": 78, "loc": 0x4c}, + {"name": "ct7318", "bus": 79, "loc": 0x4c}, + {"name": "ct7318", "bus": 80, "loc": 0x4c}, + #dcdc + {"name": "ucd90160", "bus": 69, "loc": 0x5b}, + {"name": "ucd90160", "bus": 70, "loc": 0x5f}, + {"name": "ucd90160", "bus": 73, "loc": 0x68}, + {"name": "ucd90160", "bus": 83, "loc": 0x5b}, + {"name": "ucd90160", "bus": 84, "loc": 0x5b}, + {"name": "wb_ina238", "bus": 57, "loc": 0x40}, + {"name": "wb_ina238", "bus": 58, "loc": 0x41}, + {"name": "ads7828", "bus": 97, "loc": 0x48}, + {"name": "ads7828", "bus": 97, "loc": 0x4a}, + {"name": "ina3221", "bus": 98, "loc": 0x40}, + {"name": "raa228228", "bus": 70, "loc": 0x72}, + {"name": "raa228228", "bus": 70, "loc": 0x74}, + {"name": "raa228228", "bus": 85, "loc": 0x60}, + {"name": "isl69260", "bus": 85, "loc": 0x62}, + {"name": "isl69260", "bus": 85, "loc": 0x74}, + {"name": "isl69260", "bus": 87, "loc": 0x60}, + {"name": "isl69260", "bus": 87, "loc": 0x62}, + {"name": "isl69260", "bus": 87, "loc": 0x74}, + {"name": "isl69260", "bus": 89, "loc": 0x74}, + {"name": "isl69260", "bus": 89, "loc": 0x60}, + {"name": "isl69260", "bus": 90, "loc": 0x60}, + {"name": "isl69260", "bus": 91, "loc": 0x60}, + {"name": "isl69260", "bus": 91, "loc": 0x62}, + {"name": "isl69260", "bus": 92, "loc": 0x60}, + {"name": "isl69260", "bus": 92, "loc": 0x62}, + {"name": "isl69260", "bus": 95, "loc": 0x60}, + {"name": "ads7828", "bus": 13, "loc": 0x48}, + {"name": "ads7828", "bus": 14, "loc": 0x48}, + + #avs + {"name": "wb_mac_bsc_th6", "bus": 75, "loc": 0x44}, + {"name": "wb_rc32312", "bus": 103, "loc": 0x09}, + {"name": "wb_rc32312", "bus": 104, "loc": 0x09}, +] + +OPTOE = [ + {"name": "optoe1", "startbus": 265, "endbus": 265}, + {"name": "optoe3", "startbus": 201, "endbus": 264}, +] + + +INIT_PARAM = [] + +INIT_COMMAND_PRE = [] + +INIT_COMMAND = [ + # open X86 BMC Serial port + "dfd_debug sysfs_data_wr /dev/cpld1 0xA9 0x01", + # QSFP EN + "dfd_debug sysfs_data_wr /dev/cpld7 0x40 0xbf", + "dfd_debug sysfs_data_wr /dev/cpld7 0x41 0xbf", + "dfd_debug sysfs_data_wr /dev/cpld7 0x42 0xbd", + "dfd_debug sysfs_data_wr /dev/cpld7 0x43 0xbd", + "dfd_debug sysfs_data_wr /dev/cpld7 0x44 0xbb", + "dfd_debug sysfs_data_wr /dev/cpld7 0x45 0xbb", + # KR power_on + "dfd_debug sysfs_data_wr /dev/cpld7 0x50 0xaf", + "dfd_debug sysfs_data_wr /dev/cpld7 0x51 0xaf", + # KR tx-disable enable + "dfd_debug sysfs_data_wr /dev/cpld7 0x52 0xac", + "dfd_debug sysfs_data_wr /dev/cpld7 0x53 0xac", + + "echo 580000 > /sys/bus/i2c/devices/85-0060/hwmon/hwmon*/avs0_vout_min", + "echo 920000 > /sys/bus/i2c/devices/85-0060/hwmon/hwmon*/avs0_vout_max", + "echo 600000 > /sys/bus/i2c/devices/87-0060/hwmon/hwmon*/avs0_vout_min", + "echo 880000 > /sys/bus/i2c/devices/87-0060/hwmon/hwmon*/avs0_vout_max", + "echo 600000 > /sys/bus/i2c/devices/87-0060/hwmon/hwmon*/avs1_vout_min", + "echo 880000 > /sys/bus/i2c/devices/87-0060/hwmon/hwmon*/avs1_vout_max", + "echo 600000 > /sys/bus/i2c/devices/89-0060/hwmon/hwmon*/avs0_vout_min", + "echo 880000 > /sys/bus/i2c/devices/89-0060/hwmon/hwmon*/avs0_vout_max", + "echo 600000 > /sys/bus/i2c/devices/89-0060/hwmon/hwmon*/avs1_vout_min", + "echo 880000 > /sys/bus/i2c/devices/89-0060/hwmon/hwmon*/avs1_vout_max", + "echo 600000 > /sys/bus/i2c/devices/90-0060/hwmon/hwmon*/avs0_vout_min", + "echo 880000 > /sys/bus/i2c/devices/90-0060/hwmon/hwmon*/avs0_vout_max", + "echo 600000 > /sys/bus/i2c/devices/90-0060/hwmon/hwmon*/avs1_vout_min", + "echo 880000 > /sys/bus/i2c/devices/90-0060/hwmon/hwmon*/avs1_vout_max", + "echo 600000 > /sys/bus/i2c/devices/95-0060/hwmon/hwmon*/avs0_vout_min", + "echo 880000 > /sys/bus/i2c/devices/95-0060/hwmon/hwmon*/avs0_vout_max", + "echo 600000 > /sys/bus/i2c/devices/95-0060/hwmon/hwmon*/avs1_vout_min", + "echo 880000 > /sys/bus/i2c/devices/95-0060/hwmon/hwmon*/avs1_vout_max", +] + +UPGRADE_SUMMARY = { + "devtype": 0x414c, + + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "BASE_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain2": { + "name": "MAC_CPLDA", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain3": { + "name": "MAC_CPLDB", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain4": { + "name": "IO_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain5": { + "name": "FAN_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + "chain6": { + "name": "CPU_CPLD", + "is_support_warm_upg": 0, + "init_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + ], + }, + }, + + "SPI-LOGIC-DEV": { + "chain1": { + "name": "MAC_FPGA", + "is_support_warm_upg": 0, + }, + "chain3": { + "name": "IO_FPGA", + "is_support_warm_upg": 0, + } + }, + + "SYSFS": { + "chain2": { + "name": "BCM53134", + "is_support_warm_upg": 0, + "init_cmd": [ + {"cmd": "modprobe wb_spi_gpio", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_gpio_device sck=7 mosi=5 miso=6 cs=8 bus=0 gpio_chip_name=AMDI0030:00", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_93xx46", "gettype": "cmd", "delay": 0.1}, + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa5}, + ], + "finish_cmd": [ + {"gettype": "devfile", "path": "/dev/cpld0", "offset": 0x9d, "value": 0xa4}, + {"cmd": "rmmod wb_spi_93xx46", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio_device", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio", "gettype": "cmd", "delay": 0.1}, + ], + }, + }, + + "TEST": { + "fpga": [ + {"chain": 1, "file": "/etc/.upgrade_test/fpga_test_0_1_header.bin", "display_name": "MAC_FPGA"}, + {"chain": 3, "file": "/etc/.upgrade_test/fpga_test_0_3_header.bin", "display_name": "IO_FPGA"}, + ], + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/cpld_test_0_1_header.vme", "display_name": "BASE_CPLD"}, + {"chain": 2, "file": "/etc/.upgrade_test/cpld_test_0_2_header.vme", "display_name": "MAC_CPLDA"}, + {"chain": 3, "file": "/etc/.upgrade_test/cpld_test_0_3_header.vme", "display_name": "MAC_CPLDB"}, + {"chain": 4, "file": "/etc/.upgrade_test/cpld_test_0_4_header.vme", "display_name": "IO_CPLD"}, + {"chain": 5, "file": "/etc/.upgrade_test/cpld_test_0_5_header.vme", "display_name": "FAN_CPLD"}, + {"chain": 6, "file": "/etc/.upgrade_test/cpld_test_0_6_header.vme", "display_name": "CPU_CPLD"}, + ], + }, + }, +} + +PLATFORM_E2_CONF = { + "fan": [ + {"name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/59-0050/eeprom"}, + {"name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/60-0050/eeprom"}, + {"name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/61-0050/eeprom"}, + {"name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/62-0050/eeprom"}, + {"name": "fan5", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/63-0050/eeprom"}, + {"name": "fan6", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/64-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, + ], + "io": [ + {"name": "IO card", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/12-0054/eeprom"}, + ], + "fcb": [ + {"name": "FAN board", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/427-0057/eeprom"}, + ], + "base": [ + {"name": "BASE board", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/67-0057/eeprom"}, + ], + "mac": [ + {"name": "MAC board", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/105-0057/eeprom"}, + ], +} + +AIR_FLOW_CONF = { +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_port_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_port_config.py new file mode 100644 index 0000000000..b47d25e8d2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/config/x86_64_micas_m2_w6951_64hc_cp_r0_port_config.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 66, + "port_bus_map": { + 3: 201, + 4: 202, + 7: 203, + 8: 204, + 11: 205, + 12: 206, + 15: 207, + 16: 208, + 19: 209, + 20: 210, + 23: 211, + 24: 212, + 27: 213, + 28: 214, + 31: 215, + 32: 216, + 35: 217, + 36: 218, + 39: 219, + 40: 220, + 43: 221, + 44: 222, + 47: 223, + 48: 224, + 51: 225, + 52: 226, + 55: 227, + 56: 228, + 59: 229, + 60: 230, + 63: 231, + 64: 232, + 1: 233, + 2: 234, + 5: 235, + 6: 236, + 9: 237, + 10: 238, + 13: 239, + 14: 240, + 17: 241, + 18: 242, + 21: 243, + 22: 244, + 25: 245, + 26: 246, + 29: 247, + 30: 248, + 33: 249, + 34: 250, + 37: 251, + 38: 252, + 41: 253, + 42: 254, + 45: 255, + 46: 256, + 49: 257, + 50: 258, + 53: 259, + 54: 260, + 57: 261, + 58: 262, + 61: 263, + 62: 264, + 65: 265, + 66: 265, + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_device.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_device.py new file mode 100644 index 0000000000..bfb3940447 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_device.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + + +class threshold: + PSU_TEMP_MIN = -20 * 1000 + PSU_TEMP_MAX = 65 * 1000 + + PSU_FAN_SPEED_MIN = 3500 + PSU_FAN_SPEED_MAX = 23500 + PSU_A_FAN_SPEED_MAX = 39000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 13 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 90 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 264 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 180 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 320 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 0* 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 3000 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 0 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 3100* 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 0 * 1000 + PSU_OUTPUT_CURRENT_MAX = 246 * 1000 + + PSU_INPUT_CURRENT_MIN = 0 * 1000 + PSU_INPUT_CURRENT_MAX = 20 * 1000 + + FRONT_FAN_SPEED_MAX = 32000 + REAR_FAN_SPEED_MAX = 30200 + FAN_SPEED_MIN = 6040 + + + +devices = { + "sensor_print_src": "s3ip", + + "dcdc_data_source": [ + { + "path": "/sys/s3ip/vol_sensor", + "type": "vol", + "Unit": Unit.Voltage, + "read_times": 3, + "format": "float(float(%s)/1000)", + }, + { + "path": "/sys/s3ip/curr_sensor", + "type": "curr", + "Unit": Unit.Current, + "read_times": 3, + "format": "float(float(%s)/1000)", + }, + ], + "temp_data_source": [ + { + "path": "/sys/s3ip/temp_sensor", + "type": "temp", + "Unit": Unit.Temperature, + }, + ], + + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/1-0056/eeprom", "way": "sysfs"}, + "airflow": "N/A" + }, + ], + "psus": [ + { + # "psu_sn": {"loc": "/sys/s3ip/psu/psu1/serial_number", "way": "sysfs"}, + # "psu_hw": {"loc": "/sys/s3ip/psu/psu1/hardware_version", "way": "sysfs"}, + # "psu_pn": {"loc": "/sys/s3ip/psu/psu1/part_number", "way": "sysfs"}, + # "psu_vendor": {"loc": "/sys/s3ip/psu/psu1/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 53, "addr": 0x60, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "TempStatus": {"bus": 53, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu1/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 53, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu1/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 53, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 53, "addr": 0x60, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu1/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu1/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu1/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu1/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 53, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu1/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu1/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu1/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + }, + { + # "psu_sn": {"loc": "/sys/s3ip/psu/psu2/serial_number", "way": "sysfs"}, + # "psu_hw": {"loc": "/sys/s3ip/psu/psu2/hardware_version", "way": "sysfs"}, + # "psu_pn": {"loc": "/sys/s3ip/psu/psu2/part_number", "way": "sysfs"}, + # "psu_vendor": {"loc": "/sys/s3ip/psu/psu2/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 54, "addr": 0x60, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "TempStatus": {"bus": 54, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu2/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 54, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu2/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 54, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 54, "addr": 0x60, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu2/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu2/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu2/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu2/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 54, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu2/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu2/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu2/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + }, + { + # "psu_sn": {"loc": "/sys/s3ip/psu/psu3/serial_number", "way": "sysfs"}, + # "psu_hw": {"loc": "/sys/s3ip/psu/psu3/hardware_version", "way": "sysfs"}, + # "psu_pn": {"loc": "/sys/s3ip/psu/psu3/part_number", "way": "sysfs"}, + # "psu_vendor": {"loc": "/sys/s3ip/psu/psu3/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 55, "addr": 0x60, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU3", + "TempStatus": {"bus": 55, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu3/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 55, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu3/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "FanStatus": {"bus": 55, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "InputsStatus": {"bus": 55, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 55, "addr": 0x60, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu3/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu3/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu3/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu3/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 55, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu3/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu3/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu3/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + }, + { + # "psu_sn": {"loc": "/sys/s3ip/psu/psu4/serial_number", "way": "sysfs"}, + # "psu_hw": {"loc": "/sys/s3ip/psu/psu4/hardware_version", "way": "sysfs"}, + # "psu_pn": {"loc": "/sys/s3ip/psu/psu4/part_number", "way": "sysfs"}, + # "psu_vendor": {"loc": "/sys/s3ip/psu/psu4/vendor", "way": "sysfs"}, + "pmbusloc": {"bus": 56, "addr": 0x60, "way": "i2c"}, + "present": {"loc": "/sys/s3ip/psu/psu4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU4", + "TempStatus": {"bus": 56, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu4/temp1/value", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 56, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/s3ip/psu/psu4/fan_speed", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "FanStatus": {"bus": 56, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "InputsStatus": {"bus": 56, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 56, "addr": 0x60, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'DC': { + "value": {"loc": "/sys/s3ip/psu/psu4/in_vol", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/s3ip/psu/psu4/in_vol", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu4/in_curr", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu4/in_power", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 56, "addr": 0x60, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/s3ip/psu/psu4/out_vol", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/s3ip/psu/psu4/out_curr", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/s3ip/psu/psu4/out_power", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + } + } + ], + "temps": [ + { + "name": "BOARD_TEMP", + "temp_id": "TEMP1", + "Temperature": { + "value":{"loc": "/sys/s3ip/temp_sensor/temp5/value", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 95000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "Temperature": { + "value": {"loc": "/sys/s3ip/temp_sensor/temp1/value", "way": "sysfs"}, + "Min": -15000, + "Low": 10000, + "High": 95000, + "Max": 99000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "Temperature": { + "value": [ + {"loc": "/sys/s3ip/temp_sensor/temp4/value", "way": "sysfs"}, + ], + "Min": -30000, + "Low": 0, + "High": 50000, + "Max": 55000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "Temperature": { + "value": [ + {"loc": "/sys/s3ip/temp_sensor/temp2/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp3/value", "way": "sysfs"}, + ], + "Min": -30000, + "Low": 0, + "High": 70000, + "Max": 75000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP5", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/s3ip/temp_sensor/temp10/value", "way": "sysfs"}, + "Min": -30000, + "Low": 10000, + "High": 100000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu1/temp1/value", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu2/temp1/value", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU3_TEMP", + "temp_id": "TEMP8", + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu3/temp1/value", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU4_TEMP", + "temp_id": "TEMP9", + "Temperature": { + "value": {"loc": "/sys/s3ip/psu/psu4/temp1/value", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "MOS_TEMP", + "temp_id": "TEMP10", + "Temperature": { + "value": [ + {"loc": "/sys/s3ip/temp_sensor/temp11/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp12/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp13/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp14/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp15/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp16/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp17/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp18/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp19/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp20/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp21/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp22/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp23/value", "way": "sysfs"}, + {"loc": "/sys/s3ip/temp_sensor/temp24/value", "way": "sysfs"}, + ], + "Min": -30000, + "Low": 10000, + "High": 100000, + "Max":125000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -15000, + "Low": 0, + "High": 80000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"loc": "/dev/cpld1", "offset": 0xaa, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0x07 + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"loc": "/dev/cpld1", "offset": 0xac, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0x07 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"loc": "/dev/cpld1", "offset": 0xad, "len": 1, "way": "devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0, "mask": 0x07 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-59/59-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/dev/cpld10", "offset":0xd0, "len": 1, "way":"devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 + }, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb0, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb0, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan1/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan1/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan1/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-60/60-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/dev/cpld10", "offset":0xd1, "len": 1, "way":"devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 + }, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb1, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb1, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan2/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan2/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan2/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-61/61-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/dev/cpld10", "offset":0xd2, "len": 1, "way":"devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 + }, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb2, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb2, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan3/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan3/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan3/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN4", + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-62/62-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/dev/cpld10", "offset":0xd3, "len": 1, "way":"devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 + }, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb3, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb3, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN5", + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-63/63-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/dev/cpld10", "offset":0xd4, "len": 1, "way":"devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 + }, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb4, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb4, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN6", + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-64/64-0050/eeprom', 'offset': 0, 'len': 256, 'way': 'devfile'}, + "present": {"loc": "/sys/s3ip/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"loc": "/dev/cpld10", "offset":0xd5, "len": 1, "way":"devfile"}, + "led_attrs": { + "green": 0x04, "red": 0x02, "amber": 0x06, "default": 0x04, + "flash": 0xff, "light": 0xff, "off": 0xff, "mask": 0x07 + }, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb5, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"loc": "/dev/cpld10", "offset":0xb5, "len": 1, "way":"devfile"}, + "Running": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/s3ip/fan/fan4/motor2/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/s3ip/fan/fan4/motor2/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + "warm": 1, + }, + { + "name": "BASE_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDA", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld6", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDB", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld7", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "IO_CPLD", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld8", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "FAN_CPLD", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/cpld10", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_FPGA", + "cpld_id": "CPLD7", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "IO_FPGA", + "cpld_id": "CPLD8", + "VersionFile": {"loc": "/dev/fpga1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "BIOS", + "cpld_id": "CPLD9", + "VersionFile": {"cmd": "dmidecode -s bios-version", "way": "cmd"}, + "desc": "Performs initialization of hardware components during booting", + "slot": 0, + "type": "str", + "warm": 0, + }, + ], + "cpu": [ + { + "name": "cpu", + "CpuResetCntReg": {"loc": "/dev/cpld1", "offset": 0x2e, "len": 1, "way": "devfile_ascii"}, + "reboot_cause_path": "/etc/sonic/.reboot/.previous-reboot-cause.txt" + } + ], + "sfps": { + "ver": '2.0', + "port_index_start": 0, + "port_num": 66, + "logical_to_physical_sfp_map": { + 66: 65, + }, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_path": "/sys/s3ip/transceiver/eth%d/present", + "presence_val_is_present": 1, + "eeprom_path": "/sys/s3ip/transceiver/eth%d/eeprom", + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(201, 265)) + [265, 265] , + "lpmode_path": "/sys/s3ip/transceiver/eth%d/low_power_mode", + "reset_path": "/sys/s3ip/transceiver/eth%d/reset", + "reset_val_is_reset": 0xDA, + "tx_dis_path": "/sys/s3ip/transceiver/eth%d/tx_disable", + "rx_los_path": "/sys/s3ip/transceiver/eth%d/rx_los", + "tx_fault_path": "/sys/s3ip/transceiver/eth%d/tx_fault", + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_monitor.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_monitor.py new file mode 100644 index 0000000000..26a9663551 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/hal-config/x86_64_micas_m2_w6951_64hc_cp_r0_monitor.py @@ -0,0 +1,133 @@ +# coding:utf-8 + +class fan_pwn: + FAN_PWN_MIN = 0x66 + FAN_PWN_MAX = 0xff + FAN_PWN_ERROR = 0x99 + FAN_PWN_WARNING = 0xcc + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 0, + "pwm_min": fan_pwn.FAN_PWN_MIN, + "pwm_max": fan_pwn.FAN_PWN_MAX, + "K": 11, + "tin_min": 38, + }, + "curve": { + "name": "curve", + "flag": 0, + "pwm_min": fan_pwn.FAN_PWN_MIN, + "pwm_max": fan_pwn.FAN_PWN_MAX, + "a": 0.22, + "b": -3.1, + "c": 43, + "tin_min": 27, + }, + }, + + "pid": { + "OUTLET_TEMP": { + "name": "OUTLET_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": fan_pwn.FAN_PWN_MIN, + "pwm_max": fan_pwn.FAN_PWN_MAX, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "MOS_TEMP": { + "name": "MOS_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": fan_pwn.FAN_PWN_MIN, + "pwm_max": fan_pwn.FAN_PWN_MAX, + "Kp": 1, + "Ki": 0.4, + "Kd": 0.3, + "target": 95, + "value": [None, None, None], + }, + "BOARD_TEMP" : { + "name": "BOARD_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": fan_pwn.FAN_PWN_MIN, + "pwm_max": fan_pwn.FAN_PWN_MAX, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105, "invalid": -100000, "error": -99999}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 75}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 95, "critical": 99}, + "MOS_TEMP": {"name": "MOS_TEMP", "warning": 110, "critical": 125}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 70, "critical": 75}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 65, "critical": 70, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "max_pwm": fan_pwn.FAN_PWN_MAX, + "min_pwm": fan_pwn.FAN_PWN_MIN, + "abnormal_pwm": fan_pwn.FAN_PWN_MAX, + "warning_pwm": fan_pwn.FAN_PWN_WARNING, + "temp_invalid_pid_pwm": fan_pwn.FAN_PWN_MIN, + "temp_error_pid_pwm": fan_pwn.FAN_PWN_MIN, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "SWITCH_TEMP"}, + {"temp_name": "CPU_TEMP"}, + {"temp_name": "MOS_TEMP"}, + {"temp_name": "OUTLET_TEMP"}, + {"temp_name": "BOARD_TEMP"}, + ], + "temp_warning_num": 3, # temp over warning 3 times continuously + "temp_critical_num": 3, # temp over critical 3 times continuously + "temp_warning_countdown": 60, # 5 min warning speed after not warning + "temp_critical_countdown": 60, # 5 min full speed after not critical + "rotor_error_count": 6, # fan rotor error 6 times continuously + "check_inlet_mac_diff": 0, + "inlet_mac_diff": 999, + "check_crit_reboot_flag": 1, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_fan_control": 0, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + "deal_all_fan_error_method_flag": 0, + }, + + "ledcontrol_para": { + "interval":5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "FRONT_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "FRONT_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "FRONT_FAN_LED"}, + ], + }, + + "otp_reboot_judge_file": { + "otp_switch_reboot_judge_file": "/etc/.otp_switch_reboot_flag", + "otp_other_reboot_judge_file": "/etc/.otp_other_reboot_flag", + }, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/Makefile new file mode 100644 index 0000000000..db5e130fc5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/Makefile @@ -0,0 +1,25 @@ +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +FIRMWARE_UPGRADE_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/app/firmware_upgrade/firmware_driver/include) +KERNEL_MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) +COMMON_MODULE_SYMVERS = $(KERNEL_MODULES_DIR)/Module.symvers +BSP_PUBLIC_PATH = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/public/include) + +ifneq ($(wildcard $(COMMON_MODULE_SYMVERS)),) +KBUILD_EXTRA_SYMBOLS += $(COMMON_MODULE_SYMVERS) +endif + +EXTRA_CFLAGS+= -I$(MODULES_DIR) +EXTRA_CFLAGS+= -I$(FIRMWARE_UPGRADE_PATH) +EXTRA_CFLAGS+= -I$(BSP_PUBLIC_PATH) + +obj-m += wb_pcie_dev_device.o +obj-m += wb_spi_ocores_device.o +obj-m += wb_spi_dev_device.o +obj-m += wb_fpga_i2c_bus_device.o +obj-m += wb_i2c_mux_pca954x_device.o +obj-m += wb_fpga_pca954x_device.o +obj-m += wb_i2c_dev_device.o +obj-m += wb_wdt_device.o +obj-m += wb_indirect_dev_device.o +#obj-m += wb_firmware_upgrade_device.o diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_firmware_upgrade_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_firmware_upgrade_device.c new file mode 100644 index 0000000000..c65669b92c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_firmware_upgrade_device.c @@ -0,0 +1,457 @@ +/* + * wb_firmware_upgrade.c + * + * ko for firmware device + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_AMD_NUM (256) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) +#define GPIO_OFFSET (GPIO_DYNAMIC_BASE) /* Formula of gpio base number in Kernel */ +#else +#define GPIO_OFFSET (ARCH_NR_GPIOS - GPIO_AMD_NUM) /* Formula of gpio base number in Kernel */ +#endif + +static int g_wb_firmware_upgrade_debug = 0; +static int g_wb_firmware_upgrade_error = 0; + +module_param(g_wb_firmware_upgrade_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_firmware_upgrade_error, int, S_IRUGO | S_IWUSR); + +#define WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_firmware_upgrade_debug) { \ + printk(KERN_INFO "[WB_FIRMWARE_UPGRADE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FIRMWARE_UPGRADE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_firmware_upgrade_error) { \ + printk(KERN_ERR "[WB_FIRMWARE_UPGRADE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* base cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data0 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 1, + .chip_index = 1, + + .chain = 1, + .chip_index = 1, + .en_gpio[0] = 91 + GPIO_OFFSET, + .en_level[0] = 1, + + .en_gpio_num = 1, + .en_logic_num = 0, +}; + +/* mac cpld a */ +static firmware_upgrade_device_t firmware_upgrade_device_data1 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 2, + .chip_index = 1, + + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + .en_gpio_num = 2, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0xe1, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x01, + .en_logic_dis_val[0] = 0x00, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0xe2, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x02, + .en_logic_dis_val[1] = 0x00, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0xe3, + .en_logic_mask[2] = 0x00, + .en_logic_en_val[2] = 0x1c, + .en_logic_dis_val[2] = 0x1d, + .en_logic_width[2] = 0x1, + + .en_logic_num = 3, +}; + +/* mac cpld b */ +static firmware_upgrade_device_t firmware_upgrade_device_data2 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + + .chain = 3, + .chip_index = 1, + + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + .en_gpio_num = 2, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0xe1, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x01, + .en_logic_dis_val[0] = 0x00, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0xe2, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x02, + .en_logic_dis_val[1] = 0x00, + .en_logic_width[1] = 0x1, + + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0xe4, + .en_logic_mask[2] = 0x00, + .en_logic_en_val[2] = 0x1a, + .en_logic_dis_val[2] = 0x1b, + .en_logic_width[2] = 0x1, + + .en_logic_num = 3, +}; + +/* io cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data3 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + + .chain = 4, + .chip_index = 1, + + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + .en_gpio_num = 2, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0xe1, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x01, + .en_logic_dis_val[0] = 0x00, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0xe2, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x03, + .en_logic_dis_val[1] = 0x00, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0xe6, + .en_logic_mask[2] = 0x00, + .en_logic_en_val[2] = 0x18, + .en_logic_dis_val[2] = 0x19, + .en_logic_width[2] = 0x1, + + .en_logic_num = 3, +}; + +/* fan cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data4 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + + .chain = 5, + .chip_index = 1, + + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + .en_gpio_num = 2, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0xe1, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x01, + .en_logic_dis_val[0] = 0x00, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0xe2, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x04, + .en_logic_dis_val[1] = 0x00, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0xe8, + .en_logic_mask[2] = 0x00, + .en_logic_en_val[2] = 0x16, + .en_logic_dis_val[2] = 0x17, + .en_logic_width[2] = 0x1, + + .en_logic_num = 3, +}; + + +/* cpu cpld */ +static firmware_upgrade_device_t firmware_upgrade_device_data5 = { + .type = "JTAG", + .upg_type.jtag = { + .tdi = 5 + GPIO_OFFSET, + .tck = 7 + GPIO_OFFSET, + .tms = 8 + GPIO_OFFSET, + .tdo = 6 + GPIO_OFFSET, + }, + .chain = 6, + .chip_index = 1, + + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + .en_gpio_num = 2, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0xe1, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x01, + .en_logic_dis_val[0] = 0x00, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0xe2, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x01, + .en_logic_dis_val[1] = 0x00, + .en_logic_width[1] = 0x1, + + .en_logic_num = 2, +}; + +/* mac fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data6 = { + .type = "SPI_LOGIC", + .chain = 1, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga0", + .ctrl_base = 0xa00, + .flash_base = 0x2f0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_gpio_num = 0, + .en_logic_num = 0, +}; + +/* io fpga */ +static firmware_upgrade_device_t firmware_upgrade_device_data7 = { + .type = "SPI_LOGIC", + .chain = 3, + .chip_index = 1, + .upg_type.sysfs = { + .dev_name = "/dev/fpga1", + .ctrl_base = 0xa00, + .flash_base = 0x2f0000, + .test_base = 0x7F0000, + .test_size = 0x10000, + }, + .en_logic_num = 0, + .en_logic_num = 0, +}; + +/* bcm53134 */ +static firmware_upgrade_device_t firmware_upgrade_device_data8 = { + .type = "SYSFS", + .chain = 2, + .chip_index = 1, + .upg_type.sysfs = { + .sysfs_name = "/sys/bus/spi/devices/spi0.0/eeprom", + }, + .en_gpio[0] = 85 + GPIO_OFFSET, + .en_level[0] = 1, + .en_gpio[1] = 84 + GPIO_OFFSET, + .en_level[1] = 1, + + .en_logic_dev[0] = "/dev/cpld1", + .en_logic_addr[0] = 0xe1, + .en_logic_mask[0] = 0xfc, + .en_logic_en_val[0] = 0x01, + .en_logic_dis_val[0] = 0x00, + .en_logic_width[0] = 0x1, + + .en_logic_dev[1] = "/dev/cpld1", + .en_logic_addr[1] = 0xe2, + .en_logic_mask[1] = 0xf8, + .en_logic_en_val[1] = 0x05, + .en_logic_dis_val[1] = 0x00, + .en_logic_width[1] = 0x1, + + .en_logic_dev[2] = "/dev/cpld1", + .en_logic_addr[2] = 0xe9, + .en_logic_mask[2] = 0x00, + .en_logic_en_val[2] = 0x16, + .en_logic_dis_val[2] = 0x17, + .en_logic_width[2] = 0x1, + + .en_gpio_num = 2, + .en_logic_num = 3, +}; + +static void firmware_device_release(struct device *dev) +{ + return; +} + +static struct platform_device firmware_upgrade_device[] = { + { + .name = "firmware_cpld_ispvme", + .id = 1, + .dev = { + .platform_data = &firmware_upgrade_device_data0, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 2, + .dev = { + .platform_data = &firmware_upgrade_device_data1, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 3, + .dev = { + .platform_data = &firmware_upgrade_device_data2, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 4, + .dev = { + .platform_data = &firmware_upgrade_device_data3, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 5, + .dev = { + .platform_data = &firmware_upgrade_device_data4, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_cpld_ispvme", + .id = 6, + .dev = { + .platform_data = &firmware_upgrade_device_data5, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 7, + .dev = { + .platform_data = &firmware_upgrade_device_data6, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 8, + .dev = { + .platform_data = &firmware_upgrade_device_data7, + .release = firmware_device_release, + }, + }, + { + .name = "firmware_sysfs", + .id = 9, + .dev = { + .platform_data = &firmware_upgrade_device_data8, + .release = firmware_device_release, + }, + }, + }; + + static int __init firmware_upgrade_device_init(void) + { + int i; + int ret = 0; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(firmware_upgrade_device); i++) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + ret = platform_device_register(&firmware_upgrade_device[i]); + if (ret < 0) { + firmware_upgrade_device_data->device_flag = -1; + printk(KERN_ERR "firmware_upgrade_device id%d register failed!\n", i + 1); + } else { + firmware_upgrade_device_data->device_flag = 0; + } + } + return 0; + } + + static void __exit firmware_upgrade_device_exit(void) + { + int i; + firmware_upgrade_device_t *firmware_upgrade_device_data; + + WB_FIRMWARE_UPGRADE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(firmware_upgrade_device) - 1; i >= 0; i--) { + firmware_upgrade_device_data = firmware_upgrade_device[i].dev.platform_data; + if (firmware_upgrade_device_data->device_flag == 0) { + platform_device_unregister(&firmware_upgrade_device[i]); + } + } + } + + module_init(firmware_upgrade_device_init); + module_exit(firmware_upgrade_device_exit); + MODULE_DESCRIPTION("FIRMWARE UPGRADE Devices"); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_i2c_bus_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_i2c_bus_device.c new file mode 100644 index 0000000000..75c292ba20 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_i2c_bus_device.c @@ -0,0 +1,1219 @@ +/* + * An wb_fpga_i2c_bus_device driver for fpga i2c device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_wb_fpga_i2c_debug = 0; +static int g_wb_fpga_i2c_error = 0; + +module_param(g_wb_fpga_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_i2c_error, int, S_IRUGO | S_IWUSR); + +#define WB_FPGA_I2C_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_i2c_debug) { \ + printk(KERN_INFO "[WB_FPGA_I2C][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FPGA_I2C_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_fpga_i2c_error) { \ + printk(KERN_ERR "[WB_FPGA_I2C][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* CPLD-I2C-MASTER-1 */ +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data0 = { + .adap_nr = 401, + .i2c_timeout = 3000, + .i2c_scale = 0x00, + .i2c_filter = 0x04, + .i2c_stretch = 0x08, + .i2c_ext_9548_exits_flag = 0x0c, + .i2c_ext_9548_addr = 0x10, + .i2c_ext_9548_chan = 0x14, + .i2c_in_9548_chan = 0x18, + .i2c_slave = 0x1c, + .i2c_reg = 0x20, + .i2c_reg_len = 0x30, + .i2c_data_len = 0x34, + .i2c_ctrl = 0x38, + .i2c_status = 0x3c, + .i2c_err_vec = 0x48, + .i2c_data_buf = 0x100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/cpld2", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 6, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +/* CPLD-I2C-MASTER-4 */ +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data1 = { + .adap_nr = 402, + .i2c_timeout = 3000, + .i2c_scale = 0x00, + .i2c_filter = 0x04, + .i2c_stretch = 0x08, + .i2c_ext_9548_exits_flag = 0x0c, + .i2c_ext_9548_addr = 0x10, + .i2c_ext_9548_chan = 0x14, + .i2c_in_9548_chan = 0x18, + .i2c_slave = 0x1c, + .i2c_reg = 0x20, + .i2c_reg_len = 0x30, + .i2c_data_len = 0x34, + .i2c_ctrl = 0x38, + .i2c_status = 0x3c, + .i2c_err_vec = 0x48, + .i2c_data_buf = 0x100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/cpld5", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 6, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +/* CPLD-I2C-MASTER-3 */ +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data2 = { + .adap_nr = 403, + .i2c_timeout = 3000, + .i2c_scale = 0x00, + .i2c_filter = 0x04, + .i2c_stretch = 0x08, + .i2c_ext_9548_exits_flag = 0x0c, + .i2c_ext_9548_addr = 0x10, + .i2c_ext_9548_chan = 0x14, + .i2c_in_9548_chan = 0x18, + .i2c_slave = 0x1c, + .i2c_reg = 0x20, + .i2c_reg_len = 0x30, + .i2c_data_len = 0x34, + .i2c_ctrl = 0x38, + .i2c_status = 0x3c, + .i2c_err_vec = 0x48, + .i2c_data_buf = 0x100, + .i2c_data_buf_len = 256, + .dev_name = "/dev/cpld4", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 6, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data3 = { + .adap_nr = 404, + .i2c_timeout = 3000, + .i2c_scale = 0x2000, + .i2c_filter = 0x2004, + .i2c_stretch = 0x2008, + .i2c_ext_9548_exits_flag = 0x200c, + .i2c_ext_9548_addr = 0x2010, + .i2c_ext_9548_chan = 0x2014, + .i2c_in_9548_chan = 0x2018, + .i2c_slave = 0x201c, + .i2c_reg = 0x2020, + .i2c_reg_len = 0x2030, + .i2c_data_len = 0x2034, + .i2c_ctrl = 0x2038, + .i2c_status = 0x203c, + .i2c_err_vec = 0x2048, + .i2c_data_buf = 0x2100, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x207c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data4 = { + .adap_nr = 405, + .i2c_timeout = 3000, + .i2c_scale = 0x2200, + .i2c_filter = 0x2204, + .i2c_stretch = 0x2208, + .i2c_ext_9548_exits_flag = 0x220c, + .i2c_ext_9548_addr = 0x2210, + .i2c_ext_9548_chan = 0x2214, + .i2c_in_9548_chan = 0x2218, + .i2c_slave = 0x221c, + .i2c_reg = 0x2220, + .i2c_reg_len = 0x2230, + .i2c_data_len = 0x2234, + .i2c_ctrl = 0x2238, + .i2c_status = 0x223c, + .i2c_err_vec = 0x2248, + .i2c_data_buf = 0x2300, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x227c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data5 = { + .adap_nr = 406, + .i2c_timeout = 3000, + .i2c_scale = 0x2400, + .i2c_filter = 0x2404, + .i2c_stretch = 0x2408, + .i2c_ext_9548_exits_flag = 0x240c, + .i2c_ext_9548_addr = 0x2410, + .i2c_ext_9548_chan = 0x2414, + .i2c_in_9548_chan = 0x2418, + .i2c_slave = 0x241c, + .i2c_reg = 0x2420, + .i2c_reg_len = 0x2430, + .i2c_data_len = 0x2434, + .i2c_ctrl = 0x2438, + .i2c_status = 0x243c, + .i2c_err_vec = 0x2448, + .i2c_data_buf = 0x2500, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x247c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data6 = { + .adap_nr = 407, + .i2c_timeout = 3000, + .i2c_scale = 0x2600, + .i2c_filter = 0x2604, + .i2c_stretch = 0x2608, + .i2c_ext_9548_exits_flag = 0x260c, + .i2c_ext_9548_addr = 0x2610, + .i2c_ext_9548_chan = 0x2614, + .i2c_in_9548_chan = 0x2618, + .i2c_slave = 0x261c, + .i2c_reg = 0x2620, + .i2c_reg_len = 0x2630, + .i2c_data_len = 0x2634, + .i2c_ctrl = 0x2638, + .i2c_status = 0x263c, + .i2c_err_vec = 0x2648, + .i2c_data_buf = 0x2700, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x267c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data7 = { + .adap_nr = 408, + .i2c_timeout = 3000, + .i2c_scale = 0x2800, + .i2c_filter = 0x2804, + .i2c_stretch = 0x2808, + .i2c_ext_9548_exits_flag = 0x280c, + .i2c_ext_9548_addr = 0x2810, + .i2c_ext_9548_chan = 0x2814, + .i2c_in_9548_chan = 0x2818, + .i2c_slave = 0x281c, + .i2c_reg = 0x2820, + .i2c_reg_len = 0x2830, + .i2c_data_len = 0x2834, + .i2c_ctrl = 0x2838, + .i2c_status = 0x283c, + .i2c_err_vec = 0x2848, + .i2c_data_buf = 0x2900, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x287c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_i2c_bus_device_data8 = { + .adap_nr = 432, + .i2c_timeout = 3000, + .i2c_scale = 0x2a00, + .i2c_filter = 0x2a04, + .i2c_stretch = 0x2a08, + .i2c_ext_9548_exits_flag = 0x2a0c, + .i2c_ext_9548_addr = 0x2a10, + .i2c_ext_9548_chan = 0x2a14, + .i2c_in_9548_chan = 0x2a18, + .i2c_slave = 0x2a1c, + .i2c_reg = 0x2a20, + .i2c_reg_len = 0x2a30, + .i2c_data_len = 0x2a34, + .i2c_ctrl = 0x2a38, + .i2c_status = 0x2a3c, + .i2c_err_vec = 0x2a48, + .i2c_data_buf = 0x2b00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x2a7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_i2c_bus_device_data0 = { + .adap_nr = 409, + .i2c_timeout = 3000, + .i2c_scale = 0x2200, + .i2c_filter = 0x2204, + .i2c_stretch = 0x2208, + .i2c_ext_9548_exits_flag = 0x220c, + .i2c_ext_9548_addr = 0x2210, + .i2c_ext_9548_chan = 0x2214, + .i2c_in_9548_chan = 0x2218, + .i2c_slave = 0x221c, + .i2c_reg = 0x2220, + .i2c_reg_len = 0x2230, + .i2c_data_len = 0x2234, + .i2c_ctrl = 0x2238, + .i2c_status = 0x223c, + .i2c_err_vec = 0x2248, + .i2c_data_buf = 0x2300, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x227c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data0 = { + .adap_nr = 410, + .i2c_timeout = 3000, + .i2c_scale = 0x4000, + .i2c_filter = 0x4004, + .i2c_stretch = 0x4008, + .i2c_ext_9548_exits_flag = 0x400c, + .i2c_ext_9548_addr = 0x4010, + .i2c_ext_9548_chan = 0x4014, + .i2c_in_9548_chan = 0x4018, + .i2c_slave = 0x401c, + .i2c_reg = 0x4020, + .i2c_reg_len = 0x4030, + .i2c_data_len = 0x4034, + .i2c_ctrl = 0x4038, + .i2c_status = 0x403c, + .i2c_err_vec = 0x4048, + .i2c_data_buf = 0x4100, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x407c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data1 = { + .adap_nr = 411, + .i2c_timeout = 3000, + .i2c_scale = 0x4400, + .i2c_filter = 0x4404, + .i2c_stretch = 0x4408, + .i2c_ext_9548_exits_flag = 0x440c, + .i2c_ext_9548_addr = 0x4410, + .i2c_ext_9548_chan = 0x4414, + .i2c_in_9548_chan = 0x4418, + .i2c_slave = 0x441c, + .i2c_reg = 0x4420, + .i2c_reg_len = 0x4430, + .i2c_data_len = 0x4434, + .i2c_ctrl = 0x4438, + .i2c_status = 0x443c, + .i2c_err_vec = 0x4448, + .i2c_data_buf = 0x4500, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x447c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data2 = { + .adap_nr = 412, + .i2c_timeout = 3000, + .i2c_scale = 0x4800, + .i2c_filter = 0x4804, + .i2c_stretch = 0x4808, + .i2c_ext_9548_exits_flag = 0x480c, + .i2c_ext_9548_addr = 0x4810, + .i2c_ext_9548_chan = 0x4814, + .i2c_in_9548_chan = 0x4818, + .i2c_slave = 0x481c, + .i2c_reg = 0x4820, + .i2c_reg_len = 0x4830, + .i2c_data_len = 0x4834, + .i2c_ctrl = 0x4838, + .i2c_status = 0x483c, + .i2c_err_vec = 0x4848, + .i2c_data_buf = 0x4900, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x487c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data3 = { + .adap_nr = 413, + .i2c_timeout = 3000, + .i2c_scale = 0x4c00, + .i2c_filter = 0x4c04, + .i2c_stretch = 0x4c08, + .i2c_ext_9548_exits_flag = 0x4c0c, + .i2c_ext_9548_addr = 0x4c10, + .i2c_ext_9548_chan = 0x4c14, + .i2c_in_9548_chan = 0x4c18, + .i2c_slave = 0x4c1c, + .i2c_reg = 0x4c20, + .i2c_reg_len = 0x4c30, + .i2c_data_len = 0x4c34, + .i2c_ctrl = 0x4c38, + .i2c_status = 0x4c3c, + .i2c_err_vec = 0x4c48, + .i2c_data_buf = 0x4d00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data4 = { + .adap_nr = 414, + .i2c_timeout = 3000, + .i2c_scale = 0x5000, + .i2c_filter = 0x5004, + .i2c_stretch = 0x5008, + .i2c_ext_9548_exits_flag = 0x500c, + .i2c_ext_9548_addr = 0x5010, + .i2c_ext_9548_chan = 0x5014, + .i2c_in_9548_chan = 0x5018, + .i2c_slave = 0x501c, + .i2c_reg = 0x5020, + .i2c_reg_len = 0x5030, + .i2c_data_len = 0x5034, + .i2c_ctrl = 0x5038, + .i2c_status = 0x503c, + .i2c_err_vec = 0x5048, + .i2c_data_buf = 0x5100, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x507c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data5 = { + .adap_nr = 415, + .i2c_timeout = 3000, + .i2c_scale = 0x5400, + .i2c_filter = 0x5404, + .i2c_stretch = 0x5408, + .i2c_ext_9548_exits_flag = 0x540c, + .i2c_ext_9548_addr = 0x5410, + .i2c_ext_9548_chan = 0x5414, + .i2c_in_9548_chan = 0x5418, + .i2c_slave = 0x541c, + .i2c_reg = 0x5420, + .i2c_reg_len = 0x5430, + .i2c_data_len = 0x5434, + .i2c_ctrl = 0x5438, + .i2c_status = 0x543c, + .i2c_err_vec = 0x5448, + .i2c_data_buf = 0x5500, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x547c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data6 = { + .adap_nr = 416, + .i2c_timeout = 3000, + .i2c_scale = 0x5800, + .i2c_filter = 0x5804, + .i2c_stretch = 0x5808, + .i2c_ext_9548_exits_flag = 0x580c, + .i2c_ext_9548_addr = 0x5810, + .i2c_ext_9548_chan = 0x5814, + .i2c_in_9548_chan = 0x5818, + .i2c_slave = 0x581c, + .i2c_reg = 0x5820, + .i2c_reg_len = 0x5830, + .i2c_data_len = 0x5834, + .i2c_ctrl = 0x5838, + .i2c_status = 0x583c, + .i2c_err_vec = 0x5848, + .i2c_data_buf = 0x5900, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x587c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga0_dom_i2c_bus_device_data7 = { + .adap_nr = 417, + .i2c_timeout = 3000, + .i2c_scale = 0x5c00, + .i2c_filter = 0x5c04, + .i2c_stretch = 0x5c08, + .i2c_ext_9548_exits_flag = 0x5c0c, + .i2c_ext_9548_addr = 0x5c10, + .i2c_ext_9548_chan = 0x5c14, + .i2c_in_9548_chan = 0x5c18, + .i2c_slave = 0x5c1c, + .i2c_reg = 0x5c20, + .i2c_reg_len = 0x5c30, + .i2c_data_len = 0x5c34, + .i2c_ctrl = 0x5c38, + .i2c_status = 0x5c3c, + .i2c_err_vec = 0x5c48, + .i2c_data_buf = 0x5d00, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x5c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data0 = { + .adap_nr = 418, + .i2c_timeout = 3000, + .i2c_scale = 0x4000, + .i2c_filter = 0x4004, + .i2c_stretch = 0x4008, + .i2c_ext_9548_exits_flag = 0x400c, + .i2c_ext_9548_addr = 0x4010, + .i2c_ext_9548_chan = 0x4014, + .i2c_in_9548_chan = 0x4018, + .i2c_slave = 0x401c, + .i2c_reg = 0x4020, + .i2c_reg_len = 0x4030, + .i2c_data_len = 0x4034, + .i2c_ctrl = 0x4038, + .i2c_status = 0x403c, + .i2c_err_vec = 0x4048, + .i2c_data_buf = 0x4100, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x407c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data1 = { + .adap_nr = 419, + .i2c_timeout = 3000, + .i2c_scale = 0x4400, + .i2c_filter = 0x4404, + .i2c_stretch = 0x4408, + .i2c_ext_9548_exits_flag = 0x440c, + .i2c_ext_9548_addr = 0x4410, + .i2c_ext_9548_chan = 0x4414, + .i2c_in_9548_chan = 0x4418, + .i2c_slave = 0x441c, + .i2c_reg = 0x4420, + .i2c_reg_len = 0x4430, + .i2c_data_len = 0x4434, + .i2c_ctrl = 0x4438, + .i2c_status = 0x443c, + .i2c_err_vec = 0x4448, + .i2c_data_buf = 0x4500, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x447c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data2 = { + .adap_nr = 420, + .i2c_timeout = 3000, + .i2c_scale = 0x4800, + .i2c_filter = 0x4804, + .i2c_stretch = 0x4808, + .i2c_ext_9548_exits_flag = 0x480c, + .i2c_ext_9548_addr = 0x4810, + .i2c_ext_9548_chan = 0x4814, + .i2c_in_9548_chan = 0x4818, + .i2c_slave = 0x481c, + .i2c_reg = 0x4820, + .i2c_reg_len = 0x4830, + .i2c_data_len = 0x4834, + .i2c_ctrl = 0x4838, + .i2c_status = 0x483c, + .i2c_err_vec = 0x4848, + .i2c_data_buf = 0x4900, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x487c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data3 = { + .adap_nr = 421, + .i2c_timeout = 3000, + .i2c_scale = 0x4c00, + .i2c_filter = 0x4c04, + .i2c_stretch = 0x4c08, + .i2c_ext_9548_exits_flag = 0x4c0c, + .i2c_ext_9548_addr = 0x4c10, + .i2c_ext_9548_chan = 0x4c14, + .i2c_in_9548_chan = 0x4c18, + .i2c_slave = 0x4c1c, + .i2c_reg = 0x4c20, + .i2c_reg_len = 0x4c30, + .i2c_data_len = 0x4c34, + .i2c_ctrl = 0x4c38, + .i2c_status = 0x4c3c, + .i2c_err_vec = 0x4c48, + .i2c_data_buf = 0x4d00, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x4c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data4 = { + .adap_nr = 422, + .i2c_timeout = 3000, + .i2c_scale = 0x5000, + .i2c_filter = 0x5004, + .i2c_stretch = 0x5008, + .i2c_ext_9548_exits_flag = 0x500c, + .i2c_ext_9548_addr = 0x5010, + .i2c_ext_9548_chan = 0x5014, + .i2c_in_9548_chan = 0x5018, + .i2c_slave = 0x501c, + .i2c_reg = 0x5020, + .i2c_reg_len = 0x5030, + .i2c_data_len = 0x5034, + .i2c_ctrl = 0x5038, + .i2c_status = 0x503c, + .i2c_err_vec = 0x5048, + .i2c_data_buf = 0x5100, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x507c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data5 = { + .adap_nr = 423, + .i2c_timeout = 3000, + .i2c_scale = 0x5400, + .i2c_filter = 0x5404, + .i2c_stretch = 0x5408, + .i2c_ext_9548_exits_flag = 0x540c, + .i2c_ext_9548_addr = 0x5410, + .i2c_ext_9548_chan = 0x5414, + .i2c_in_9548_chan = 0x5418, + .i2c_slave = 0x541c, + .i2c_reg = 0x5420, + .i2c_reg_len = 0x5430, + .i2c_data_len = 0x5434, + .i2c_ctrl = 0x5438, + .i2c_status = 0x543c, + .i2c_err_vec = 0x5448, + .i2c_data_buf = 0x5500, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x547c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data6 = { + .adap_nr = 424, + .i2c_timeout = 3000, + .i2c_scale = 0x5800, + .i2c_filter = 0x5804, + .i2c_stretch = 0x5808, + .i2c_ext_9548_exits_flag = 0x580c, + .i2c_ext_9548_addr = 0x5810, + .i2c_ext_9548_chan = 0x5814, + .i2c_in_9548_chan = 0x5818, + .i2c_slave = 0x581c, + .i2c_reg = 0x5820, + .i2c_reg_len = 0x5830, + .i2c_data_len = 0x5834, + .i2c_ctrl = 0x5838, + .i2c_status = 0x583c, + .i2c_err_vec = 0x5848, + .i2c_data_buf = 0x5900, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x587c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_dom_i2c_bus_device_data7 = { + .adap_nr = 425, + .i2c_timeout = 3000, + .i2c_scale = 0x5c00, + .i2c_filter = 0x5c04, + .i2c_stretch = 0x5c08, + .i2c_ext_9548_exits_flag = 0x5c0c, + .i2c_ext_9548_addr = 0x5c10, + .i2c_ext_9548_chan = 0x5c14, + .i2c_in_9548_chan = 0x5c18, + .i2c_slave = 0x5c1c, + .i2c_reg = 0x5c20, + .i2c_reg_len = 0x5c30, + .i2c_data_len = 0x5c34, + .i2c_ctrl = 0x5c38, + .i2c_status = 0x5c3c, + .i2c_err_vec = 0x5c48, + .i2c_data_buf = 0x5d00, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x5c7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_i2c_bus_device_data1 = { + .adap_nr = 434, + .i2c_timeout = 3000, + .i2c_scale = 0x2000, + .i2c_filter = 0x2004, + .i2c_stretch = 0x2008, + .i2c_ext_9548_exits_flag = 0x200c, + .i2c_ext_9548_addr = 0x2010, + .i2c_ext_9548_chan = 0x2014, + .i2c_in_9548_chan = 0x2018, + .i2c_slave = 0x201c, + .i2c_reg = 0x2020, + .i2c_reg_len = 0x2030, + .i2c_data_len = 0x2034, + .i2c_ctrl = 0x2038, + .i2c_status = 0x203c, + .i2c_err_vec = 0x2048, + .i2c_data_buf = 0x2100, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x207c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static fpga_i2c_bus_device_t fpga1_i2c_bus_device_data2 = { + .adap_nr = 436, + .i2c_timeout = 3000, + .i2c_scale = 0x2400, + .i2c_filter = 0x2404, + .i2c_stretch = 0x2408, + .i2c_ext_9548_exits_flag = 0x240c, + .i2c_ext_9548_addr = 0x2410, + .i2c_ext_9548_chan = 0x2414, + .i2c_in_9548_chan = 0x2418, + .i2c_slave = 0x241c, + .i2c_reg = 0x2420, + .i2c_reg_len = 0x2430, + .i2c_data_len = 0x2434, + .i2c_ctrl = 0x2438, + .i2c_status = 0x243c, + .i2c_err_vec = 0x2448, + .i2c_data_buf = 0x2500, + .dev_name = "/dev/fpga1", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x247c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, /* delay time before reset(us) */ + .i2c_rst_delay = 1, /* reset time(us) */ + .i2c_rst_delay_a = 1, /* delay time after reset(us) */ +}; + +static void wb_fpga_i2c_bus_device_release(struct device *dev) +{ + return; +} + +static struct platform_device fpga_i2c_bus_device[] = { + { + .name = "wb-fpga-i2c", + .id = 1, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 2, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 3, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 4, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 5, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 6, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 7, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 8, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 10, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 11, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 12, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 13, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 14, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 15, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 16, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 17, + .dev = { + .platform_data = &fpga0_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 18, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 19, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 20, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 21, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 22, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 23, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 24, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 25, + .dev = { + .platform_data = &fpga1_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 26, + .dev = { + .platform_data = &fpga1_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 27, + .dev = { + .platform_data = &fpga0_i2c_bus_device_data8, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 28, + .dev = { + .platform_data = &fpga1_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 29, + .dev = { + .platform_data = &fpga1_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, +}; + +static int __init wb_fpga_i2c_bus_device_init(void) +{ + int i; + int ret = 0; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + WB_FPGA_I2C_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_i2c_bus_device); i++) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + ret = platform_device_register(&fpga_i2c_bus_device[i]); + if (ret < 0) { + fpga_i2c_bus_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-fpga-i2c.%d register failed!\n", i + 1); + } else { + fpga_i2c_bus_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_fpga_i2c_bus_device_exit(void) +{ + int i; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + WB_FPGA_I2C_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_i2c_bus_device) - 1; i >= 0; i--) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + if (fpga_i2c_bus_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&fpga_i2c_bus_device[i]); + } + } +} + +module_init(wb_fpga_i2c_bus_device_init); +module_exit(wb_fpga_i2c_bus_device_exit); +MODULE_DESCRIPTION("FPGA I2C Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_pca954x_device.c new file mode 100644 index 0000000000..6f9bdc16e8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_fpga_pca954x_device.c @@ -0,0 +1,524 @@ +/* + * An wb_fpga_pca954x_device driver for fpga pca954x device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_fpga_pca954x_device_debug = 0; +static int g_wb_fpga_pca954x_device_error = 0; + +module_param(g_wb_fpga_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_FPGA_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FPGA_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_fpga_pca954x_device_error) { \ + printk(KERN_ERR "[WB_FPGA_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* CPLD-I2C-MASTER-1 */ +static fpga_pca954x_device_t fpga_pca954x_device_data0 = { + .i2c_bus = 401, + .i2c_addr = 0x70, + .pca9548_base_nr = 426, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data1 = { + .i2c_bus = 426, + .i2c_addr = 0x76, + .pca9548_base_nr = 51, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +/* CPLD-I2C-MASTER-4 */ +static fpga_pca954x_device_t fpga_pca954x_device_data2 = { + .i2c_bus = 402, + .i2c_addr = 0x70, + .pca9548_base_nr = 427, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data3 = { + .i2c_bus = 427, + .i2c_addr = 0x77, + .pca9548_base_nr = 59, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +/* CPLD-I2C-MASTER-3 */ +static fpga_pca954x_device_t fpga_pca954x_device_data6 = { + .i2c_bus = 403, + .i2c_addr = 0x71, + .pca9548_base_nr = 428, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data7 = { + .i2c_bus = 428, + .i2c_addr = 0x77, + .pca9548_base_nr = 67, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +/* fpga-i2c-1 */ +static fpga_pca954x_device_t fpga_pca954x_device_data8 = { + .i2c_bus = 404, + .i2c_addr = 0x70, + .pca9548_base_nr = 429, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data9 = { + .i2c_bus = 429, + .i2c_addr = 0x76, + .pca9548_base_nr = 75, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data10 = { + .i2c_bus = 405, + .i2c_addr = 0x70, + .pca9548_base_nr = 430, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data11 = { + .i2c_bus = 430, + .i2c_addr = 0x76, + .pca9548_base_nr = 83, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data12 = { + .i2c_bus = 406, + .i2c_addr = 0x71, + .pca9548_base_nr = 431, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data13 = { + .i2c_bus = 431, + .i2c_addr = 0x76, + .pca9548_base_nr = 91, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data14 = { + .i2c_bus = 407, + .i2c_addr = 0x70, + .pca9548_base_nr = 99, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data15 = { + .i2c_bus = 408, + .i2c_addr = 0x70, + .pca9548_base_nr = 103, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data16 = { + .i2c_bus = 409, + .i2c_addr = 0x70, + .pca9548_base_nr = 107, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data17 = { + .i2c_bus = 410, + .i2c_addr = 0x70, + .pca9548_base_nr = 201, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data18 = { + .i2c_bus = 411, + .i2c_addr = 0x70, + .pca9548_base_nr = 205, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data19 = { + .i2c_bus = 412, + .i2c_addr = 0x70, + .pca9548_base_nr = 209, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data20 = { + .i2c_bus = 413, + .i2c_addr = 0x70, + .pca9548_base_nr = 213, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data21 = { + .i2c_bus = 414, + .i2c_addr = 0x70, + .pca9548_base_nr = 217, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data22 = { + .i2c_bus = 415, + .i2c_addr = 0x70, + .pca9548_base_nr = 221, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data23 = { + .i2c_bus = 416, + .i2c_addr = 0x70, + .pca9548_base_nr = 225, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data24 = { + .i2c_bus = 417, + .i2c_addr = 0x70, + .pca9548_base_nr = 229, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data25 = { + .i2c_bus = 418, + .i2c_addr = 0x70, + .pca9548_base_nr = 233, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data26 = { + .i2c_bus = 419, + .i2c_addr = 0x70, + .pca9548_base_nr = 237, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data27 = { + .i2c_bus = 420, + .i2c_addr = 0x70, + .pca9548_base_nr = 241, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data28 = { + .i2c_bus = 421, + .i2c_addr = 0x70, + .pca9548_base_nr = 245, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data29 = { + .i2c_bus = 422, + .i2c_addr = 0x70, + .pca9548_base_nr = 249, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data30 = { + .i2c_bus = 423, + .i2c_addr = 0x70, + .pca9548_base_nr = 253, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data31 = { + .i2c_bus = 424, + .i2c_addr = 0x70, + .pca9548_base_nr = 257, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data32 = { + .i2c_bus = 425, + .i2c_addr = 0x70, + .pca9548_base_nr = 261, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data33 = { + .i2c_bus = 434, + .i2c_addr = 0x71, + .pca9548_base_nr = 435, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data34 = { + .i2c_bus = 435, + .i2c_addr = 0x73, + .pca9548_base_nr = 111, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data35 = { + .i2c_bus = 436, + .i2c_addr = 0x71, + .pca9548_base_nr = 119, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data36 = { + .i2c_bus = 432, + .i2c_addr = 0x71, + .pca9548_base_nr = 265, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +struct i2c_board_info fpga_pca954x_device_info[] = { + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data0, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data1, + }, + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data2, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data3, + }, + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data6, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data7, + }, + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data8, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data9, + }, + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data10, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data11, + }, + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data12, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data13, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data14, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data15, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data16, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data17, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data18, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data19, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data20, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data21, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data22, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data23, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data24, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data25, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data26, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data27, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data28, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data29, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data30, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data31, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data32, + }, + { + .type = "wb_fpga_pca9541", + .platform_data = &fpga_pca954x_device_data33, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data34, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data35, + }, + { + .type = "wb_fpga_pca9544", + .platform_data = &fpga_pca954x_device_data36, + }, +}; + +static int __init wb_fpga_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_pca954x_device_info); i++) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + fpga_pca954x_device_info[i].addr = fpga_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(fpga_pca954x_device_data->i2c_bus); + if (adap == NULL) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", fpga_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); + if (!client) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", + fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); + } else { + fpga_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_fpga_pca954x_device_exit(void) +{ + int i; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_pca954x_device_info) - 1; i >= 0; i--) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + if (fpga_pca954x_device_data->client) { + i2c_unregister_device(fpga_pca954x_device_data->client); + fpga_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_fpga_pca954x_device_init); +module_exit(wb_fpga_pca954x_device_exit); +MODULE_DESCRIPTION("FPGA PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 0000000000..ee6b995943 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,197 @@ +/* + * An wb_io_dev_device driver for io device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* mac cplda */ +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 99, + .i2c_addr = 0x1d, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* mac cpldb */ +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 100, + .i2c_addr = 0x3d, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* io cpld */ +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 107, + .i2c_addr = 0x2d, + .i2c_name = "cpld8", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* fan cpld */ +static i2c_dev_device_t i2c_dev_device_data3 = { + .i2c_bus = 427, + .i2c_addr = 0x0d, + .i2c_name = "cpld10", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* CPU cpld */ +static i2c_dev_device_t i2c_dev_device_data4 = { + .i2c_bus = 0, + .i2c_addr = 0x0d, + .i2c_name = "cpld0", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +/* BASE cpld */ +static i2c_dev_device_t i2c_dev_device_data5 = { + .i2c_bus = 21, + .i2c_addr = 0x0d, + .i2c_name = "cpld1", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data3, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data4, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data5, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_mux_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_mux_pca954x_device.c new file mode 100644 index 0000000000..57896e72a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_i2c_mux_pca954x_device.c @@ -0,0 +1,149 @@ +/* + * An wb_i2c_mux_pca954x_device driver for pca954x i2c load device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_mux_pca954x_device_debug = 0; +static int g_wb_i2c_mux_pca954x_device_error = 0; + +module_param(g_wb_i2c_mux_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_mux_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_I2C_MUX_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_MUX_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_mux_pca954x_device_error) { \ + printk(KERN_ERR "[WB_I2C_MUX_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data0 = { + .i2c_bus = 1, + .i2c_addr = 0x70, + .probe_disable = 1, + .select_chan_check = 1, + .close_chan_force_reset = 1, + .pca9548_base_nr = 2, + .pca9548_reset_type = PCA9548_RESET_I2C, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .i2c_attr.i2c_bus = 1, + .i2c_attr.i2c_addr = 0x0d, + .i2c_attr.reg_offset = 0x74, + .i2c_attr.mask = 0xFF, + .i2c_attr.reset_on = 0x8A, + .i2c_attr.reset_off = 0x8B, + }, +}; + +static i2c_mux_pca954x_device_t i2c_mux_pca954x_device_data1 = { + .i2c_bus = 1, + .i2c_addr = 0x71, + .probe_disable = 1, + .select_chan_check = 1, + .close_chan_force_reset = 1, + .pca9548_base_nr = 10, + .pca9548_reset_type = PCA9548_RESET_I2C, + .rst_delay_b = 0, + .rst_delay = 1000, + .rst_delay_a = 1000, + .attr = { + .i2c_attr.i2c_bus = 107, + .i2c_attr.i2c_addr = 0x2d, + .i2c_attr.reg_offset = 0xd4, + .i2c_attr.mask = 0xFF, + .i2c_attr.reset_on = 0x2A, + .i2c_attr.reset_off = 0x2B, + }, +}; + +struct i2c_board_info i2c_mux_pca954x_device_info[] = { + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data0, + }, + { + .type = "wb_pca9548", + .platform_data = &i2c_mux_pca954x_device_data1, + }, +}; + +static int __init wb_i2c_mux_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_mux_pca954x_device_info); i++) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + i2c_mux_pca954x_device_info[i].addr = i2c_mux_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_mux_pca954x_device_data->i2c_bus); + if (adap == NULL) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_mux_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_mux_pca954x_device_info[i]); + if (!client) { + i2c_mux_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register pca954x device %d at bus %d!\n", + i2c_mux_pca954x_device_data->i2c_addr, i2c_mux_pca954x_device_data->i2c_bus); + } else { + i2c_mux_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_mux_pca954x_device_exit(void) +{ + int i; + i2c_mux_pca954x_device_t *i2c_mux_pca954x_device_data; + + WB_I2C_MUX_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_mux_pca954x_device_info) - 1; i >= 0; i--) { + i2c_mux_pca954x_device_data = i2c_mux_pca954x_device_info[i].platform_data; + if (i2c_mux_pca954x_device_data->client) { + i2c_unregister_device(i2c_mux_pca954x_device_data->client); + i2c_mux_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_mux_pca954x_device_init); +module_exit(wb_i2c_mux_pca954x_device_exit); +MODULE_DESCRIPTION("WB I2C MUX PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_indirect_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_indirect_dev_device.c new file mode 100644 index 0000000000..3af007789a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_indirect_dev_device.c @@ -0,0 +1,162 @@ +/* + * An wb_indirect_dev_device driver for indirect load device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_indirect_dev_device_debug = 0; +static int g_indirect_dev_device_error = 0; + +module_param(g_indirect_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_indirect_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define INDIRECT_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_indirect_dev_device_debug) { \ + printk(KERN_INFO "[INDIRECT_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define INDIRECT_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_indirect_dev_device_error) { \ + printk(KERN_ERR "[INDIRECT_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/* CPLD-I2C-MASTER-1 */ +static indirect_dev_device_t indirect_dev_device_data0 = { + .logic_func_mode = 5, /* SYMBOL_SPI_DEV_MODE */ + .dev_name = "cpld2", + .logic_dev_name = "/dev/cpld11", + .data_bus_width = 4, + .wr_data = 0x80, + .addr_low = 0x84, + .addr_high = 0x85, + .rd_data = 0x86, + .opt_ctl = 0x8a, + .indirect_len = 0x200, + .lock_mode = 2, /* 1:spin lock, 2:mutex */ +}; + +/* CPLD-I2C-MASTER-3 */ +static indirect_dev_device_t indirect_dev_device_data2 = { + .logic_func_mode = 5, /* SYMBOL_SPI_DEV_MODE */ + .dev_name = "cpld4", + .logic_dev_name = "/dev/cpld11", + .data_bus_width = 4, + .wr_data = 0x8b, + .addr_low = 0x8f, + .addr_high = 0x90, + .rd_data = 0x91, + .opt_ctl = 0x95, + .indirect_len = 0x200, + .lock_mode = 2, /* 1:spin lock, 2:mutex */ +}; + +/* CPLD-I2C-MASTER-4 */ +static indirect_dev_device_t indirect_dev_device_data3 = { + .logic_func_mode = 5, /* SYMBOL_SPI_DEV_MODE */ + .dev_name = "cpld5", + .logic_dev_name = "/dev/cpld11", + .data_bus_width = 4, + .wr_data = 0x96, + .addr_low = 0x9a, + .addr_high = 0x9b, + .rd_data = 0x9c, + .opt_ctl = 0xa0, + .indirect_len = 0x200, + .lock_mode = 2, /* 1:spin lock, 2:mutex */ +}; + +static void indirect_dev_device_bus_device_release(struct device *dev) +{ + return; +} + +static struct platform_device indirect_dev_device[] = { + { + .name = "wb-indirect-dev", + .id = 1, + .dev = { + .platform_data = &indirect_dev_device_data0, + .release = indirect_dev_device_bus_device_release, + }, + }, + { + .name = "wb-indirect-dev", + .id = 2, + .dev = { + .platform_data = &indirect_dev_device_data2, + .release = indirect_dev_device_bus_device_release, + }, + }, + { + .name = "wb-indirect-dev", + .id = 3, + .dev = { + .platform_data = &indirect_dev_device_data3, + .release = indirect_dev_device_bus_device_release, + }, + }, +}; + +static int __init indirect_dev_device_bus_device_init(void) +{ + int i; + int ret = 0; + indirect_dev_device_t *indirect_dev_device_data; + + INDIRECT_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(indirect_dev_device); i++) { + indirect_dev_device_data = indirect_dev_device[i].dev.platform_data; + ret = platform_device_register(&indirect_dev_device[i]); + if (ret < 0) { + indirect_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-indirect-dev.%d register failed!\n", i + 1); + } else { + indirect_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit indirect_dev_device_bus_device_exit(void) +{ + int i; + indirect_dev_device_t *indirect_dev_device_data; + + INDIRECT_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(indirect_dev_device) - 1; i >= 0; i--) { + indirect_dev_device_data = indirect_dev_device[i].dev.platform_data; + if (indirect_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&indirect_dev_device[i]); + } + } +} + +module_init(indirect_dev_device_bus_device_init); +module_exit(indirect_dev_device_bus_device_exit); +MODULE_DESCRIPTION("INDIRECT DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 0000000000..2c8c0a5e35 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,139 @@ +/* + * An wb_pcie_dev_device driver for pcie device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +/*mac fpga */ +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 7, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .search_mode = 1, + .bridge_bus = 0, + .bridge_slot = 0x03, + .bridge_fn = 1, +}; + + +static pci_dev_device_t pcie_dev_device_data1 = { + .pci_dev_name = "fpga1", + .pci_domain = 0x0000, + .pci_bus = 9, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .search_mode = 1, + .bridge_bus = 0, + .bridge_slot = 0x03, + .bridge_fn = 4, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, + { + .name = "wb-pci-dev", + .id = 2, + .dev = { + .platform_data = &pcie_dev_device_data1, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_dev_device.c new file mode 100644 index 0000000000..30f577a7ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_dev_device.c @@ -0,0 +1,126 @@ +/* + * An wb_spi_dev_device driver for spi device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include "wb_spi_master.h" + +#define SPI_DEVICE_MAX_NUM (64) + +static int g_wb_spi_dev_device_debug = 0; +static int g_wb_spi_dev_device_error = 0; + +module_param(g_wb_spi_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_SPI_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_dev_device_debug) { \ + printk(KERN_INFO "[WB_SPI_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_SPI_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_dev_device_error) { \ + printk(KERN_ERR "[WB_SPI_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static spi_dev_device_t spi_dev_device_data0 = { + .spi_dev_name = "cpld11", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 1, + .per_wr_len = 1, + .spi_len = 0x100, +}; + +static struct spi_device *g_spi_device[SPI_DEVICE_MAX_NUM]; + +struct spi_board_info spi_dev_device_info[] = { + { + .modalias = "wb-spi-dev", + .max_speed_hz = 3000000, + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_3, + .platform_data = &spi_dev_device_data0, + }, +}; + +static int __init wb_spi_dev_device_init(void) +{ + int i; + struct spi_controller *ctlr; + struct spi_device *spi; + int spi_dev_num; + + WB_SPI_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + + spi_dev_num = ARRAY_SIZE(spi_dev_device_info); + if (spi_dev_num > SPI_DEVICE_MAX_NUM) { + printk(KERN_ERR "spi_dev_num[%d] is bigger than max_num[%d].\n", + spi_dev_num, SPI_DEVICE_MAX_NUM); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(spi_dev_device_info); i++) { + ctlr = wb_spi_master_busnum_to_master(spi_dev_device_info[i].bus_num); + if (!ctlr) { + printk(KERN_ERR "get bus_num %u spi master failed.\n", + spi_dev_device_info[i].bus_num); + continue; + } + spi = spi_new_device(ctlr, &spi_dev_device_info[i]); + spi_controller_put(ctlr); + if (spi) { + g_spi_device[i] = spi; + } else { + g_spi_device[i] = NULL; + printk(KERN_ERR "Failed to register spi dev device %s at bus %d!\n", + spi_dev_device_info[i].modalias, spi_dev_device_info[i].bus_num); + continue; + } + } + return 0; +} + +static void __exit wb_spi_dev_device_exit(void) +{ + int i; + + WB_SPI_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(spi_dev_device_info) - 1; i >= 0; i--) { + if (g_spi_device[i]) { + spi_unregister_device(g_spi_device[i]); + g_spi_device[i] = NULL; + } + } +} + +module_init(wb_spi_dev_device_init); +module_exit(wb_spi_dev_device_exit); +MODULE_DESCRIPTION("SPI DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_ocores_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_ocores_device.c new file mode 100644 index 0000000000..5cfa231cdf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_spi_ocores_device.c @@ -0,0 +1,115 @@ +/* + * An wb_spi_ocores_device driver for spi ocores device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_wb_spi_ocores_device_debug = 0; +static int g_wb_spi_ocores_device_error = 0; + +module_param(g_wb_spi_ocores_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_spi_ocores_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_SPI_OCORE_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_spi_ocores_device_debug) { \ + printk(KERN_INFO "[WB_SPI_OCORE_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_SPI_OCORE_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_spi_ocores_device_error) { \ + printk(KERN_ERR "[WB_SPI_OCORE_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static spi_ocores_device_t spi_ocores_device_data0 = { + .bus_num = 1, + .big_endian = 0, + .dev_name = "/dev/fpga0", + .reg_access_mode = 3, + .dev_base = 0x400, + .reg_shift = 2, + .reg_io_width = 4, + .clock_frequency = 125000000, /* 125M */ + .num_chipselect = 8, + .irq_flag = 0, + .spioc_mode = 1, +}; + +static void wb_spi_ocores_device_release(struct device *dev) +{ + return; +} + +static struct platform_device spi_ocores_device[] = { + { + .name = "wb-spioc", + .id = 1, + .dev = { + .platform_data = &spi_ocores_device_data0, + .release = wb_spi_ocores_device_release, + }, + }, +}; + +static int __init wb_spi_ocores_device_init(void) +{ + int i; + int ret = 0; + spi_ocores_device_t *spi_ocores_device_data; + + WB_SPI_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(spi_ocores_device); i++) { + spi_ocores_device_data = spi_ocores_device[i].dev.platform_data; + ret = platform_device_register(&spi_ocores_device[i]); + if (ret < 0) { + spi_ocores_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-spi-oc.%d register failed!\n", i + 1); + } else { + spi_ocores_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_spi_ocores_device_exit(void) +{ + int i; + spi_ocores_device_t *spi_ocores_device_data; + + WB_SPI_OCORE_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(spi_ocores_device) - 1; i >= 0; i--) { + spi_ocores_device_data = spi_ocores_device[i].dev.platform_data; + if (spi_ocores_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&spi_ocores_device[i]); + } + } +} + +module_init(wb_spi_ocores_device_init); +module_exit(wb_spi_ocores_device_exit); +MODULE_DESCRIPTION("SPI OCORES Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_wdt_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_wdt_device.c new file mode 100644 index 0000000000..c86e800df5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/modules/driver/wb_wdt_device.c @@ -0,0 +1,155 @@ +/* + * An wb_wdt_device driver for watchdog device function + * + * Copyright (C) 2024 Micas Networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include + +#include + +static int g_wb_wdt_device_debug = 0; +static int g_wb_wdt_device_error = 0; + +module_param(g_wb_wdt_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_wdt_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_WDT_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_wdt_device_debug) { \ + printk(KERN_INFO "[WB_WDT_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_WDT_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_wdt_device_error) { \ + printk(KERN_ERR "[WB_WDT_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + + +static wb_wdt_device_t wb_wdt_device_data_0 = { + .feed_wdt_type = 1, + .hw_margin = 90000, + .feed_time = 5000, + .config_dev_name = "/dev/cpld1", + .config_mode = 1, + .priv_func_mode = 1, + .enable_reg = 0x40, + .enable_val = 0x1, + .disable_val = 0x0, + .enable_mask = 0x1, + .timeout_cfg_reg = 0x41, + .timeleft_cfg_reg = 0x42, + .hw_algo = "toggle", + .wdt_config_mode.gpio_wdt = { + .gpio = 642, + .flags = 1 + }, + .timer_accuracy = 1600, /* 1.6s */ + .sysfs_index = SYSFS_NO_CFG, +}; + +/* sys led */ +static wb_wdt_device_t wb_wdt_device_data_1 = { + .feed_wdt_type = 2, + .hw_margin = 180000, + .feed_time = 30000, + .config_dev_name = "/dev/cpld1", + .config_mode = 2, + .priv_func_mode = 1, + .enable_reg = 0x44, + .enable_val = 0x1, + .disable_val = 0x0, + .enable_mask = 0x1, + .timeout_cfg_reg = 0x46, + .timeleft_cfg_reg = 0x47, + .hw_algo = "toggle", + .wdt_config_mode.logic_wdt = { + .feed_dev_name = "/dev/cpld1", + .feed_reg = 0x45, + .active_val = 0x01, + .logic_func_mode = 1, + }, + .timer_accuracy = 6000, /* 6s */ +}; + +static void wb_wdt_device_release(struct device *dev) +{ + return; +} + +static struct platform_device wb_wdt_device[] = { + { + .name = "wb_wdt", + .id = 0, + .dev = { + .platform_data = &wb_wdt_device_data_0, + .release = wb_wdt_device_release, + }, + }, + { + .name = "wb_wdt", + .id = 1, + .dev = { + .platform_data = &wb_wdt_device_data_1, + .release = wb_wdt_device_release, + }, + }, +}; + +static int __init wb_wdt_device_init(void) +{ + int i; + int ret = 0; + wb_wdt_device_t *wb_wdt_device_data; + + WB_WDT_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(wb_wdt_device); i++) { + wb_wdt_device_data = wb_wdt_device[i].dev.platform_data; + ret = platform_device_register(&wb_wdt_device[i]); + if (ret < 0) { + wb_wdt_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "rg-wdt.%d register failed!\n", i + 1); + } else { + wb_wdt_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_wdt_device_exit(void) +{ + int i; + wb_wdt_device_t *wb_wdt_device_data; + + WB_WDT_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(wb_wdt_device) - 1; i >= 0; i--) { + wb_wdt_device_data = wb_wdt_device[i].dev.platform_data; + if (wb_wdt_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&wb_wdt_device[i]); + } + } +} + +module_init(wb_wdt_device_init); +module_exit(wb_wdt_device_exit); +MODULE_DESCRIPTION("WB WDT Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/CPLD.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/CPLD.cfg new file mode 100644 index 0000000000..c85c3aca16 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/CPLD.cfg @@ -0,0 +1,275 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Set item: System E2 i2c bus address +# Description: Format other_i2c_dev.bus_[main_dev]_[minor_dev] other_i2c_dev.addr_[main_dev]_[minor_dev], +# .bus is configuration item corresponds to the bus number (/dev/i2c-bus) +# .addr is address of the device corresponding to the configuration item on the bus +# Note: main_dev look rg_main_dev_type_t definition, main board is 0, minor_dev is 0 +other_i2c_dev.bus_0_0=1 +other_i2c_dev.addr_0_0=0x56 + +# Configuration item: System E2 path +eeprom_path_0_0=/sys/bus/i2c/devices/1-0056/eeprom + +# Configuration item: System E2 size +eeprom_size_0_0=256 + +# Configuration item: watchdog number +# Description: Format watchdog_id_[index] +watchdog_id_0=0 + +# Configuration item: i2c bus address of the cpld +# Description: Format cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# All cpld numbers of each product are customized and do not have to be repeated. +# The numbers are reflected in the upper eight digits of the offset address of the cpld device +# cpld_slot: 1: cable card 1, 2: cable card 2, 3: cable card 3, 4: cable card 4,5: fan adapter board +# cpld_id: 0:CPLD_A 1:CPLD_B +# .bus is configuration item corresponds to the bus number(/dev/i2c-bus) +# .addr is address of the device corresponding to the configuration item on the bus +# Note: This field is optional. This field is not required for a cpld that does not have I2C access +cpld_i2c_dev.bus_0_0=0 +cpld_i2c_dev.addr_0_0=0x0d +cpld_i2c_dev.bus_0_1=21 +cpld_i2c_dev.addr_0_1=0x0d +cpld_i2c_dev.bus_0_2=99 +cpld_i2c_dev.addr_0_2=0x1d +cpld_i2c_dev.bus_0_3=100 +cpld_i2c_dev.addr_0_3=0x3d +cpld_i2c_dev.bus_0_4=107 +cpld_i2c_dev.addr_0_4=0x2d +cpld_i2c_dev.bus_0_5=59 +cpld_i2c_dev.addr_0_5=0x0d + + +# Configuration item: Access mode of each cpld(LPC/I2C) +# Description: Format mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c, cpld_id is cpld number,Start at 0 +# Note: This field is required +mode_cpld_0_0=i2c +mode_cpld_0_1=i2c +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c +mode_cpld_0_5=i2c + +# Configuration item: the number of CPLD +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev: indicates that the mainboard is 0, the subPLD is 5, and the minor_dev: CPLD is 8 +dev_num_0_8=6 + +# Configuration item: Name of each cpld +# Description: Format cpld_name_[cpld_id] cpld_id is cpld number,start with 1 +# Note: This field is required +cpld_name_0_0=CPU_CPLD +cpld_name_0_1=BASE_CPLD +cpld_name_0_2=MAC_CPLDA +cpld_name_0_3=MAC_CPLDB +cpld_name_0_4=IO_CPLD +cpld_name_0_5=FAN_CPLD + + +# Configuration item: Model of each cpld +# Description: Format cpld_type_[cpld_id] cpld_idis cpld number,start with 1 +# Note: This field is required +cpld_type_0_0=LATTICE/LCMXO3LF-6900C-5BG400C +cpld_type_0_1=LATTICE/LCMXO3LF-6900C-5BG400C +cpld_type_0_2=LATTICE/LCMXO3LF-4300C-6BG324I +cpld_type_0_3=LATTICE/LCMXO3LF-4300C-6BG324I +cpld_type_0_4=LATTICE/LCMXO3LF-4300C-6BG324I +cpld_type_0_5=LATTICE/LCMXO3LF-6900C-5BG256C + +# Configuration item: Version register of each CPLD +# Description: Format cpld_version_[cpld_id] cpld_id is cpld number,start with 1 +# Note: This field is required +cpld_version.mode_0_0=config +cpld_version.int_cons_0_0= +cpld_version.src_0_0=cpld +cpld_version.frmt_0_0=num_bytes +cpld_version.pola_0_0= +cpld_version.fpath_0_0= +cpld_version.addr_0_0=0x00000000 +cpld_version.len_0_0=4 +cpld_version.bit_offset_0_0= + +cpld_version.mode_0_1=config +cpld_version.int_cons_0_1= +cpld_version.src_0_1=cpld +cpld_version.frmt_0_1=num_bytes +cpld_version.pola_0_1= +cpld_version.fpath_0_1= +cpld_version.addr_0_1=0x00010000 +cpld_version.len_0_1=4 +cpld_version.bit_offset_0_1= + +cpld_version.mode_0_2=config +cpld_version.int_cons_0_2= +cpld_version.src_0_2=cpld +cpld_version.frmt_0_2=num_bytes +cpld_version.pola_0_2= +cpld_version.fpath_0_2= +cpld_version.addr_0_2=0x00020000 +cpld_version.len_0_2=4 +cpld_version.bit_offset_0_2= + +cpld_version.mode_0_3=config +cpld_version.int_cons_0_3= +cpld_version.src_0_3=cpld +cpld_version.frmt_0_3=num_bytes +cpld_version.pola_0_3= +cpld_version.fpath_0_3= +cpld_version.addr_0_3=0x00030000 +cpld_version.len_0_3=4 +cpld_version.bit_offset_0_3= + +cpld_version.mode_0_4=config +cpld_version.int_cons_0_4= +cpld_version.src_0_4=cpld +cpld_version.frmt_0_4=num_bytes +cpld_version.pola_0_4= +cpld_version.fpath_0_4= +cpld_version.addr_0_4=0x00040000 +cpld_version.len_0_4=4 +cpld_version.bit_offset_0_4= + +cpld_version.mode_0_5=config +cpld_version.int_cons_0_5= +cpld_version.src_0_5=cpld +cpld_version.frmt_0_5=num_bytes +cpld_version.pola_0_5= +cpld_version.fpath_0_5= +cpld_version.addr_0_5=0x00050000 +cpld_version.len_0_5=4 +cpld_version.bit_offset_0_5= + + +# Configuration item: Test register for each CPLD +# Description: Format cpld_test_reg_[cpld_id] cpld_id is cpld number,start with 1 +# Note: This field is required +cpld_test_reg.mode_0_0=config +cpld_test_reg.int_cons_0_0= +cpld_test_reg.src_0_0=cpld +cpld_test_reg.frmt_0_0=byte +cpld_test_reg.pola_0_0= +cpld_test_reg.fpath_0_0= +cpld_test_reg.addr_0_0=0x0000000f +cpld_test_reg.len_0_0=1 +cpld_test_reg.bit_offset_0_0= + +cpld_test_reg.mode_0_1=config +cpld_test_reg.int_cons_0_1= +cpld_test_reg.src_0_1=cpld +cpld_test_reg.frmt_0_1=byte +cpld_test_reg.pola_0_1= +cpld_test_reg.fpath_0_1= +cpld_test_reg.addr_0_1=0x0001000f +cpld_test_reg.len_0_1=1 +cpld_test_reg.bit_offset_0_1= + +cpld_test_reg.mode_0_2=config +cpld_test_reg.int_cons_0_2= +cpld_test_reg.src_0_2=cpld +cpld_test_reg.frmt_0_2=byte +cpld_test_reg.pola_0_2= +cpld_test_reg.fpath_0_2= +cpld_test_reg.addr_0_2=0x0002000f +cpld_test_reg.len_0_2=1 +cpld_test_reg.bit_offset_0_2= + +cpld_test_reg.mode_0_3=config +cpld_test_reg.int_cons_0_3= +cpld_test_reg.src_0_3=cpld +cpld_test_reg.frmt_0_3=byte +cpld_test_reg.pola_0_3= +cpld_test_reg.fpath_0_3= +cpld_test_reg.addr_0_3=0x0003000f +cpld_test_reg.len_0_3=1 +cpld_test_reg.bit_offset_0_3= + +cpld_test_reg.mode_0_4=config +cpld_test_reg.int_cons_0_4= +cpld_test_reg.src_0_4=cpld +cpld_test_reg.frmt_0_4=byte +cpld_test_reg.pola_0_4= +cpld_test_reg.fpath_0_4= +cpld_test_reg.addr_0_4=0x0004000f +cpld_test_reg.len_0_4=1 +cpld_test_reg.bit_offset_0_4= + +cpld_test_reg.mode_0_5=config +cpld_test_reg.int_cons_0_5= +cpld_test_reg.src_0_5=cpld +cpld_test_reg.frmt_0_5=byte +cpld_test_reg.pola_0_5= +cpld_test_reg.fpath_0_5= +cpld_test_reg.addr_0_5=0x0005000f +cpld_test_reg.len_0_5=1 +cpld_test_reg.bit_offset_0_5= + +# Configuration item: Hardware version register of each CPLD +# Description: Format cpld_hw_version_[cpld_id] cpld_id is cpld number,start with 1 +# Note: Optional +cpld_hw_version.mode_0_0=config +cpld_hw_version.int_cons_0_0= +cpld_hw_version.src_0_0=cpld +cpld_hw_version.frmt_0_0=byte +cpld_hw_version.pola_0_0= +cpld_hw_version.fpath_0_0= +cpld_hw_version.addr_0_0=0x0000000c +cpld_hw_version.len_0_0=1 +cpld_hw_version.bit_offset_0_0= + +cpld_hw_version.mode_0_1=config +cpld_hw_version.int_cons_0_1= +cpld_hw_version.src_0_1=cpld +cpld_hw_version.frmt_0_1=byte +cpld_hw_version.pola_0_1= +cpld_hw_version.fpath_0_1= +cpld_hw_version.addr_0_1=0x0001000c +cpld_hw_version.len_0_1=1 +cpld_hw_version.bit_offset_0_1= + +cpld_hw_version.mode_0_2=config +cpld_hw_version.int_cons_0_2= +cpld_hw_version.src_0_2=cpld +cpld_hw_version.frmt_0_2=byte +cpld_hw_version.pola_0_2= +cpld_hw_version.fpath_0_2= +cpld_hw_version.addr_0_2=0x0002000c +cpld_hw_version.len_0_2=1 +cpld_hw_version.bit_offset_0_2= + +cpld_hw_version.mode_0_3=config +cpld_hw_version.int_cons_0_3= +cpld_hw_version.src_0_3=cpld +cpld_hw_version.frmt_0_3=byte +cpld_hw_version.pola_0_3= +cpld_hw_version.fpath_0_3= +cpld_hw_version.addr_0_3=0x0003000c +cpld_hw_version.len_0_3=1 +cpld_hw_version.bit_offset_0_3= + +cpld_hw_version.mode_0_4=config +cpld_hw_version.int_cons_0_4= +cpld_hw_version.src_0_4=cpld +cpld_hw_version.frmt_0_4=byte +cpld_hw_version.pola_0_4= +cpld_hw_version.fpath_0_4= +cpld_hw_version.addr_0_4=0x0004000c +cpld_hw_version.len_0_4=1 +cpld_hw_version.bit_offset_0_4= + +cpld_hw_version.mode_0_5=config +cpld_hw_version.int_cons_0_5= +cpld_hw_version.src_0_5=cpld +cpld_hw_version.frmt_0_5=byte +cpld_hw_version.pola_0_5= +cpld_hw_version.fpath_0_5= +cpld_hw_version.addr_0_5=0x0005000c +cpld_hw_version.len_0_5=1 +cpld_hw_version.bit_offset_0_5= diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FAN.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FAN.cfg new file mode 100644 index 0000000000..7e4a608398 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FAN.cfg @@ -0,0 +1,440 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration items: E2 i2c bus address +# Description: Format other_i2c_dev.bus_[main_dev]_[minor_dev] other_i2c_dev.addr_[main_dev]_[minor_dev], +# .bus is configuration item corresponds to the bus number (/dev/i2c-bus) +# .addr is address of the device corresponding to the configuration item on the bus +# Note: main_dev is defined in rg_main_dev_type_t. mainboard is 0, fan is 1, dev_index is device index +other_i2c_dev.bus_1_1=59 +other_i2c_dev.addr_1_1=0x50 +other_i2c_dev.bus_1_2=60 +other_i2c_dev.addr_1_2=0x50 +other_i2c_dev.bus_1_3=61 +other_i2c_dev.addr_1_3=0x50 +other_i2c_dev.bus_1_4=62 +other_i2c_dev.addr_1_4=0x50 +other_i2c_dev.bus_1_5=63 +other_i2c_dev.addr_1_5=0x50 +other_i2c_dev.bus_1_6=64 +other_i2c_dev.addr_1_6=0x50 + +# Configuration items: Fan dependent constant +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,Fan is 1 minor_dev, 0: does not exist, 5: motor + +# Number of fans +dev_num_1_0=6 + +# Number of motors +dev_num_1_5=2 + +# Configuration items: Product fan E2 format +# Description: Format fan_e2_mode +# Note: required +fan_e2_mode=fru + +# Configuration items: Mode of reading fan E2 +# Description: Format fan_sysfs_name +# Note: If not configured, it is read by i2c, otherwise it is read by sysfs +fan_sysfs_name=eeprom + +# Configuration items: Fan air duct type +# Filling instructions: fan_direction_[direction]_[index] +# direction is air duct 0:F2B 1:B2F, indexstart with 1 +# Note: required +fan_direction_0_1=FAN40-01L-CP + +# Configuration items: Fan status CPLD register address +# Description: Format dev_present_status_[main_dev_id][fan_index] fan_indexstart with 1 +# Note: fan main_dev_id is 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=file +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.fpath_1_1=/dev/cpld10 +dev_present_status.addr_1_1=0xda +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=0 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=file +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.fpath_1_2=/dev/cpld10 +dev_present_status.addr_1_2=0xda +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=1 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=file +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.fpath_1_3=/dev/cpld10 +dev_present_status.addr_1_3=0xda +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=2 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=file +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.fpath_1_4=/dev/cpld10 +dev_present_status.addr_1_4=0xda +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=3 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=file +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.fpath_1_5=/dev/cpld10 +dev_present_status.addr_1_5=0xda +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=4 + +dev_present_status.mode_1_6=config +dev_present_status.src_1_6=file +dev_present_status.frmt_1_6=bit +dev_present_status.pola_1_6=negative +dev_present_status.fpath_1_6=/dev/cpld10 +dev_present_status.addr_1_6=0xda +dev_present_status.len_1_6=1 +dev_present_status.bit_offset_1_6=5 + +# Configuration items: Fan rotation status CPLD register address +# Description: Format fan_roll_status_[fan_id]_[motor_id] fan_idstart with 1, motor_idstart with 1 +# Note: required +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=file +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1=/dev/cpld10 +fan_roll_status.addr_1_1=0xdb +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=0 + +fan_roll_status.mode_1_2=config +fan_roll_status.int_cons_1_2= +fan_roll_status.src_1_2=file +fan_roll_status.frmt_1_2=bit +fan_roll_status.pola_1_2=positive +fan_roll_status.fpath_1_2=/dev/cpld10 +fan_roll_status.addr_1_2=0xdc +fan_roll_status.len_1_2=1 +fan_roll_status.bit_offset_1_2=0 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=file +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1=/dev/cpld10 +fan_roll_status.addr_2_1=0xdb +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=1 + +fan_roll_status.mode_2_2=config +fan_roll_status.int_cons_2_2= +fan_roll_status.src_2_2=file +fan_roll_status.frmt_2_2=bit +fan_roll_status.pola_2_2=positive +fan_roll_status.fpath_2_2=/dev/cpld10 +fan_roll_status.addr_2_2=0xdc +fan_roll_status.len_2_2=1 +fan_roll_status.bit_offset_2_2=1 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=file +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1=/dev/cpld10 +fan_roll_status.addr_3_1=0xdb +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=2 + +fan_roll_status.mode_3_2=config +fan_roll_status.int_cons_3_2= +fan_roll_status.src_3_2=file +fan_roll_status.frmt_3_2=bit +fan_roll_status.pola_3_2=positive +fan_roll_status.fpath_3_2=/dev/cpld10 +fan_roll_status.addr_3_2=0xdc +fan_roll_status.len_3_2=1 +fan_roll_status.bit_offset_3_2=2 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=file +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1=/dev/cpld10 +fan_roll_status.addr_4_1=0xdb +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=3 + +fan_roll_status.mode_4_2=config +fan_roll_status.int_cons_4_2= +fan_roll_status.src_4_2=file +fan_roll_status.frmt_4_2=bit +fan_roll_status.pola_4_2=positive +fan_roll_status.fpath_4_2=/dev/cpld10 +fan_roll_status.addr_4_2=0xdc +fan_roll_status.len_4_2=1 +fan_roll_status.bit_offset_4_2=3 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=file +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1=/dev/cpld10 +fan_roll_status.addr_5_1=0xdb +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=4 + +fan_roll_status.mode_5_2=config +fan_roll_status.int_cons_5_2= +fan_roll_status.src_5_2=file +fan_roll_status.frmt_5_2=bit +fan_roll_status.pola_5_2=positive +fan_roll_status.fpath_5_2=/dev/cpld10 +fan_roll_status.addr_5_2=0xdc +fan_roll_status.len_5_2=1 +fan_roll_status.bit_offset_5_2=4 + +fan_roll_status.mode_6_1=config +fan_roll_status.int_cons_6_1= +fan_roll_status.src_6_1=file +fan_roll_status.frmt_6_1=bit +fan_roll_status.pola_6_1=positive +fan_roll_status.fpath_6_1=/dev/cpld10 +fan_roll_status.addr_6_1=0xdb +fan_roll_status.len_6_1=1 +fan_roll_status.bit_offset_6_1=5 + +fan_roll_status.mode_6_2=config +fan_roll_status.int_cons_6_2= +fan_roll_status.src_6_2=file +fan_roll_status.frmt_6_2=bit +fan_roll_status.pola_6_2=positive +fan_roll_status.fpath_6_2=/dev/cpld10 +fan_roll_status.addr_6_2=0xdc +fan_roll_status.len_6_2=1 +fan_roll_status.bit_offset_6_2=5 + +# Configuration items: Fan speed CPLD register address +# Description: Format fan_speed_[fan_id]_[motor_id] fan_idstart with 1, motor_idstart with 1 +# Note: required +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=file +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1= +fan_speed.fpath_1_1=/dev/cpld10 +fan_speed.addr_1_1=0x60 +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_1_2=config +fan_speed.int_cons_1_2= +fan_speed.src_1_2=file +fan_speed.frmt_1_2=num_bytes +fan_speed.pola_1_2= +fan_speed.fpath_1_2=/dev/cpld10 +fan_speed.addr_1_2=0x70 +fan_speed.len_1_2=2 +fan_speed.bit_offset_1_2= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=file +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1= +fan_speed.fpath_2_1=/dev/cpld10 +fan_speed.addr_2_1=0x62 +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_2_2=config +fan_speed.int_cons_2_2= +fan_speed.src_2_2=file +fan_speed.frmt_2_2=num_bytes +fan_speed.pola_2_2= +fan_speed.fpath_2_2=/dev/cpld10 +fan_speed.addr_2_2=0x72 +fan_speed.len_2_2=2 +fan_speed.bit_offset_2_2= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=file +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1= +fan_speed.fpath_3_1=/dev/cpld10 +fan_speed.addr_3_1=0x64 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_3_2=config +fan_speed.int_cons_3_2= +fan_speed.src_3_2=file +fan_speed.frmt_3_2=num_bytes +fan_speed.pola_3_2= +fan_speed.fpath_3_2=/dev/cpld10 +fan_speed.addr_3_2=0x74 +fan_speed.len_3_2=2 +fan_speed.bit_offset_3_2= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=file +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1= +fan_speed.fpath_4_1=/dev/cpld10 +fan_speed.addr_4_1=0x66 +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_4_2=config +fan_speed.int_cons_4_2= +fan_speed.src_4_2=file +fan_speed.frmt_4_2=num_bytes +fan_speed.pola_4_2= +fan_speed.fpath_4_2=/dev/cpld10 +fan_speed.addr_4_2=0x76 +fan_speed.len_4_2=2 +fan_speed.bit_offset_4_2= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=file +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1= +fan_speed.fpath_5_1=/dev/cpld10 +fan_speed.addr_5_1=0x68 +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + +fan_speed.mode_5_2=config +fan_speed.int_cons_5_2= +fan_speed.src_5_2=file +fan_speed.frmt_5_2=num_bytes +fan_speed.pola_5_2= +fan_speed.fpath_5_2=/dev/cpld10 +fan_speed.addr_5_2=0x78 +fan_speed.len_5_2=2 +fan_speed.bit_offset_5_2= + +fan_speed.mode_6_1=config +fan_speed.int_cons_6_1= +fan_speed.src_6_1=file +fan_speed.frmt_6_1=num_bytes +fan_speed.pola_6_1= +fan_speed.fpath_6_1=/dev/cpld10 +fan_speed.addr_6_1=0x6A +fan_speed.len_6_1=2 +fan_speed.bit_offset_6_1= + +fan_speed.mode_6_2=config +fan_speed.int_cons_6_2= +fan_speed.src_6_2=file +fan_speed.frmt_6_2=num_bytes +fan_speed.pola_6_2= +fan_speed.fpath_6_2=/dev/cpld10 +fan_speed.addr_6_2=0x7A +fan_speed.len_6_2=2 +fan_speed.bit_offset_6_2= + +# Configuration items: Fan speed level CPLD register address +# Description: Format fan_ratio_[fan_id]_[motor_id] fan_idstart with 1, motor_idstart with 1 +# Note: required +fan_ratio.mode_1=config +fan_ratio.int_cons_1= +fan_ratio.src_1=file +fan_ratio.frmt_1=byte +fan_ratio.pola_1= +fan_ratio.fpath_1=/dev/cpld10 +fan_ratio.addr_1=0xb0 +fan_ratio.len_1=1 +fan_ratio.bit_offset_1= + +fan_ratio.mode_2=config +fan_ratio.int_cons_2= +fan_ratio.src_2=file +fan_ratio.frmt_2=byte +fan_ratio.pola_2= +fan_ratio.fpath_2=/dev/cpld10 +fan_ratio.addr_2=0xb1 +fan_ratio.len_2=1 +fan_ratio.bit_offset_2= + +fan_ratio.mode_3=config +fan_ratio.int_cons_3= +fan_ratio.src_3=file +fan_ratio.frmt_3=byte +fan_ratio.pola_3= +fan_ratio.fpath_3=/dev/cpld10 +fan_ratio.addr_3=0xb2 +fan_ratio.len_3=1 +fan_ratio.bit_offset_3= + +fan_ratio.mode_4=config +fan_ratio.int_cons_4= +fan_ratio.src_4=file +fan_ratio.frmt_4=byte +fan_ratio.pola_4= +fan_ratio.fpath_4=/dev/cpld10 +fan_ratio.addr_4=0xb3 +fan_ratio.len_4=1 +fan_ratio.bit_offset_4= + +fan_ratio.mode_5=config +fan_ratio.int_cons_5= +fan_ratio.src_5=file +fan_ratio.frmt_5=byte +fan_ratio.pola_5= +fan_ratio.fpath_5=/dev/cpld10 +fan_ratio.addr_5=0xb4 +fan_ratio.len_5=1 +fan_ratio.bit_offset_5= + +fan_ratio.mode_6=config +fan_ratio.int_cons_6= +fan_ratio.src_6=file +fan_ratio.frmt_6=byte +fan_ratio.pola_6= +fan_ratio.fpath_6=/dev/cpld10 +fan_ratio.addr_6=0xb5 +fan_ratio.len_6=1 +fan_ratio.bit_offset_6= + + +# Configuration items: the number of fan names displayed in the product +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,FAN is 1, minor_dev, 7: The number of fan names displayed +dev_num_1_7=1 + +# Configuration items: number of fan types supported by each fan name +# Description: Format fan_type_num_[fan_id] +# Note: fan_id start with 1 +fan_type_num_1=1 + +# Configuration items: product Fan type Name +# Description: Format fan_name_[index1]_[index2] +# Note: index1 indicates the ID of the fan that is displayed, start with 1, +# index2 Indicates different fan names with the same ID, start with 1 +fan_name_0_1=FAN40-01L-CP + +# Configuration items: fan name is displayed +# Description: Format decode_fan_name_[index] +# Note: index indicates the ID of the fan that is displayed +decode_fan_name_1=FAN40-01L-CP diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FPGA.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FPGA.cfg new file mode 100644 index 0000000000..5436320855 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/FPGA.cfg @@ -0,0 +1,95 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + + +# Configuration item: motherboard FPGA number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev: motherboard is 0,daughter card is 5, minor_dev: FPGA is 8 +dev_num_0_9=2 + +# Configuration item: name of each fpga +# Description: Format fpga_name_[fpga_id] fpga_id is fpga number,Start at 0 +# Note: required +fpga_name_0_0=MAC_FPGA +fpga_name_0_1=IO_FPGA + +# Configuration item: Version register for each FPGA +# Description: Format fpga_version_[fpga_id] fpga_id is fpga number,Start at 0 +# Note: required +fpga_version.mode_0_0=config +fpga_version.int_cons_0_0= +fpga_version.src_0_0=file +fpga_version.frmt_0_0=num_bytes +fpga_version.pola_0_0=negative +fpga_version.fpath_0_0=/dev/fpga0 +fpga_version.addr_0_0=0x0 +fpga_version.len_0_0=4 +fpga_version.bit_offset_0_0= + +fpga_version.mode_0_1=config +fpga_version.int_cons_0_1= +fpga_version.src_0_1=file +fpga_version.frmt_0_1=num_bytes +fpga_version.pola_0_1=negative +fpga_version.fpath_0_1=/dev/fpga1 +fpga_version.addr_0_1=0x0 +fpga_version.len_0_1=4 +fpga_version.bit_offset_0_1= + +# Configuration item: Test registers for each FPGA +# Description: Format fpga_test_reg_[fpga_id] fpga_id is fpga number,Start at 0 +# Note: required +fpga_test_reg.mode_0_0=config +fpga_test_reg.int_cons_0_0= +fpga_test_reg.src_0_0=file +fpga_test_reg.frmt_0_0=num_bytes +fpga_test_reg.pola_0_0=negative +fpga_test_reg.fpath_0_0=/dev/fpga0 +fpga_test_reg.addr_0_0=0x08 +fpga_test_reg.len_0_0=4 +fpga_test_reg.bit_offset_0_0= + +fpga_test_reg.mode_0_1=config +fpga_test_reg.int_cons_0_1= +fpga_test_reg.src_0_1=file +fpga_test_reg.frmt_0_1=num_bytes +fpga_test_reg.pola_0_1=negative +fpga_test_reg.fpath_0_1=/dev/fpga1 +fpga_test_reg.addr_0_1=0x08 +fpga_test_reg.len_0_1=4 +fpga_test_reg.bit_offset_0_1= + +# Configuration item: Device type register for each FPGA +# Description: Format fpga_model_reg_[main_dev]_[fpga_id] +# Note: main_dev: motherboard is 0, daughter card is 5, fpga_id is fpga number,Start at 0 +fpga_model_reg.mode_0_0=config +fpga_model_reg.int_cons_0_0= +fpga_model_reg.src_0_0=file +fpga_model_reg.frmt_0_0=num_bytes +fpga_model_reg.pola_0_0=negative +fpga_model_reg.fpath_0_0=/dev/fpga0 +fpga_model_reg.addr_0_0=0x10 +fpga_model_reg.len_0_0=4 +fpga_model_reg.bit_offset_0_0= + +fpga_model_reg.mode_0_1=config +fpga_model_reg.int_cons_0_1= +fpga_model_reg.src_0_1=file +fpga_model_reg.frmt_0_1=num_bytes +fpga_model_reg.pola_0_1=negative +fpga_model_reg.fpath_0_1=/dev/fpga1 +fpga_model_reg.addr_0_1=0x10 +fpga_model_reg.len_0_1=4 +fpga_model_reg.bit_offset_0_1= + +# Configuration item: Device conversion configuration for each FPGA +# Description: Format fpga_model_decode_[origin_value] +# Note: origin_value is the value read from the FPGA device model register cannot exceed 0xffff +fpga_model_decode_0x50=XC7A50T_2FGG484C +fpga_model_decode_0x100=XC7A100T_2FGG484C diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/LED.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/LED.cfg new file mode 100644 index 0000000000..392a7e8e2f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/LED.cfg @@ -0,0 +1,165 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration item: LED CPLD register address +# Description: Formatled_status_[led_id]_[led_index] +# Note: led_id By definition wb_led_t +# led_index:If there is no index, fill in 0. If there is an index (such as a fan light), the number starts from 1 + +# Front panel SYS light +led_status.mode_0_0=config +led_status.src_0_0=file +led_status.frmt_0_0=byte +led_status.fpath_0_0=/dev/cpld1 +led_status.addr_0_0=0xaa +led_status.len_0_0=1 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 0- Front panel SYS light +# cpld: 0: off, 1: red flash, 2: red, 3: green flash, 4: green, 5: amber flash, 6: amber +# s3ip: 0: off, 1: green, 2: amber, 3: red, 4: blue, 5: green flash, 6: amber flash, +# 7: red flash, 8: blue flash +led_status_decode_0_0=0 +led_status_decode_0_1=7 +led_status_decode_0_2=3 +led_status_decode_0_3=5 +led_status_decode_0_4=1 +led_status_decode_0_5=6 +led_status_decode_0_6=2 +led_status_decode_0_17=5 +led_status_decode_0_18=7 +led_status_decode_0_19=6 +led_status_decode_0_33=5 +led_status_decode_0_34=7 +led_status_decode_0_35=6 +led_status_decode_0_65=5 +led_status_decode_0_66=7 +led_status_decode_0_67=6 +led_status_decode_0_129=5 +led_status_decode_0_130=7 +led_status_decode_0_131=6 +led_status_decode_0_255=0 + +# Front panel BMC light +led_status.mode_2_0=config +led_status.src_2_0=file +led_status.frmt_2_0=byte +led_status.fpath_2_0=/dev/cpld1 +led_status.addr_2_0=0xab +led_status.len_2_0=1 + +led_status_decode_2_0=0 +led_status_decode_2_1=7 +led_status_decode_2_2=3 +led_status_decode_2_3=5 +led_status_decode_2_4=1 +led_status_decode_2_5=6 +led_status_decode_2_6=2 +led_status_decode_2_7=0 + +# Front panel FAN light +led_status.mode_4_0=config +led_status.src_4_0=file +led_status.frmt_4_0=byte +led_status.fpath_4_0=/dev/cpld1 +led_status.addr_4_0=0xad +led_status.len_4_0=1 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 4-Front panel FAN light +led_status_decode_4_0=0 +led_status_decode_4_1=7 +led_status_decode_4_2=3 +led_status_decode_4_3=5 +led_status_decode_4_4=1 +led_status_decode_4_5=6 +led_status_decode_4_6=2 +led_status_decode_4_7=0 + +# Front panel PSU light +led_status.mode_6_0=config +led_status.src_6_0=file +led_status.frmt_6_0=byte +led_status.fpath_6_0=/dev/cpld1 +led_status.addr_6_0=0xac +led_status.len_6_0=1 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 6-Front panel PSU light +led_status_decode_6_0=0 +led_status_decode_6_1=7 +led_status_decode_6_2=3 +led_status_decode_6_3=5 +led_status_decode_6_4=1 +led_status_decode_6_5=6 +led_status_decode_6_6=2 +led_status_decode_6_7=0 + +# Fan body lamp1 +led_status.mode_10_1=config +led_status.src_10_1=file +led_status.frmt_10_1=byte +led_status.fpath_10_1=/dev/cpld10 +led_status.addr_10_1=0xd0 +led_status.len_10_1=1 + +# Fan body lamp2 +led_status.mode_10_2=config +led_status.src_10_2=file +led_status.frmt_10_2=byte +led_status.fpath_10_2=/dev/cpld10 +led_status.addr_10_2=0xd1 +led_status.len_10_2=1 + +# Fan body lamp3 +led_status.mode_10_3=config +led_status.src_10_3=file +led_status.frmt_10_3=byte +led_status.fpath_10_3=/dev/cpld10 +led_status.addr_10_3=0xd2 +led_status.len_10_3=1 + +# Fan body lamp4 +led_status.mode_10_4=config +led_status.src_10_4=file +led_status.frmt_10_4=byte +led_status.fpath_10_4=/dev/cpld10 +led_status.addr_10_4=0xd3 +led_status.len_10_4=1 + +# Fan body lamp5 +led_status.mode_10_5=config +led_status.src_10_5=file +led_status.frmt_10_5=byte +led_status.fpath_10_5=/dev/cpld10 +led_status.addr_10_5=0xd4 +led_status.len_10_5=1 + +# Fan body lamp6 +led_status.mode_10_6=config +led_status.src_10_6=file +led_status.frmt_10_6=byte +led_status.fpath_10_6=/dev/cpld10 +led_status.addr_10_6=0xd5 +led_status.len_10_6=1 + +# Configuration item: LED indicator CPLD register value converted to standard value +# Description: Format led_status_decode_[led_id]_[origin_value] origin_value:Original CPLD value +# led_id Same LED light type defined, 10-Fan body lamp +led_status_decode_10_0=0 +led_status_decode_10_1=7 +led_status_decode_10_2=3 +led_status_decode_10_3=5 +led_status_decode_10_4=1 +led_status_decode_10_5=6 +led_status_decode_10_6=2 +led_status_decode_10_7=0 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/PSU.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/PSU.cfg new file mode 100644 index 0000000000..b96310f499 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/PSU.cfg @@ -0,0 +1,1088 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration items: PSU number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev,0 indicates the obtained number +dev_num_2_0=4 + +# Configuration items: PSU temperature sensors number +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev, 1:temperature +dev_num_2_1=2 + +# Configuration item: Method of reading power FRU information +# Description: Format psu_fru_mode +# Note: If not configured, read through EEPROM, otherwise read through pmbus +psu_fru_mode=pmbus + +# Configuration item: product power type name +# Fill in instructions: format power_name_[index1]_[index2] +# Note: index1 indicates the power supply ID displayed, starting from 1, index2 indicates different power supplies with the same ID, starting from 1 +power_name_1_1=Q54SN120A1RNPH +power_name_2_1=BMR3502250531 + +# Configuration item: Displays the power supply name +# Fill in instructions: format decode_power_name_[index] +# Note: index indicates the ID of the power supply that is displayed +decode_power_name_1=Q54SN120A1RNPH +decode_power_name_2=BMR3502250531 + +# Configuration item: Method of reading power FRU information +# Fill in the description: format psu_fru_pmbus_[psu_index]_[fruid] +# Note: psu_index: indicates the power supply number, starting from 1 +# Note: fruid: 3:serial_number(mfr_serial), 5:hardware_version(mfr_revision), 8:part_number(mfr_model), 12:date(mfr_date), 13:vendor(mfr_id), +# mfr_serial +psu_fru_pmbus.mode_1_3=config +psu_fru_pmbus.int_cons_1_3=0 +psu_fru_pmbus.src_1_3=file +psu_fru_pmbus.frmt_1_3=buf +psu_fru_pmbus.fpath_1_3=/sys/bus/i2c/devices/53-0060/mfr_serial +psu_fru_pmbus.addr_1_3=0 +psu_fru_pmbus.len_1_3=32 +psu_fru_pmbus.bit_offset_1_3= +psu_fru_pmbus.str_cons_1_3= + +# mfr_revision +psu_fru_pmbus.mode_1_5=config +psu_fru_pmbus.int_cons_1_5=0 +psu_fru_pmbus.src_1_5=file +psu_fru_pmbus.frmt_1_5=buf +psu_fru_pmbus.fpath_1_5=/sys/bus/i2c/devices/53-0060/mfr_revision +psu_fru_pmbus.addr_1_5=0 +psu_fru_pmbus.len_1_5=32 +psu_fru_pmbus.bit_offset_1_5= +psu_fru_pmbus.str_cons_1_5= + +# mfr_model +psu_fru_pmbus.mode_1_8=config +psu_fru_pmbus.int_cons_1_8=0 +psu_fru_pmbus.src_1_8=file +psu_fru_pmbus.frmt_1_8=buf +psu_fru_pmbus.fpath_1_8=/sys/bus/i2c/devices/53-0060/mfr_model +psu_fru_pmbus.addr_1_8=0 +psu_fru_pmbus.len_1_8=32 +psu_fru_pmbus.bit_offset_1_8= +psu_fru_pmbus.str_cons_1_8= + +# mfr_date +psu_fru_pmbus.mode_1_12=config +psu_fru_pmbus.int_cons_1_12=0 +psu_fru_pmbus.src_1_12=file +psu_fru_pmbus.frmt_1_12=buf +psu_fru_pmbus.fpath_1_12=/sys/bus/i2c/devices/53-0060/mfr_date +psu_fru_pmbus.addr_1_12=0 +psu_fru_pmbus.len_1_12=32 +psu_fru_pmbus.bit_offset_1_12= +psu_fru_pmbus.str_cons_1_12= + +# mfr_id +psu_fru_pmbus.mode_1_13=config +psu_fru_pmbus.int_cons_1_13=0 +psu_fru_pmbus.src_1_13=file +psu_fru_pmbus.frmt_1_13=buf +psu_fru_pmbus.fpath_1_13=/sys/bus/i2c/devices/53-0060/mfr_id +psu_fru_pmbus.addr_1_13=0 +psu_fru_pmbus.len_1_13=32 +psu_fru_pmbus.bit_offset_1_13= +psu_fru_pmbus.str_cons_1_13= + + +# mfr_serial +psu_fru_pmbus.mode_2_3=config +psu_fru_pmbus.int_cons_2_3=0 +psu_fru_pmbus.src_2_3=file +psu_fru_pmbus.frmt_2_3=buf +psu_fru_pmbus.fpath_2_3=/sys/bus/i2c/devices/54-0060/mfr_serial +psu_fru_pmbus.addr_2_3=0 +psu_fru_pmbus.len_2_3=32 +psu_fru_pmbus.bit_offset_2_3= +psu_fru_pmbus.str_cons_2_3= + +# mfr_revision +psu_fru_pmbus.mode_2_5=config +psu_fru_pmbus.int_cons_2_5=0 +psu_fru_pmbus.src_2_5=file +psu_fru_pmbus.frmt_2_5=buf +psu_fru_pmbus.fpath_2_5=/sys/bus/i2c/devices/54-0060/mfr_revision +psu_fru_pmbus.addr_2_5=0 +psu_fru_pmbus.len_2_5=32 +psu_fru_pmbus.bit_offset_2_5= +psu_fru_pmbus.str_cons_2_5= + +# mfr_model +psu_fru_pmbus.mode_2_8=config +psu_fru_pmbus.int_cons_2_8=0 +psu_fru_pmbus.src_2_8=file +psu_fru_pmbus.frmt_2_8=buf +psu_fru_pmbus.fpath_2_8=/sys/bus/i2c/devices/54-0060/mfr_model +psu_fru_pmbus.addr_2_8=0 +psu_fru_pmbus.len_2_8=32 +psu_fru_pmbus.bit_offset_2_8= +psu_fru_pmbus.str_cons_2_8= + +# mfr_date +psu_fru_pmbus.mode_2_12=config +psu_fru_pmbus.int_cons_2_12=0 +psu_fru_pmbus.src_2_12=file +psu_fru_pmbus.frmt_2_12=buf +psu_fru_pmbus.fpath_2_12=/sys/bus/i2c/devices/54-0060/mfr_date +psu_fru_pmbus.addr_2_12=0 +psu_fru_pmbus.len_2_12=32 +psu_fru_pmbus.bit_offset_2_12= +psu_fru_pmbus.str_cons_2_12= + +# mfr_id +psu_fru_pmbus.mode_2_13=config +psu_fru_pmbus.int_cons_2_13=0 +psu_fru_pmbus.src_2_13=file +psu_fru_pmbus.frmt_2_13=buf +psu_fru_pmbus.fpath_2_13=/sys/bus/i2c/devices/54-0060/mfr_id +psu_fru_pmbus.addr_2_13=0 +psu_fru_pmbus.len_2_13=32 +psu_fru_pmbus.bit_offset_2_13= +psu_fru_pmbus.str_cons_2_13= + + +# mfr_serial +psu_fru_pmbus.mode_3_3=config +psu_fru_pmbus.int_cons_3_3=0 +psu_fru_pmbus.src_3_3=file +psu_fru_pmbus.frmt_3_3=buf +psu_fru_pmbus.fpath_3_3=/sys/bus/i2c/devices/55-0060/mfr_serial +psu_fru_pmbus.addr_3_3=0 +psu_fru_pmbus.len_3_3=32 +psu_fru_pmbus.bit_offset_3_3= +psu_fru_pmbus.str_cons_3_3= + +# mfr_revision +psu_fru_pmbus.mode_3_5=config +psu_fru_pmbus.int_cons_3_5=0 +psu_fru_pmbus.src_3_5=file +psu_fru_pmbus.frmt_3_5=buf +psu_fru_pmbus.fpath_3_5=/sys/bus/i2c/devices/55-0060/mfr_revision +psu_fru_pmbus.addr_3_5=0 +psu_fru_pmbus.len_3_5=32 +psu_fru_pmbus.bit_offset_3_5= +psu_fru_pmbus.str_cons_3_5= + +# mfr_model +psu_fru_pmbus.mode_3_8=config +psu_fru_pmbus.int_cons_3_8=0 +psu_fru_pmbus.src_3_8=file +psu_fru_pmbus.frmt_3_8=buf +psu_fru_pmbus.fpath_3_8=/sys/bus/i2c/devices/55-0060/mfr_model +psu_fru_pmbus.addr_3_8=0 +psu_fru_pmbus.len_3_8=32 +psu_fru_pmbus.bit_offset_3_8= +psu_fru_pmbus.str_cons_3_8= + +# mfr_date +psu_fru_pmbus.mode_3_12=config +psu_fru_pmbus.int_cons_3_12=0 +psu_fru_pmbus.src_3_12=file +psu_fru_pmbus.frmt_3_12=buf +psu_fru_pmbus.fpath_3_12=/sys/bus/i2c/devices/55-0060/mfr_date +psu_fru_pmbus.addr_3_12=0 +psu_fru_pmbus.len_3_12=32 +psu_fru_pmbus.bit_offset_3_12= +psu_fru_pmbus.str_cons_3_12= + +# mfr_id +psu_fru_pmbus.mode_3_13=config +psu_fru_pmbus.int_cons_3_13=0 +psu_fru_pmbus.src_3_13=file +psu_fru_pmbus.frmt_3_13=buf +psu_fru_pmbus.fpath_3_13=/sys/bus/i2c/devices/55-0060/mfr_id +psu_fru_pmbus.addr_3_13=0 +psu_fru_pmbus.len_3_13=32 +psu_fru_pmbus.bit_offset_3_13= +psu_fru_pmbus.str_cons_3_13= + + +# mfr_serial +psu_fru_pmbus.mode_4_3=config +psu_fru_pmbus.int_cons_4_3=0 +psu_fru_pmbus.src_4_3=file +psu_fru_pmbus.frmt_4_3=buf +psu_fru_pmbus.fpath_4_3=/sys/bus/i2c/devices/56-0060/mfr_serial +psu_fru_pmbus.addr_4_3=0 +psu_fru_pmbus.len_4_3=32 +psu_fru_pmbus.bit_offset_4_3= +psu_fru_pmbus.str_cons_4_3= + +# mfr_revision +psu_fru_pmbus.mode_4_5=config +psu_fru_pmbus.int_cons_4_5=0 +psu_fru_pmbus.src_4_5=file +psu_fru_pmbus.frmt_4_5=buf +psu_fru_pmbus.fpath_4_5=/sys/bus/i2c/devices/56-0060/mfr_revision +psu_fru_pmbus.addr_4_5=0 +psu_fru_pmbus.len_4_5=32 +psu_fru_pmbus.bit_offset_4_5= +psu_fru_pmbus.str_cons_4_5= + +# mfr_model +psu_fru_pmbus.mode_4_8=config +psu_fru_pmbus.int_cons_4_8=0 +psu_fru_pmbus.src_4_8=file +psu_fru_pmbus.frmt_4_8=buf +psu_fru_pmbus.fpath_4_8=/sys/bus/i2c/devices/56-0060/mfr_model +psu_fru_pmbus.addr_4_8=0 +psu_fru_pmbus.len_4_8=32 +psu_fru_pmbus.bit_offset_4_8= +psu_fru_pmbus.str_cons_4_8= + +# mfr_date +psu_fru_pmbus.mode_4_12=config +psu_fru_pmbus.int_cons_4_12=0 +psu_fru_pmbus.src_4_12=file +psu_fru_pmbus.frmt_4_12=buf +psu_fru_pmbus.fpath_4_12=/sys/bus/i2c/devices/56-0060/mfr_date +psu_fru_pmbus.addr_4_12=0 +psu_fru_pmbus.len_4_12=32 +psu_fru_pmbus.bit_offset_4_12= +psu_fru_pmbus.str_cons_4_12= + +# mfr_id +psu_fru_pmbus.mode_4_13=config +psu_fru_pmbus.int_cons_4_13=0 +psu_fru_pmbus.src_4_13=file +psu_fru_pmbus.frmt_4_13=buf +psu_fru_pmbus.fpath_4_13=/sys/bus/i2c/devices/56-0060/mfr_id +psu_fru_pmbus.addr_4_13=0 +psu_fru_pmbus.len_4_13=32 +psu_fru_pmbus.bit_offset_4_13= +psu_fru_pmbus.str_cons_4_13= + +# Configuration items: PSU PMBus information +# Description: Format other_i2c_dev_[main_dev]_[psu_index] +# Note: main_dev,PSU is 2, psu_index:Power supply number, start with 1 +other_i2c_dev.bus_2_1=53 +other_i2c_dev.addr_2_1=0x60 +other_i2c_dev.bus_2_2=54 +other_i2c_dev.addr_2_2=0x60 +other_i2c_dev.bus_2_3=55 +other_i2c_dev.addr_2_3=0x60 +other_i2c_dev.bus_2_4=56 +other_i2c_dev.addr_2_4=0x60 + +# Configuration items: PMBUS register address of the power supply +# Description: Format psu_status_[psu_index]_[reg_id] +# Note:psu_index:Power supply number,start with 1 reg_id, 9:Power Output Status (0x79) +psu_pmbus_reg.mode_1_9=config +psu_pmbus_reg.src_1_9=other_i2c +psu_pmbus_reg.frmt_1_9=byte +psu_pmbus_reg.pola_1_9=negative +psu_pmbus_reg.addr_1_9=0x02010079 +psu_pmbus_reg.len_1_9=2 +psu_pmbus_reg.bit_offset_1_9= + +psu_pmbus_reg.mode_2_9=config +psu_pmbus_reg.src_2_9=other_i2c +psu_pmbus_reg.frmt_2_9=byte +psu_pmbus_reg.pola_2_9=negative +psu_pmbus_reg.addr_2_9=0x02020079 +psu_pmbus_reg.len_2_9=2 +psu_pmbus_reg.bit_offset_2_9= + +psu_pmbus_reg.mode_3_9=config +psu_pmbus_reg.src_3_9=other_i2c +psu_pmbus_reg.frmt_3_9=byte +psu_pmbus_reg.pola_3_9=negative +psu_pmbus_reg.addr_3_9=0x02030079 +psu_pmbus_reg.len_3_9=2 +psu_pmbus_reg.bit_offset_3_9= + +psu_pmbus_reg.mode_4_9=config +psu_pmbus_reg.src_4_9=other_i2c +psu_pmbus_reg.frmt_4_9=byte +psu_pmbus_reg.pola_4_9=negative +psu_pmbus_reg.addr_4_9=0x02040079 +psu_pmbus_reg.len_4_9=2 +psu_pmbus_reg.bit_offset_4_9= + +# Configuration items:PMBUS register address of the power supply +# Description: Format psu_status_[psu_index]_[reg_id] +# Note:psu_index:Power supply number,start with 1 reg_id, 10:Power input Status (0x79) +psu_pmbus_reg.mode_1_10=config +psu_pmbus_reg.src_1_10=other_i2c +psu_pmbus_reg.frmt_1_10=byte +psu_pmbus_reg.pola_1_10=negative +psu_pmbus_reg.addr_1_10=0x02010079 +psu_pmbus_reg.len_1_10=2 +psu_pmbus_reg.bit_offset_1_10= + +psu_pmbus_reg.mode_2_10=config +psu_pmbus_reg.src_2_10=other_i2c +psu_pmbus_reg.frmt_2_10=byte +psu_pmbus_reg.pola_2_10=negative +psu_pmbus_reg.addr_2_10=0x02020079 +psu_pmbus_reg.len_2_10=2 +psu_pmbus_reg.bit_offset_2_10= + +psu_pmbus_reg.mode_3_10=config +psu_pmbus_reg.src_3_10=other_i2c +psu_pmbus_reg.frmt_3_10=byte +psu_pmbus_reg.pola_3_10=negative +psu_pmbus_reg.addr_3_10=0x02030079 +psu_pmbus_reg.len_3_10=2 +psu_pmbus_reg.bit_offset_3_10= + +psu_pmbus_reg.mode_4_10=config +psu_pmbus_reg.src_4_10=other_i2c +psu_pmbus_reg.frmt_4_10=byte +psu_pmbus_reg.pola_4_10=negative +psu_pmbus_reg.addr_4_10=0x02040079 +psu_pmbus_reg.len_4_10=2 +psu_pmbus_reg.bit_offset_4_10= + +# Configuration items:PMBUS register address of the power supply +# Description: Format psu_status_[psu_index]_[reg_id] +# Note:psu_index:Power supply number,,start with 1 reg_id 11:Power Input type (0x80) +psu_pmbus_reg.mode_1_11=constant +psu_pmbus_reg.int_cons_1_11=2 + +psu_pmbus_reg.mode_2_11=constant +psu_pmbus_reg.int_cons_2_11=2 + +psu_pmbus_reg.mode_3_11=constant +psu_pmbus_reg.int_cons_3_11=2 + +psu_pmbus_reg.mode_4_11=constant +psu_pmbus_reg.int_cons_4_11=2 + +# Configuration items: Input status of the power module +# Description: Format psu_pmbus_id_[psu_index]_[psu_sensor_type]=value +# Note: psu_index is Power supply number,start with 1, psu_sensor_type is PMBUS type,Input stateis 10 +# value value:bus[8]_addr[16]_offset[8] + +psu_pmbus_id_1_11=0x53006080 +psu_pmbus_id_2_11=0x54006080 +psu_pmbus_id_3_11=0x55006080 +psu_pmbus_id_4_11=0x56006080 + +# Configuration items: Input status of the power module +# Description: Format psu_pmbus_id_[psu_index]_[psu_sensor_type]=value +# Note: psu_index is Power supply number,start with 1, psu_sensor_type is PMBUS type,Input stateis 10 +# value value:bus[8]_addr[16]_offset[8] +# present +psu_status.mode_1_0=constant +psu_status.int_cons_1_0=1 + +# output +psu_status.mode_1_1=config +psu_status.src_1_1=logic_file +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.fpath_1_1=/dev/cpld1 +psu_status.addr_1_1=0xc7 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=0 + +# alert +psu_status.mode_1_2=config +psu_status.src_1_2=logic_file +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.fpath_1_2=/dev/cpld1 +psu_status.addr_1_2=0xc5 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=0 + +psu_status.mode_2_0=constant +psu_status.int_cons_2_0=1 + +psu_status.mode_2_1=config +psu_status.src_2_1=logic_file +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.fpath_2_1=/dev/cpld1 +psu_status.addr_2_1=0xc7 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=1 + +psu_status.mode_2_2=config +psu_status.src_2_2=logic_file +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.fpath_2_2=/dev/cpld1 +psu_status.addr_2_2=0xc5 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=1 + +psu_status.mode_3_0=constant +psu_status.int_cons_3_0=1 + +psu_status.mode_3_1=config +psu_status.src_3_1=logic_file +psu_status.frmt_3_1=bit +psu_status.pola_3_1=positive +psu_status.fpath_3_1=/dev/cpld1 +psu_status.addr_3_1=0xc7 +psu_status.len_3_1=1 +psu_status.bit_offset_3_1=2 + +psu_status.mode_3_2=config +psu_status.src_3_2=logic_file +psu_status.frmt_3_2=bit +psu_status.pola_3_2=negative +psu_status.fpath_3_2=/dev/cpld1 +psu_status.addr_3_2=0xc5 +psu_status.len_3_2=1 +psu_status.bit_offset_3_2=2 + +psu_status.mode_4_0=constant +psu_status.int_cons_4_0=1 + +psu_status.mode_4_1=config +psu_status.src_4_1=logic_file +psu_status.frmt_4_1=bit +psu_status.pola_4_1=positive +psu_status.fpath_4_1=/dev/cpld1 +psu_status.addr_4_1=0xc7 +psu_status.len_4_1=1 +psu_status.bit_offset_4_1=3 + +psu_status.mode_4_2=config +psu_status.src_4_2=logic_file +psu_status.frmt_4_2=bit +psu_status.pola_4_2=negative +psu_status.fpath_4_2=/dev/cpld1 +psu_status.addr_4_2=0xc5 +psu_status.len_4_2=1 +psu_status.bit_offset_4_2=3 + +# 0:None 1:in_vol 2:in_curr 3:in_power 4:out_vol 5:out_curr 6:out_power 7:fan +# psu1 in_vol +hwmon_psu.mode_1_1=config +hwmon_psu.int_cons_1_1=0 +hwmon_psu.src_1_1=file +hwmon_psu.frmt_1_1=buf +hwmon_psu.fpath_1_1=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_psu.addr_1_1=0 +hwmon_psu.len_1_1=8 +hwmon_psu.bit_offset_1_1= +hwmon_psu.str_cons_1_1=in1_input + +# psu1 in_curr +hwmon_psu.mode_1_2=config +hwmon_psu.int_cons_1_2=0 +hwmon_psu.src_1_2=file +hwmon_psu.frmt_1_2=buf +hwmon_psu.fpath_1_2=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_psu.addr_1_2=0 +hwmon_psu.len_1_2=8 +hwmon_psu.bit_offset_1_2= +hwmon_psu.str_cons_1_2=curr1_input + +# psu1 in_power +hwmon_psu.mode_1_3=config +hwmon_psu.int_cons_1_3=0 +hwmon_psu.src_1_3=file +hwmon_psu.frmt_1_3=buf +hwmon_psu.fpath_1_3=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_psu.addr_1_3=0 +hwmon_psu.len_1_3=16 +hwmon_psu.bit_offset_1_3=0 +hwmon_psu.str_cons_1_3=power1_input + +# psu1 out_vol +hwmon_psu.mode_1_4=config +hwmon_psu.int_cons_1_4=0 +hwmon_psu.src_1_4=file +hwmon_psu.frmt_1_4=buf +hwmon_psu.fpath_1_4=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_psu.addr_1_4=0 +hwmon_psu.len_1_4=8 +hwmon_psu.bit_offset_1_4= +hwmon_psu.str_cons_1_4=in2_input + +# psu1 out_curr +hwmon_psu.mode_1_5=config +hwmon_psu.int_cons_1_5=0 +hwmon_psu.src_1_5=file +hwmon_psu.frmt_1_5=buf +hwmon_psu.fpath_1_5=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_psu.addr_1_5=0 +hwmon_psu.len_1_5=8 +hwmon_psu.bit_offset_1_5= +hwmon_psu.str_cons_1_5=curr2_input + +# psu1 out_power +hwmon_psu.mode_1_6=config +hwmon_psu.int_cons_1_6=0 +hwmon_psu.src_1_6=file +hwmon_psu.frmt_1_6=buf +hwmon_psu.fpath_1_6=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_psu.addr_1_6=0 +hwmon_psu.len_1_6=16 +hwmon_psu.bit_offset_1_6=0 +hwmon_psu.str_cons_1_6=power2_input + +# psu2 in_vol +hwmon_psu.mode_2_1=config +hwmon_psu.int_cons_2_1=0 +hwmon_psu.src_2_1=file +hwmon_psu.frmt_2_1=buf +hwmon_psu.fpath_2_1=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_psu.addr_2_1=0 +hwmon_psu.len_2_1=8 +hwmon_psu.bit_offset_2_1= +hwmon_psu.str_cons_2_1=in1_input + +# psu2 in_curr +hwmon_psu.mode_2_2=config +hwmon_psu.int_cons_2_2=0 +hwmon_psu.src_2_2=file +hwmon_psu.frmt_2_2=buf +hwmon_psu.fpath_2_2=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_psu.addr_2_2=0 +hwmon_psu.len_2_2=8 +hwmon_psu.bit_offset_2_2= +hwmon_psu.str_cons_2_2=curr1_input + +# psu2 in_power +hwmon_psu.mode_2_3=config +hwmon_psu.int_cons_2_3=0 +hwmon_psu.src_2_3=file +hwmon_psu.frmt_2_3=buf +hwmon_psu.fpath_2_3=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_psu.addr_2_3=0 +hwmon_psu.len_2_3=16 +hwmon_psu.bit_offset_2_3=0 +hwmon_psu.str_cons_2_3=power1_input + +# psu2 out_vol +hwmon_psu.mode_2_4=config +hwmon_psu.int_cons_2_4=0 +hwmon_psu.src_2_4=file +hwmon_psu.frmt_2_4=buf +hwmon_psu.fpath_2_4=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_psu.addr_2_4=0 +hwmon_psu.len_2_4=8 +hwmon_psu.bit_offset_2_4= +hwmon_psu.str_cons_2_4=in2_input + +# psu2 out_curr +hwmon_psu.mode_2_5=config +hwmon_psu.int_cons_2_5=0 +hwmon_psu.src_2_5=file +hwmon_psu.frmt_2_5=buf +hwmon_psu.fpath_2_5=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_psu.addr_2_5=0 +hwmon_psu.len_2_5=8 +hwmon_psu.bit_offset_2_5= +hwmon_psu.str_cons_2_5=curr2_input + +# psu2 out_power +hwmon_psu.mode_2_6=config +hwmon_psu.int_cons_2_6=0 +hwmon_psu.src_2_6=file +hwmon_psu.frmt_2_6=buf +hwmon_psu.fpath_2_6=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_psu.addr_2_6=0 +hwmon_psu.len_2_6=16 +hwmon_psu.bit_offset_2_6=0 +hwmon_psu.str_cons_2_6=power2_input + +# psu3 in_vol +hwmon_psu.mode_3_1=config +hwmon_psu.int_cons_3_1=0 +hwmon_psu.src_3_1=file +hwmon_psu.frmt_3_1=buf +hwmon_psu.fpath_3_1=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_psu.addr_3_1=0 +hwmon_psu.len_3_1=8 +hwmon_psu.bit_offset_3_1= +hwmon_psu.str_cons_3_1=in1_input +# psu3 in_curr +hwmon_psu.mode_3_2=config +hwmon_psu.int_cons_3_2=0 +hwmon_psu.src_3_2=file +hwmon_psu.frmt_3_2=buf +hwmon_psu.fpath_3_2=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_psu.addr_3_2=0 +hwmon_psu.len_3_2=8 +hwmon_psu.bit_offset_3_2= +hwmon_psu.str_cons_3_2=curr1_input + +# psu3 in_power +hwmon_psu.mode_3_3=config +hwmon_psu.int_cons_3_3=0 +hwmon_psu.src_3_3=file +hwmon_psu.frmt_3_3=buf +hwmon_psu.fpath_3_3=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_psu.addr_3_3=0 +hwmon_psu.len_3_3=16 +hwmon_psu.bit_offset_3_3=0 +hwmon_psu.str_cons_3_3=power1_input + +# psu3 out_vol +hwmon_psu.mode_3_4=config +hwmon_psu.int_cons_3_4=0 +hwmon_psu.src_3_4=file +hwmon_psu.frmt_3_4=buf +hwmon_psu.fpath_3_4=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_psu.addr_3_4=0 +hwmon_psu.len_3_4=8 +hwmon_psu.bit_offset_3_4= +hwmon_psu.str_cons_3_4=in2_input + +# psu3 out_curr +hwmon_psu.mode_3_5=config +hwmon_psu.int_cons_3_5=0 +hwmon_psu.src_3_5=file +hwmon_psu.frmt_3_5=buf +hwmon_psu.fpath_3_5=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_psu.addr_3_5=0 +hwmon_psu.len_3_5=8 +hwmon_psu.bit_offset_3_5= +hwmon_psu.str_cons_3_5=curr2_input + +# psu3 out_power +hwmon_psu.mode_3_6=config +hwmon_psu.int_cons_3_6=0 +hwmon_psu.src_3_6=file +hwmon_psu.frmt_3_6=buf +hwmon_psu.fpath_3_6=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_psu.addr_3_6=0 +hwmon_psu.len_3_6=16 +hwmon_psu.bit_offset_3_6=0 +hwmon_psu.str_cons_3_6=power2_input + +# psu4 in_vol +hwmon_psu.mode_4_1=config +hwmon_psu.int_cons_4_1=0 +hwmon_psu.src_4_1=file +hwmon_psu.frmt_4_1=buf +hwmon_psu.fpath_4_1=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_psu.addr_4_1=0 +hwmon_psu.len_4_1=8 +hwmon_psu.bit_offset_4_1= +hwmon_psu.str_cons_4_1=in1_input +# psu4 in_curr +hwmon_psu.mode_4_2=config +hwmon_psu.int_cons_4_2=0 +hwmon_psu.src_4_2=file +hwmon_psu.frmt_4_2=buf +hwmon_psu.fpath_4_2=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_psu.addr_4_2=0 +hwmon_psu.len_4_2=8 +hwmon_psu.bit_offset_4_2= +hwmon_psu.str_cons_4_2=curr1_input + +# psu4 in_power +hwmon_psu.mode_4_3=config +hwmon_psu.int_cons_4_3=0 +hwmon_psu.src_4_3=file +hwmon_psu.frmt_4_3=buf +hwmon_psu.fpath_4_3=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_psu.addr_4_3=0 +hwmon_psu.len_4_3=16 +hwmon_psu.bit_offset_4_3=0 +hwmon_psu.str_cons_4_3=power1_input + +# psu4 out_vol +hwmon_psu.mode_4_4=config +hwmon_psu.int_cons_4_4=0 +hwmon_psu.src_4_4=file +hwmon_psu.frmt_4_4=buf +hwmon_psu.fpath_4_4=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_psu.addr_4_4=0 +hwmon_psu.len_4_4=8 +hwmon_psu.bit_offset_4_4= +hwmon_psu.str_cons_4_4=in2_input + +# psu4 out_curr +hwmon_psu.mode_4_5=config +hwmon_psu.int_cons_4_5=0 +hwmon_psu.src_4_5=file +hwmon_psu.frmt_4_5=buf +hwmon_psu.fpath_4_5=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_psu.addr_4_5=0 +hwmon_psu.len_4_5=8 +hwmon_psu.bit_offset_4_5= +hwmon_psu.str_cons_4_5=curr2_input + +# psu4 out_power +hwmon_psu.mode_4_6=config +hwmon_psu.int_cons_4_6=0 +hwmon_psu.src_4_6=file +hwmon_psu.frmt_4_6=buf +hwmon_psu.fpath_4_6=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_psu.addr_4_6=0 +hwmon_psu.len_4_6=16 +hwmon_psu.bit_offset_4_6=0 +hwmon_psu.str_cons_4_6=power2_input + +# Configuration item: temperature hwmon path +# Format: hwmon_temp[key1]_[key2] +# Note: key1: High 8bit indicates the index of the device, starting from 1; low 8bit indicates the temperature index, starting from 1 +# key2: High 4bit indicates the master device type, power supply is 5, low 4bit indicates the temperature type 0:input 1:alias +# 2:type 3:max 4:max_hyst 5:min 6:crit +# mode: str_constant takes the value of str_cons directly and config reads it in the way specified by src +# int_cons:N Original value /(10^N) +# fpath: indicates the first half of the hwmon path +# bit_offset: specifies the number of decimal places. If not configured, the original precision is retained +# str_cons: when mode is str_constant, its value is the result of reading, and when reading from a file, the name of the file being read + +# psu1 temp1 input +hwmon_temp.mode_0x0101_0x20=config +hwmon_temp.int_cons_0x0101_0x20=0 +hwmon_temp.src_0x0101_0x20=file +hwmon_temp.frmt_0x0101_0x20=buf +hwmon_temp.fpath_0x0101_0x20=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_temp.addr_0x0101_0x20=0 +hwmon_temp.len_0x0101_0x20=8 +hwmon_temp.bit_offset_0x0101_0x20= +hwmon_temp.str_cons_0x0101_0x20=temp1_input +# psu1 temp1 alias +hwmon_temp.mode_0x0101_0x21=str_constant +hwmon_temp.str_cons_0x0101_0x21=temp0 +# psu1 temp1 max +hwmon_temp.mode_0x0101_0x23=str_constant +hwmon_temp.str_cons_0x0101_0x23=125000 +# psu1 temp1 min +hwmon_temp.mode_0x0101_0x25=str_constant +hwmon_temp.str_cons_0x0101_0x25=-40000 +# psu1 temp1 high +hwmon_temp.mode_0x0101_0x29=str_constant +hwmon_temp.str_cons_0x0101_0x29=115000 +# psu1 temp1 low +hwmon_temp.mode_0x0101_0x2a=str_constant +hwmon_temp.str_cons_0x0101_0x2a=-20000 +# psu1 temp1 type +hwmon_temp.mode_0x0101_0x22=str_constant +hwmon_temp.str_cons_0x0101_0x22=psu_pmbus + +# psu1 temp2 input +hwmon_temp.mode_0x0102_0x20=config +hwmon_temp.int_cons_0x0102_0x20=0 +hwmon_temp.src_0x0102_0x20=file +hwmon_temp.frmt_0x0102_0x20=buf +hwmon_temp.fpath_0x0102_0x20=/sys/bus/i2c/devices/53-0060/hwmon/ +hwmon_temp.addr_0x0102_0x20=0 +hwmon_temp.len_0x0102_0x20=8 +hwmon_temp.bit_offset_0x0102_0x20= +hwmon_temp.str_cons_0x0102_0x20=temp2_input +# psu1 temp2 alias +hwmon_temp.mode_0x0102_0x21=str_constant +hwmon_temp.str_cons_0x0102_0x21=temp1 +# psu1 temp2 max +hwmon_temp.mode_0x0102_0x23=str_constant +hwmon_temp.str_cons_0x0102_0x23=125000 +# psu1 temp2 min +hwmon_temp.mode_0x0102_0x25=str_constant +hwmon_temp.str_cons_0x0102_0x25=-40000 +# psu1 temp2 high +hwmon_temp.mode_0x0102_0x29=str_constant +hwmon_temp.str_cons_0x0102_0x29=115000 +# psu1 temp2 low +hwmon_temp.mode_0x0102_0x2a=str_constant +hwmon_temp.str_cons_0x0102_0x2a=-20000 +# psu1 temp2 type +hwmon_temp.mode_0x0102_0x22=str_constant +hwmon_temp.str_cons_0x0102_0x22=psu_pmbus + +# psu2 temp1 input +hwmon_temp.mode_0x0201_0x20=config +hwmon_temp.int_cons_0x0201_0x20=0 +hwmon_temp.src_0x0201_0x20=file +hwmon_temp.frmt_0x0201_0x20=buf +hwmon_temp.fpath_0x0201_0x20=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_temp.addr_0x0201_0x20=0 +hwmon_temp.len_0x0201_0x20=8 +hwmon_temp.bit_offset_0x0201_0x20= +hwmon_temp.str_cons_0x0201_0x20=temp1_input +# psu2 temp1 alias +hwmon_temp.mode_0x0201_0x21=str_constant +hwmon_temp.str_cons_0x0201_0x21=temp0 +# psu2 temp1 max +hwmon_temp.mode_0x0201_0x23=str_constant +hwmon_temp.str_cons_0x0201_0x23=125000 +# psu2 temp1 min +hwmon_temp.mode_0x0201_0x25=str_constant +hwmon_temp.str_cons_0x0201_0x25=-40000 +# psu2 temp1 high +hwmon_temp.mode_0x0201_0x29=str_constant +hwmon_temp.str_cons_0x0201_0x29=115000 +# psu2 temp1 low +hwmon_temp.mode_0x0201_0x2a=str_constant +hwmon_temp.str_cons_0x0201_0x2a=-20000 +# psu2 temp1 type +hwmon_temp.mode_0x0201_0x22=str_constant +hwmon_temp.str_cons_0x0201_0x22=psu_pmbus + +# psu2 temp2 input +hwmon_temp.mode_0x0202_0x20=config +hwmon_temp.int_cons_0x0202_0x20=0 +hwmon_temp.src_0x0202_0x20=file +hwmon_temp.frmt_0x0202_0x20=buf +hwmon_temp.fpath_0x0202_0x20=/sys/bus/i2c/devices/54-0060/hwmon/ +hwmon_temp.addr_0x0202_0x20=0 +hwmon_temp.len_0x0202_0x20=8 +hwmon_temp.bit_offset_0x0202_0x20= +hwmon_temp.str_cons_0x0202_0x20=temp2_input +# psu2 temp2 alias +hwmon_temp.mode_0x0202_0x21=str_constant +hwmon_temp.str_cons_0x0202_0x21=temp1 +# psu2 temp2 max +hwmon_temp.mode_0x0202_0x23=str_constant +hwmon_temp.str_cons_0x0202_0x23=125000 +# psu2 temp2 min +hwmon_temp.mode_0x0202_0x25=str_constant +hwmon_temp.str_cons_0x0202_0x25=-40000 +# psu2 temp2 high +hwmon_temp.mode_0x0202_0x29=str_constant +hwmon_temp.str_cons_0x0202_0x29=115000 +# psu2 temp2 low +hwmon_temp.mode_0x0202_0x2a=str_constant +hwmon_temp.str_cons_0x0202_0x2a=-20000 +# psu2 temp2 type +hwmon_temp.mode_0x0202_0x22=str_constant +hwmon_temp.str_cons_0x0202_0x22=psu_pmbus + +# psu3 temp1 input +hwmon_temp.mode_0x0301_0x20=config +hwmon_temp.int_cons_0x0301_0x20=0 +hwmon_temp.src_0x0301_0x20=file +hwmon_temp.frmt_0x0301_0x20=buf +hwmon_temp.fpath_0x0301_0x20=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_temp.addr_0x0301_0x20=0 +hwmon_temp.len_0x0301_0x20=8 +hwmon_temp.bit_offset_0x0301_0x20= +hwmon_temp.str_cons_0x0301_0x20=temp1_input +# psu3 temp1 alias +hwmon_temp.mode_0x0301_0x21=str_constant +hwmon_temp.str_cons_0x0301_0x21=temp0 +# psu3 temp1 max +hwmon_temp.mode_0x0301_0x23=str_constant +hwmon_temp.str_cons_0x0301_0x23=125000 +# psu3 temp1 min +hwmon_temp.mode_0x0301_0x25=str_constant +hwmon_temp.str_cons_0x0301_0x25=-40000 +# psu3 temp1 high +hwmon_temp.mode_0x0301_0x29=str_constant +hwmon_temp.str_cons_0x0301_0x29=115000 +# psu3 temp1 low +hwmon_temp.mode_0x0301_0x2a=str_constant +hwmon_temp.str_cons_0x0301_0x2a=-20000 +# psu3 temp1 type +hwmon_temp.mode_0x0301_0x22=str_constant +hwmon_temp.str_cons_0x0301_0x22=psu_pmbus + +# psu3 temp2 input +hwmon_temp.mode_0x0302_0x20=config +hwmon_temp.int_cons_0x0302_0x20=0 +hwmon_temp.src_0x0302_0x20=file +hwmon_temp.frmt_0x0302_0x20=buf +hwmon_temp.fpath_0x0302_0x20=/sys/bus/i2c/devices/55-0060/hwmon/ +hwmon_temp.addr_0x0302_0x20=0 +hwmon_temp.len_0x0302_0x20=8 +hwmon_temp.bit_offset_0x0302_0x20= +hwmon_temp.str_cons_0x0302_0x20=temp2_input +# psu3 temp2 alias +hwmon_temp.mode_0x0302_0x21=str_constant +hwmon_temp.str_cons_0x0302_0x21=temp1 +# psu3 temp2 max +hwmon_temp.mode_0x0302_0x23=str_constant +hwmon_temp.str_cons_0x0302_0x23=125000 +# psu3 temp2 min +hwmon_temp.mode_0x0302_0x25=str_constant +hwmon_temp.str_cons_0x0302_0x25=-40000 +# psu3 temp2 high +hwmon_temp.mode_0x0302_0x29=str_constant +hwmon_temp.str_cons_0x0302_0x29=115000 +# psu3 temp2 low +hwmon_temp.mode_0x0302_0x2a=str_constant +hwmon_temp.str_cons_0x0302_0x2a=-20000 +# psu3 temp2 type +hwmon_temp.mode_0x0302_0x22=str_constant +hwmon_temp.str_cons_0x0302_0x22=psu_pmbus + +# psu4 temp1 input +hwmon_temp.mode_0x0401_0x20=config +hwmon_temp.int_cons_0x0401_0x20=0 +hwmon_temp.src_0x0401_0x20=file +hwmon_temp.frmt_0x0401_0x20=buf +hwmon_temp.fpath_0x0401_0x20=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_temp.addr_0x0401_0x20=0 +hwmon_temp.len_0x0401_0x20=8 +hwmon_temp.bit_offset_0x0401_0x20= +hwmon_temp.str_cons_0x0401_0x20=temp1_input +# psu4 temp1 alias +hwmon_temp.mode_0x0401_0x21=str_constant +hwmon_temp.str_cons_0x0401_0x21=temp0 +# psu4 temp1 max +hwmon_temp.mode_0x0401_0x23=str_constant +hwmon_temp.str_cons_0x0401_0x23=125000 +# psu4 temp1 min +hwmon_temp.mode_0x0401_0x25=str_constant +hwmon_temp.str_cons_0x0401_0x25=-40000 +# psu4 temp1 high +hwmon_temp.mode_0x0401_0x29=str_constant +hwmon_temp.str_cons_0x0401_0x29=115000 +# psu4 temp1 low +hwmon_temp.mode_0x0401_0x2a=str_constant +hwmon_temp.str_cons_0x0401_0x2a=-20000 +# psu4 temp1 type +hwmon_temp.mode_0x0401_0x22=str_constant +hwmon_temp.str_cons_0x0401_0x22=psu_pmbus + +# psu4 temp2 input +hwmon_temp.mode_0x0402_0x20=config +hwmon_temp.int_cons_0x0402_0x20=0 +hwmon_temp.src_0x0402_0x20=file +hwmon_temp.frmt_0x0402_0x20=buf +hwmon_temp.fpath_0x0402_0x20=/sys/bus/i2c/devices/56-0060/hwmon/ +hwmon_temp.addr_0x0402_0x20=0 +hwmon_temp.len_0x0402_0x20=8 +hwmon_temp.bit_offset_0x0402_0x20= +hwmon_temp.str_cons_0x0402_0x20=temp2_input +# psu4 temp2 alias +hwmon_temp.mode_0x0402_0x21=str_constant +hwmon_temp.str_cons_0x0402_0x21=temp1 +# psu4 temp2 max +hwmon_temp.mode_0x0402_0x23=str_constant +hwmon_temp.str_cons_0x0402_0x23=125000 +# psu4 temp2 min +hwmon_temp.mode_0x0402_0x25=str_constant +hwmon_temp.str_cons_0x0402_0x25=-40000 +# psu4 temp2 high +hwmon_temp.mode_0x0402_0x29=str_constant +hwmon_temp.str_cons_0x0402_0x29=115000 +# psu4 temp2 low +hwmon_temp.mode_0x0402_0x2a=str_constant +hwmon_temp.str_cons_0x0402_0x2a=-20000 +# psu4 temp2 type +hwmon_temp.mode_0x0402_0x22=str_constant +hwmon_temp.str_cons_0x0402_0x22=psu_pmbus + + +# Configuration item: The number of power supply names displayed by the product +# Format: dev_num_[main_dev]_[minor_dev] +# Note: main_dev,PSU is 2, minor_dev, 6: Number of power supply names displayed +dev_num_2_6=2 + +# Configuration item: rated power of power supply +# Fill in instructions: format power_rate_supply_[index] +# Note: index indicates the ID of the power supply that is displayed +power_rate_supply_1=1300000000 +power_rate_supply_2=1300000000 + +# Psu in voltage max min +hwmon_psu.mode_1_13=str_constant +hwmon_psu.str_cons_1_13=60000 +hwmon_psu.mode_1_15=str_constant +hwmon_psu.str_cons_1_15=40000 +# Psu in current max min +hwmon_psu.mode_1_14=str_constant +hwmon_psu.str_cons_1_14=24500 +hwmon_psu.mode_1_16=str_constant +hwmon_psu.str_cons_1_16=0 +# Psu out voltage max min +hwmon_psu.mode_1_17=str_constant +hwmon_psu.str_cons_1_17=13200 +hwmon_psu.mode_1_19=str_constant +hwmon_psu.str_cons_1_19=10800 +# Psu out current max min +hwmon_psu.mode_1_18=str_constant +hwmon_psu.str_cons_1_18=90000 +hwmon_psu.mode_1_20=str_constant +hwmon_psu.str_cons_1_20=0 +# Psu in power max min +hwmon_psu.mode_1_23=str_constant +hwmon_psu.str_cons_1_23=1320000000 +hwmon_psu.mode_1_24=str_constant +hwmon_psu.str_cons_1_24=10000 +# Psu out power max min +hwmon_psu.mode_1_25=str_constant +hwmon_psu.str_cons_1_25=1200000000 +hwmon_psu.mode_1_26=str_constant +hwmon_psu.str_cons_1_26=10000 + +# Psu in voltage max min +hwmon_psu.mode_2_13=str_constant +hwmon_psu.str_cons_2_13=60000 +hwmon_psu.mode_2_15=str_constant +hwmon_psu.str_cons_2_15=40000 +# Psu in current max min +hwmon_psu.mode_2_14=str_constant +hwmon_psu.str_cons_2_14=24500 +hwmon_psu.mode_2_16=str_constant +hwmon_psu.str_cons_2_16=0 +# Psu out voltage max min +hwmon_psu.mode_2_17=str_constant +hwmon_psu.str_cons_2_17=13200 +hwmon_psu.mode_2_19=str_constant +hwmon_psu.str_cons_2_19=10800 +# Psu out current max min +hwmon_psu.mode_2_18=str_constant +hwmon_psu.str_cons_2_18=90000 +hwmon_psu.mode_2_20=str_constant +hwmon_psu.str_cons_2_20=0 +# Psu in power max min +hwmon_psu.mode_2_23=str_constant +hwmon_psu.str_cons_2_23=1320000000 +hwmon_psu.mode_2_24=str_constant +hwmon_psu.str_cons_2_24=10000 +# Psu out power max min +hwmon_psu.mode_2_25=str_constant +hwmon_psu.str_cons_2_25=1200000000 +hwmon_psu.mode_2_26=str_constant +hwmon_psu.str_cons_2_26=10000 + +# Psu in voltage max min +hwmon_psu.mode_3_13=str_constant +hwmon_psu.str_cons_3_13=60000 +hwmon_psu.mode_3_15=str_constant +hwmon_psu.str_cons_3_15=40000 +# Psu in current max min +hwmon_psu.mode_3_14=str_constant +hwmon_psu.str_cons_3_14=24500 +hwmon_psu.mode_3_16=str_constant +hwmon_psu.str_cons_3_16=0 +# Psu out voltage max min +hwmon_psu.mode_3_17=str_constant +hwmon_psu.str_cons_3_17=13200 +hwmon_psu.mode_3_19=str_constant +hwmon_psu.str_cons_3_19=10800 +# Psu out current max min +hwmon_psu.mode_3_18=str_constant +hwmon_psu.str_cons_3_18=90000 +hwmon_psu.mode_3_20=str_constant +hwmon_psu.str_cons_3_20=0 +# Psu in power max min +hwmon_psu.mode_3_23=str_constant +hwmon_psu.str_cons_3_23=1320000000 +hwmon_psu.mode_3_24=str_constant +hwmon_psu.str_cons_3_24=10000 +# Psu out power max min +hwmon_psu.mode_3_25=str_constant +hwmon_psu.str_cons_3_25=1200000000 +hwmon_psu.mode_3_26=str_constant +hwmon_psu.str_cons_3_26=10000 + +# blackbox info path +psu_blackbox_path_1=/proc/psu/53-0060/blackbox_info +psu_blackbox_path_2=/proc/psu/54-0060/blackbox_info +psu_blackbox_path_3=/proc/psu/55-0060/blackbox_info +psu_blackbox_path_4=/proc/psu/56-0060/blackbox_info + +# pmbus info +psu_pmbus_info_1=/sys/bus/i2c/devices/53-0060/pmbus_info +psu_pmbus_info_2=/sys/bus/i2c/devices/54-0060/pmbus_info +psu_pmbus_info_3=/sys/bus/i2c/devices/55-0060/pmbus_info +psu_pmbus_info_3=/sys/bus/i2c/devices/56-0060/pmbus_info + +psu_pmbus_addr_1 = 0x00350060 +psu_pmbus_addr_2 = 0x00360060 +psu_pmbus_addr_3 = 0x00370060 +psu_pmbus_addr_4 = 0x00380060 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg new file mode 100644 index 0000000000..37580dd877 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SENSOR.cfg @@ -0,0 +1,3769 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration item: Temperature hwmon path +# Description: Format hwmon_temp[key1]_[key2] +# Note: key1: A high 8bit indicates the device index starting from 1. A low 8bit indicates the temperature index starting from 1 +# key2:The high 4bit indicates the main device type, the sub-card is 5, and the low 4bit indicates the temperature type 0:input 1:alias +# 2:type 3:max 4:max_hyst 5:min 6:crit +# mode: str_constant takes the value of str_cons directly, and config reads it in the way specified by src +# int_cons:N raw value/(10^N) +# fpath:hwmon first half of the path +# bit_offset: Number of decimal places, retain original precision if not configured +# str_cons:if mode is str_constant,the value is result of read,if read from file the value is read file name. + +# temperature sensor number +dev_num_0_1=24 + +# voltage sensors number +dev_num_0_2=121 + +# current sensors number +dev_num_0_3=30 + + +# value : 0 +# alias : 1 +# type : 2 +# max : 3 +# hyst : 4 +# min : 5 +# crit : 6 +# range : 7 +# nominal_value : 8 +# high : 9 +# low : 10 + +# sensor temp1 input +hwmon_temp.mode_0x0001_0x00=config +hwmon_temp.int_cons_0x0001_0x00=0 +hwmon_temp.src_0x0001_0x00=file +hwmon_temp.frmt_0x0001_0x00=buf +hwmon_temp.fpath_0x0001_0x00=/sys/devices/pci0000:00/0000:00:18.3/hwmon/ +hwmon_temp.addr_0x0001_0x00=0 +hwmon_temp.len_0x0001_0x00=8 +hwmon_temp.bit_offset_0x0001_0x00= +hwmon_temp.str_cons_0x0001_0x00=temp1_input +# sensor temp1 alias +hwmon_temp.mode_0x0001_0x01=config +hwmon_temp.int_cons_0x0001_0x01= +hwmon_temp.src_0x0001_0x01=file +hwmon_temp.frmt_0x0001_0x01=buf +hwmon_temp.fpath_0x0001_0x01=/sys/devices/pci0000:00/0000:00:18.3/hwmon/ +hwmon_temp.addr_0x0001_0x01=0 +hwmon_temp.len_0x0001_0x01=16 +hwmon_temp.bit_offset_0x0001_0x01= +hwmon_temp.str_cons_0x0001_0x01=temp1_label +# sensor temp1 type +hwmon_temp.mode_0x0001_0x02=str_constant +hwmon_temp.str_cons_0x0001_0x02=cpu +# sensor temp1 max +hwmon_temp.mode_0x0001_0x03=str_constant +hwmon_temp.str_cons_0x0001_0x03=99000 +# sensor temp1 min +hwmon_temp.mode_0x0001_0x05=str_constant +hwmon_temp.str_cons_0x0001_0x05=-30000 + +# sensor temp2 input +hwmon_temp.mode_0x0002_0x00=config +hwmon_temp.int_cons_0x0002_0x00=0 +hwmon_temp.src_0x0002_0x00=file +hwmon_temp.frmt_0x0002_0x00=buf +hwmon_temp.fpath_0x0002_0x00=/sys/bus/i2c/devices/65-004b/hwmon/ +hwmon_temp.addr_0x0002_0x00=0 +hwmon_temp.len_0x0002_0x00=8 +hwmon_temp.bit_offset_0x0002_0x00= +hwmon_temp.str_cons_0x0002_0x00=temp1_input +# sensor temp2 alias +hwmon_temp.mode_0x0002_0x01=str_constant +hwmon_temp.str_cons_0x0002_0x01=FAN_CT75_01 +# sensor temp2 type +hwmon_temp.mode_0x0002_0x02=str_constant +hwmon_temp.str_cons_0x0002_0x02=lm75 +# sensor temp2 max +hwmon_temp.mode_0x0002_0x03=str_constant +hwmon_temp.str_cons_0x0002_0x03=75000 +# sensor temp2 min +hwmon_temp.mode_0x0002_0x05=str_constant +hwmon_temp.str_cons_0x0002_0x05=-30000 + +# sensor temp3 input +hwmon_temp.mode_0x0003_0x00=config +hwmon_temp.int_cons_0x0003_0x00=0 +hwmon_temp.src_0x0003_0x00=file +hwmon_temp.frmt_0x0003_0x00=buf +hwmon_temp.fpath_0x0003_0x00=/sys/bus/i2c/devices/66-004e/hwmon/ +hwmon_temp.addr_0x0003_0x00=0 +hwmon_temp.len_0x0003_0x00=8 +hwmon_temp.bit_offset_0x0003_0x00= +hwmon_temp.str_cons_0x0003_0x00=temp1_input +# sensor temp3 alias +hwmon_temp.mode_0x0003_0x01=str_constant +hwmon_temp.str_cons_0x0003_0x01=FAN_CT75_02 +# sensor temp3 type +hwmon_temp.mode_0x0003_0x02=str_constant +hwmon_temp.str_cons_0x0003_0x02=lm75 +# sensor temp3 max +hwmon_temp.mode_0x0003_0x03=str_constant +hwmon_temp.str_cons_0x0003_0x03=75000 +# sensor temp3 min +hwmon_temp.mode_0x0003_0x05=str_constant +hwmon_temp.str_cons_0x0003_0x05=-30000 + +# sensor temp4 input +hwmon_temp.mode_0x0004_0x00=config +hwmon_temp.int_cons_0x0004_0x00=0 +hwmon_temp.src_0x0004_0x00=file +hwmon_temp.frmt_0x0004_0x00=buf +hwmon_temp.fpath_0x0004_0x00=/sys/bus/i2c/devices/76-004b/hwmon/ +hwmon_temp.addr_0x0004_0x00=0 +hwmon_temp.len_0x0004_0x00=8 +hwmon_temp.bit_offset_0x0004_0x00= +hwmon_temp.str_cons_0x0004_0x00=temp1_input +# sensor temp4 alias +hwmon_temp.mode_0x0004_0x01=str_constant +hwmon_temp.str_cons_0x0004_0x01=MAC_CT75_05 +# sensor temp4 type +hwmon_temp.mode_0x0004_0x02=str_constant +hwmon_temp.str_cons_0x0004_0x02=lm75 +# sensor temp4 max +hwmon_temp.mode_0x0004_0x03=str_constant +hwmon_temp.str_cons_0x0004_0x03=75000 +# sensor temp4 min +hwmon_temp.mode_0x0004_0x05=str_constant +hwmon_temp.str_cons_0x0004_0x05=-30000 + +# sensor temp5 input +hwmon_temp.mode_0x0005_0x00=config +hwmon_temp.int_cons_0x0005_0x00=0 +hwmon_temp.src_0x0005_0x00=file +hwmon_temp.frmt_0x0005_0x00=buf +hwmon_temp.fpath_0x0005_0x00=/sys/bus/i2c/devices/77-004f/hwmon/ +hwmon_temp.addr_0x0005_0x00=0 +hwmon_temp.len_0x0005_0x00=8 +hwmon_temp.bit_offset_0x0005_0x00= +hwmon_temp.str_cons_0x0005_0x00=temp1_input +# sensor temp5 alias +hwmon_temp.mode_0x0005_0x01=str_constant +hwmon_temp.str_cons_0x0005_0x01=MAC_CT75_06 +# sensor temp5 type +hwmon_temp.mode_0x0005_0x02=str_constant +hwmon_temp.str_cons_0x0005_0x02=lm75 +# sensor temp5 max +hwmon_temp.mode_0x0005_0x03=str_constant +hwmon_temp.str_cons_0x0005_0x03=100000 +# sensor temp5 min +hwmon_temp.mode_0x0005_0x05=str_constant +hwmon_temp.str_cons_0x0005_0x05=-30000 + +# sensor temp6 input +hwmon_temp.mode_0x0006_0x00=config +hwmon_temp.int_cons_0x0006_0x00=0 +hwmon_temp.src_0x0006_0x00=file +hwmon_temp.frmt_0x0006_0x00=buf +hwmon_temp.fpath_0x0006_0x00=/sys/bus/i2c/devices/78-004c/hwmon/ +hwmon_temp.addr_0x0006_0x00=0 +hwmon_temp.len_0x0006_0x00=8 +hwmon_temp.bit_offset_0x0006_0x00= +hwmon_temp.str_cons_0x0006_0x00=temp1_input +# sensor temp6 alias +hwmon_temp.mode_0x0006_0x01=str_constant +hwmon_temp.str_cons_0x0006_0x01=MAC_CT7318MMR_01 +# sensor temp6 type +hwmon_temp.mode_0x0006_0x02=str_constant +hwmon_temp.str_cons_0x0006_0x02=ct7318 +# sensor temp6 max +hwmon_temp.mode_0x0006_0x03=str_constant +hwmon_temp.str_cons_0x0006_0x03=105000 +# sensor temp6 min +hwmon_temp.mode_0x0006_0x05=str_constant +hwmon_temp.str_cons_0x0006_0x05=-30000 + +# sensor temp7 input +hwmon_temp.mode_0x0007_0x00=config +hwmon_temp.int_cons_0x0007_0x00=0 +hwmon_temp.src_0x0007_0x00=file +hwmon_temp.frmt_0x0007_0x00=buf +hwmon_temp.fpath_0x0007_0x00=/sys/bus/i2c/devices/79-004c/hwmon/ +hwmon_temp.addr_0x0007_0x00=0 +hwmon_temp.len_0x0007_0x00=8 +hwmon_temp.bit_offset_0x0007_0x00= +hwmon_temp.str_cons_0x0007_0x00=temp1_input +# sensor temp7 alias +hwmon_temp.mode_0x0007_0x01=str_constant +hwmon_temp.str_cons_0x0007_0x01=MAC_CT7318MMR_02 +# sensor temp7 type +hwmon_temp.mode_0x0007_0x02=str_constant +hwmon_temp.str_cons_0x0007_0x02=ct7318 +# sensor temp7 max +hwmon_temp.mode_0x0007_0x03=str_constant +hwmon_temp.str_cons_0x0007_0x03=105000 +# sensor temp7 min +hwmon_temp.mode_0x0007_0x05=str_constant +hwmon_temp.str_cons_0x0007_0x05=-30000 + +# sensor temp8 input +hwmon_temp.mode_0x0008_0x00=config +hwmon_temp.int_cons_0x0008_0x00=0 +hwmon_temp.src_0x0008_0x00=file +hwmon_temp.frmt_0x0008_0x00=buf +hwmon_temp.fpath_0x0008_0x00=/sys/bus/i2c/devices/80-004c/hwmon/ +hwmon_temp.addr_0x0008_0x00=0 +hwmon_temp.len_0x0008_0x00=8 +hwmon_temp.bit_offset_0x0008_0x00= +hwmon_temp.str_cons_0x0008_0x00=temp1_input +# sensor temp8 alias +hwmon_temp.mode_0x0008_0x01=str_constant +hwmon_temp.str_cons_0x0008_0x01=MAC_CT7318MMR_03 +# sensor temp8 type +hwmon_temp.mode_0x0008_0x02=str_constant +hwmon_temp.str_cons_0x0008_0x02=ct7318 +# sensor temp8 max +hwmon_temp.mode_0x0008_0x03=str_constant +hwmon_temp.str_cons_0x0008_0x03=105000 +# sensor temp8 min +hwmon_temp.mode_0x0008_0x05=str_constant +hwmon_temp.str_cons_0x0008_0x05=-30000 + +# temp9 mac_temp_min +hwmon_temp.mode_0x0009_0x00=config +hwmon_temp.src_0x0009_0x00=cpld +hwmon_temp.addr_0x0009_0x00=0x000200e8 +hwmon_temp.frmt_0x0009_0x00=num_bytes +hwmon_temp.len_0x00009_0x00=2 +hwmon_temp.pola_0x0009_0x00=positive +hwmon_temp.str_cons_0x0009_0x00=temp0_input +hwmon_temp.int_extra1_0x0009_0x00=6 + +hwmon_temp.mode_0x0009_0x01=str_constant +hwmon_temp.str_cons_0x0009_0x01=MAC_TEMP_MIN + +hwmon_temp.mode_0x0009_0x02=str_constant +hwmon_temp.str_cons_0x0009_0x02=CPLD + +hwmon_temp.mode_0x0009_0x03=constant +hwmon_temp.int_cons_0x0009_0x03=105000 + +hwmon_temp.mode_0x0009_0x05=constant +hwmon_temp.int_cons_0x0009_0x05=-30000 + +#temp10 mac_temp_max +hwmon_temp.mode_0x000a_0x00=config +hwmon_temp.src_0x000a_0x00=cpld +hwmon_temp.addr_0x000a_0x00=0x000200ea +hwmon_temp.frmt_0x000a_0x00=num_bytes +hwmon_temp.len_0x000a_0x00=2 +hwmon_temp.pola_0x000a_0x00=positive +hwmon_temp.str_cons_0x000a_0x00=temp1_input +hwmon_temp.int_extra1_0x000a_0x00=6 + +hwmon_temp.mode_0x000a_0x01=str_constant +hwmon_temp.str_cons_0x000a_0x01=MAC_TEMP_MAX + +hwmon_temp.mode_0x000a_0x02=str_constant +hwmon_temp.str_cons_0x000a_0x02=CPLD + +hwmon_temp.mode_0x000a_0x03=constant +hwmon_temp.int_cons_0x000a_0x03=105000 + +hwmon_temp.mode_0x000a_0x05=constant +hwmon_temp.int_cons_0x000a_0x05=-30000 + +# sensor temp11 output +hwmon_temp.mode_0x000b_0x00=config +hwmon_temp.int_cons_0x000b_0x00=0 +hwmon_temp.src_0x000b_0x00=file +hwmon_temp.frmt_0x000b_0x00=buf +hwmon_temp.fpath_0x000b_0x00=/sys/bus/i2c/devices/85-0060/hwmon/ +hwmon_temp.addr_0x000b_0x00=0 +hwmon_temp.len_0x000b_0x00=8 +hwmon_temp.bit_offset_0x000b_0x00= +hwmon_temp.str_cons_0x000b_0x00=temp1_input +# sensor temp11 alias +hwmon_temp.mode_0x000b_0x01=str_constant +hwmon_temp.str_cons_0x000b_0x01=TMOS_CORE_TEMP_01 +# sensor temp11 type +hwmon_temp.mode_0x000b_0x02=str_constant +hwmon_temp.str_cons_0x000b_0x02=xdpe132g5c +# sensor temp11 min +hwmon_temp.mode_0x000b_0x05=str_constant +hwmon_temp.str_cons_0x000b_0x05=-30000 +# sensor temp11 max +hwmon_temp.mode_0x000b_0x03=str_constant +hwmon_temp.str_cons_0x000b_0x03=125000 + +# temp12 input +hwmon_temp.mode_0x000c_0x00=config +hwmon_temp.int_cons_0x000c_0x00=0 +hwmon_temp.src_0x000c_0x00=file +hwmon_temp.frmt_0x000c_0x00=buf +hwmon_temp.fpath_0x000c_0x00=/sys/bus/i2c/devices/85-0062/hwmon/ +hwmon_temp.addr_0x000c_0x00=0 +hwmon_temp.len_0x000c_0x00=8 +hwmon_temp.bit_offset_0x000c_0x00= +hwmon_temp.str_cons_0x000c_0x00=temp1_input +# sensor temp12 alias +hwmon_temp.mode_0x000c_0x01=str_constant +hwmon_temp.str_cons_0x000c_0x01=TMOS_CORE_TEMP_02 +# sensor temp12 type +hwmon_temp.mode_0x000c_0x02=str_constant +hwmon_temp.str_cons_0x000c_0x02=xdpe12284c +# sensor temp12 min +hwmon_temp.mode_0x000c_0x05=str_constant +hwmon_temp.str_cons_0x000c_0x05=-30000 +# sensor temp12 max +hwmon_temp.mode_0x000c_0x03=str_constant +hwmon_temp.str_cons_0x000c_0x03=125000 + +# temp13 board +hwmon_temp.mode_0x000d_0x00=config +hwmon_temp.int_cons_0x000d_0x00=0 +hwmon_temp.src_0x000d_0x00=file +hwmon_temp.frmt_0x000d_0x00=buf +hwmon_temp.fpath_0x000d_0x00=/sys/bus/i2c/devices/85-0074/hwmon/ +hwmon_temp.addr_0x000d_0x00=0 +hwmon_temp.len_0x000d_0x00=8 +hwmon_temp.bit_offset_0x000d_0x00= +hwmon_temp.str_cons_0x000d_0x00=temp1_input +# sensor temp13 alias +hwmon_temp.mode_0x000d_0x01=str_constant +hwmon_temp.str_cons_0x000d_0x01=TMOS_CORE_TEMP_03 +# sensor temp13 type +hwmon_temp.mode_0x000d_0x02=str_constant +hwmon_temp.str_cons_0x000d_0x02=xdpe12284c +# sensor temp13 min +hwmon_temp.mode_0x000d_0x05=str_constant +hwmon_temp.str_cons_0x000d_0x05=-30000 +# sensor temp13 max +hwmon_temp.mode_0x000d_0x03=str_constant +hwmon_temp.str_cons_0x000d_0x03=125000 + +# temp14 input +hwmon_temp.mode_0x000e_0x00=config +hwmon_temp.int_cons_0x000e_0x00=0 +hwmon_temp.src_0x000e_0x00=file +hwmon_temp.frmt_0x000e_0x00=buf +hwmon_temp.fpath_0x000e_0x00=/sys/bus/i2c/devices/87-0062/hwmon/ +hwmon_temp.addr_0x000e_0x00=0 +hwmon_temp.len_0x000e_0x00=8 +hwmon_temp.bit_offset_0x000e_0x00= +hwmon_temp.str_cons_0x000e_0x00=temp1_input +# sensor temp14 alias +hwmon_temp.mode_0x000e_0x01=str_constant +hwmon_temp.str_cons_0x000e_0x01=TMOS_CORE_TEMP_04 +# sensor temp14 type +hwmon_temp.mode_0x000e_0x02=str_constant +hwmon_temp.str_cons_0x000e_0x02=xdpe12284c +# sensor temp14 min +hwmon_temp.mode_0x000e_0x05=str_constant +hwmon_temp.str_cons_0x000e_0x05=-30000 +# sensor temp14 max +hwmon_temp.mode_0x000e_0x03=str_constant +hwmon_temp.str_cons_0x000e_0x03=125000 + +# temp15 input +hwmon_temp.mode_0x000f_0x00=config +hwmon_temp.int_cons_0x000f_0x00=0 +hwmon_temp.src_0x000f_0x00=file +hwmon_temp.frmt_0x000f_0x00=buf +hwmon_temp.fpath_0x000f_0x00=/sys/bus/i2c/devices/87-0060/hwmon/ +hwmon_temp.addr_0x000f_0x00=0 +hwmon_temp.len_0x000f_0x00=8 +hwmon_temp.bit_offset_0x000f_0x00= +hwmon_temp.str_cons_0x000f_0x00=temp1_input +# sensor temp15 alias +hwmon_temp.mode_0x000f_0x01=str_constant +hwmon_temp.str_cons_0x000f_0x01=TMOS_CORE_TEMP_05 +# sensor temp15 type +hwmon_temp.mode_0x000f_0x02=str_constant +hwmon_temp.str_cons_0x000f_0x02=xdpe12284c +# sensor temp15 min +hwmon_temp.mode_0x000f_0x05=str_constant +hwmon_temp.str_cons_0x000f_0x05=-30000 +# sensor temp15 max +hwmon_temp.mode_0x000f_0x03=str_constant +hwmon_temp.str_cons_0x000f_0x03=125000 + +# temp16 input +hwmon_temp.mode_0x0010_0x00=config +hwmon_temp.int_cons_0x0010_0x00=0 +hwmon_temp.src_0x0010_0x00=file +hwmon_temp.frmt_0x0010_0x00=buf +hwmon_temp.fpath_0x0010_0x00=/sys/bus/i2c/devices/87-0074/hwmon/ +hwmon_temp.addr_0x0010_0x00=0 +hwmon_temp.len_0x0010_0x00=8 +hwmon_temp.bit_offset_0x0010_0x00= +hwmon_temp.str_cons_0x0010_0x00=temp1_input +# sensor temp16 alias +hwmon_temp.mode_0x0010_0x01=str_constant +hwmon_temp.str_cons_0x0010_0x01=TMOS_CORE_TEMP_06 +# sensor temp16 type +hwmon_temp.mode_0x0010_0x02=str_constant +hwmon_temp.str_cons_0x0010_0x02=xdpe12284c +# sensor temp16 min +hwmon_temp.mode_0x0010_0x05=str_constant +hwmon_temp.str_cons_0x0010_0x05=-30000 +# sensor temp16 max +hwmon_temp.mode_0x0010_0x03=str_constant +hwmon_temp.str_cons_0x0010_0x03=125000 + +# temp17 TMOS_CORE_TEMP_07 +hwmon_temp.mode_0x0011_0x00=config +hwmon_temp.int_cons_0x0011_0x00=0 +hwmon_temp.src_0x0011_0x00=file +hwmon_temp.frmt_0x0011_0x00=buf +hwmon_temp.fpath_0x0011_0x00=/sys/bus/i2c/devices/89-0060/hwmon/ +hwmon_temp.addr_0x0011_0x00=0 +hwmon_temp.len_0x0011_0x00=8 +hwmon_temp.bit_offset_0x0011_0x00= +hwmon_temp.str_cons_0x0011_0x00=temp1_input + +hwmon_temp.mode_0x0011_0x01=str_constant +hwmon_temp.str_cons_0x0011_0x01=TMOS_CORE_TEMP_07 + +hwmon_temp.mode_0x0011_0x02=str_constant +hwmon_temp.str_cons_0x0011_0x02=xdpe12284c + +hwmon_temp.mode_0x0011_0x03=constant +hwmon_temp.int_cons_0x0011_0x03=125000 + +hwmon_temp.mode_0x0011_0x05=constant +hwmon_temp.int_cons_0x0011_0x05=-30000 + +#temp18 TMOS_CORE_TEMP_08 +hwmon_temp.mode_0x0012_0x00=config +hwmon_temp.int_cons_0x0012_0x00=0 +hwmon_temp.src_0x0012_0x00=file +hwmon_temp.frmt_0x0012_0x00=buf +hwmon_temp.fpath_0x0012_0x00=/sys/bus/i2c/devices/89-0074/hwmon/ +hwmon_temp.addr_0x0012_0x00=0 +hwmon_temp.len_0x0012_0x00=8 +hwmon_temp.bit_offset_0x0012_0x00= +hwmon_temp.str_cons_0x0012_0x00=temp1_input + +hwmon_temp.mode_0x0012_0x01=str_constant +hwmon_temp.str_cons_0x0012_0x01=TMOS_CORE_TEMP_08 + +hwmon_temp.mode_0x0012_0x02=str_constant +hwmon_temp.str_cons_0x0012_0x02=xdpe12284c + +hwmon_temp.mode_0x0012_0x03=constant +hwmon_temp.int_cons_0x0012_0x03=125000 + +hwmon_temp.mode_0x0012_0x05=constant +hwmon_temp.int_cons_0x0012_0x05=-30000 + +# temp19 +hwmon_temp.mode_0x0013_0x00=config +hwmon_temp.int_cons_0x0013_0x00=0 +hwmon_temp.src_0x0013_0x00=file +hwmon_temp.frmt_0x0013_0x00=buf +hwmon_temp.fpath_0x0013_0x00=/sys/bus/i2c/devices/90-0060/hwmon/ +hwmon_temp.addr_0x0013_0x00=0 +hwmon_temp.len_0x0013_0x00=8 +hwmon_temp.bit_offset_0x0013_0x00= +hwmon_temp.str_cons_0x0013_0x00=temp1_input +# sensor temp19 alias +hwmon_temp.mode_0x0013_0x01=str_constant +hwmon_temp.str_cons_0x0013_0x01=TMOS_CORE_TEMP_09 +# sensor temp19 type +hwmon_temp.mode_0x0013_0x02=str_constant +hwmon_temp.str_cons_0x0013_0x02=xdpe12284c +# sensor temp19 max +hwmon_temp.mode_0x0013_0x03=str_constant +hwmon_temp.str_cons_0x0013_0x03=125000 +# sensor temp19 min +hwmon_temp.mode_0x0013_0x05=str_constant +hwmon_temp.str_cons_0x0013_0x05=-30000 + +# temp20 +hwmon_temp.mode_0x0014_0x00=config +hwmon_temp.int_cons_0x0014_0x00=0 +hwmon_temp.src_0x0014_0x00=file +hwmon_temp.frmt_0x0014_0x00=buf +hwmon_temp.fpath_0x0014_0x00=/sys/bus/i2c/devices/91-0060/hwmon/ +hwmon_temp.addr_0x0014_0x00=0 +hwmon_temp.len_0x0014_0x00=8 +hwmon_temp.bit_offset_0x0014_0x00= +hwmon_temp.str_cons_0x0014_0x00=temp1_input +# sensor temp20 alias +hwmon_temp.mode_0x0014_0x01=str_constant +hwmon_temp.str_cons_0x0014_0x01=TMOS_CORE_TEMP_10 +# sensor temp20 type +hwmon_temp.mode_0x0014_0x02=str_constant +hwmon_temp.str_cons_0x0014_0x02=xdpe12284c +# sensor temp20 max +hwmon_temp.mode_0x0014_0x03=str_constant +hwmon_temp.str_cons_0x0014_0x03=125000 +# sensor temp20 min +hwmon_temp.mode_0x0014_0x05=str_constant +hwmon_temp.str_cons_0x0014_0x05=-30000 + +# temp21 TMOS_CORE_TEMP_11 +hwmon_temp.mode_0x0015_0x00=config +hwmon_temp.int_cons_0x0015_0x00=0 +hwmon_temp.src_0x0015_0x00=file +hwmon_temp.frmt_0x0015_0x00=buf +hwmon_temp.fpath_0x0015_0x00=/sys/bus/i2c/devices/91-0062/hwmon/ +hwmon_temp.addr_0x0015_0x00=0 +hwmon_temp.len_0x0015_0x00=8 +hwmon_temp.bit_offset_0x0015_0x00= +hwmon_temp.str_cons_0x0015_0x00=temp1_input +# sensor temp21 alias +hwmon_temp.mode_0x0015_0x01=str_constant +hwmon_temp.str_cons_0x0015_0x01=TMOS_CORE_TEMP_11 +# sensor temp21 type +hwmon_temp.mode_0x0015_0x02=str_constant +hwmon_temp.str_cons_0x0015_0x02=xdpe12284c +# sensor temp21 max +hwmon_temp.mode_0x0015_0x03=str_constant +hwmon_temp.str_cons_0x0015_0x03=125000 +# sensor temp21 min +hwmon_temp.mode_0x0015_0x05=str_constant +hwmon_temp.str_cons_0x0015_0x05=-30000 + +# temp22 TMOS_CORE_TEMP_12 +hwmon_temp.mode_0x0016_0x00=config +hwmon_temp.int_cons_0x0016_0x00=0 +hwmon_temp.src_0x0016_0x00=file +hwmon_temp.frmt_0x0016_0x00=buf +hwmon_temp.fpath_0x0016_0x00=/sys/bus/i2c/devices/92-0060/hwmon/ +hwmon_temp.addr_0x0016_0x00=0 +hwmon_temp.len_0x0016_0x00=8 +hwmon_temp.bit_offset_0x0016_0x00= +hwmon_temp.str_cons_0x0016_0x00=temp1_input +# sensor temp22 alias +hwmon_temp.mode_0x0016_0x01=str_constant +hwmon_temp.str_cons_0x0016_0x01=TMOS_CORE_TEMP_12 +# sensor temp22 type +hwmon_temp.mode_0x0016_0x02=str_constant +hwmon_temp.str_cons_0x0016_0x02=xdpe12284c +# sensor temp22 max +hwmon_temp.mode_0x0016_0x03=str_constant +hwmon_temp.str_cons_0x0016_0x03=125000 +# sensor temp22 min +hwmon_temp.mode_0x0016_0x05=str_constant +hwmon_temp.str_cons_0x0016_0x05=-30000 + +# temp23 TMOS_CORE_TEMP_13 +hwmon_temp.mode_0x0017_0x00=config +hwmon_temp.int_cons_0x0017_0x00=0 +hwmon_temp.src_0x0017_0x00=file +hwmon_temp.frmt_0x0017_0x00=buf +hwmon_temp.fpath_0x0017_0x00=/sys/bus/i2c/devices/92-0062/hwmon/ +hwmon_temp.addr_0x0017_0x00=0 +hwmon_temp.len_0x0017_0x00=8 +hwmon_temp.bit_offset_0x0017_0x00= +hwmon_temp.str_cons_0x0017_0x00=temp1_input +# sensor temp23 alias +hwmon_temp.mode_0x0017_0x01=str_constant +hwmon_temp.str_cons_0x0017_0x01=TMOS_CORE_TEMP_13 +# sensor temp23 type +hwmon_temp.mode_0x0017_0x02=str_constant +hwmon_temp.str_cons_0x0017_0x02=xdpe12284c +# sensor temp23 max +hwmon_temp.mode_0x0017_0x03=str_constant +hwmon_temp.str_cons_0x0017_0x03=125000 +# sensor temp23 min +hwmon_temp.mode_0x0017_0x05=str_constant +hwmon_temp.str_cons_0x0017_0x05=-30000 + +# temp24 TMOS_CORE_TEMP_14 +hwmon_temp.mode_0x0018_0x00=config +hwmon_temp.int_cons_0x0018_0x00=0 +hwmon_temp.src_0x0018_0x00=file +hwmon_temp.frmt_0x0018_0x00=buf +hwmon_temp.fpath_0x0018_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_temp.addr_0x0018_0x00=0 +hwmon_temp.len_0x0018_0x00=8 +hwmon_temp.bit_offset_0x0018_0x00= +hwmon_temp.str_cons_0x0018_0x00=temp1_input +# sensor temp24 alias +hwmon_temp.mode_0x0018_0x01=str_constant +hwmon_temp.str_cons_0x0018_0x01=TMOS_CORE_TEMP_14 +# sensor temp24 type +hwmon_temp.mode_0x0018_0x02=str_constant +hwmon_temp.str_cons_0x0018_0x02=xdpe12284c +# sensor temp24 max +hwmon_temp.mode_0x0018_0x03=str_constant +hwmon_temp.str_cons_0x0018_0x03=125000 +# sensor temp24 min +hwmon_temp.mode_0x0018_0x05=str_constant +hwmon_temp.str_cons_0x0018_0x05=-30000 + +# sensor vol +# value : 0 +# alias : 1 +# type : 2 +# max : 3 +# hyst : 4 +# min : 5 +# crit : 6 +# range : 7 +# nominal_value : 8 +# high : 9 +# low : 10 + +# vol1 +hwmon_in.mode_0x0001_0x00=config +hwmon_in.int_cons_0x0001_0x00=0 +hwmon_in.src_0x0001_0x00=file +hwmon_in.frmt_0x0001_0x00=buf +hwmon_in.fpath_0x0001_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0001_0x00=0 +hwmon_in.len_0x0001_0x00=8 +hwmon_in.bit_offset_0x0001_0x00= +hwmon_in.str_cons_0x0001_0x00=in1_input +hwmon_in.mode_0x0001_0x01=str_constant +hwmon_in.str_cons_0x0001_0x01=VCC12V_Standby +hwmon_in.mode_0x0001_0x02=str_constant +hwmon_in.str_cons_0x0001_0x02=ucd90160 +hwmon_in.mode_0x0001_0x03=constant +hwmon_in.int_cons_0x0001_0x03=13200 +hwmon_in.mode_0x0001_0x05=constant +hwmon_in.int_cons_0x0001_0x05=10800 +hwmon_in.mode_0x0001_0x08=constant +hwmon_in.int_cons_0x0001_0x08=12000 + +# vol2 +hwmon_in.mode_0x0002_0x00=config +hwmon_in.int_cons_0x0002_0x00=0 +hwmon_in.src_0x0002_0x00=file +hwmon_in.frmt_0x0002_0x00=buf +hwmon_in.fpath_0x0002_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0002_0x00=0 +hwmon_in.len_0x0002_0x00=8 +hwmon_in.bit_offset_0x0002_0x00= +hwmon_in.str_cons_0x0002_0x00=in2_input +hwmon_in.mode_0x0002_0x01=str_constant +hwmon_in.str_cons_0x0002_0x01=VDD12V +hwmon_in.mode_0x0002_0x02=str_constant +hwmon_in.str_cons_0x0002_0x02=ucd90160 +hwmon_in.mode_0x0002_0x03=constant +hwmon_in.int_cons_0x0002_0x03=13200 +hwmon_in.mode_0x0002_0x05=constant +hwmon_in.int_cons_0x0002_0x05=10800 +hwmon_in.mode_0x0002_0x08=constant +hwmon_in.int_cons_0x0002_0x08=12000 + +# vol3 +hwmon_in.mode_0x0003_0x00=config +hwmon_in.int_cons_0x0003_0x00=0 +hwmon_in.src_0x0003_0x00=file +hwmon_in.frmt_0x0003_0x00=buf +hwmon_in.fpath_0x0003_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0003_0x00=0 +hwmon_in.len_0x0003_0x00=8 +hwmon_in.bit_offset_0x0003_0x00= +hwmon_in.str_cons_0x0003_0x00=in3_input +hwmon_in.mode_0x0003_0x01=str_constant +hwmon_in.str_cons_0x0003_0x01=VDD_CPU12V +hwmon_in.mode_0x0003_0x02=str_constant +hwmon_in.str_cons_0x0003_0x02=ucd90160 +hwmon_in.mode_0x0003_0x03=constant +hwmon_in.int_cons_0x0003_0x03=13200 +hwmon_in.mode_0x0003_0x05=constant +hwmon_in.int_cons_0x0003_0x05=10800 +hwmon_in.mode_0x0003_0x08=constant +hwmon_in.int_cons_0x0003_0x08=12000 + +# vol4 +hwmon_in.mode_0x0004_0x00=config +hwmon_in.int_cons_0x0004_0x00=0 +hwmon_in.src_0x0004_0x00=file +hwmon_in.frmt_0x0004_0x00=buf +hwmon_in.fpath_0x0004_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0004_0x00=0 +hwmon_in.len_0x0004_0x00=8 +hwmon_in.bit_offset_0x0004_0x00= +hwmon_in.str_cons_0x0004_0x00=in4_input +hwmon_in.mode_0x0004_0x01=str_constant +hwmon_in.str_cons_0x0004_0x01=VDD5V_USB +hwmon_in.mode_0x0004_0x02=str_constant +hwmon_in.str_cons_0x0004_0x02=ucd90160 +hwmon_in.mode_0x0004_0x03=constant +hwmon_in.int_cons_0x0004_0x03=5500 +hwmon_in.mode_0x0004_0x05=constant +hwmon_in.int_cons_0x0004_0x05=4500 +hwmon_in.mode_0x0004_0x08=constant +hwmon_in.int_cons_0x0004_0x08=5000 + +# vol5 +hwmon_in.mode_0x0005_0x00=config +hwmon_in.int_cons_0x0005_0x00=0 +hwmon_in.src_0x0005_0x00=file +hwmon_in.frmt_0x0005_0x00=buf +hwmon_in.fpath_0x0005_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0005_0x00=0 +hwmon_in.len_0x0005_0x00=8 +hwmon_in.bit_offset_0x0005_0x00= +hwmon_in.str_cons_0x0005_0x00=in5_input +hwmon_in.mode_0x0005_0x01=str_constant +hwmon_in.str_cons_0x0005_0x01=USB5V +hwmon_in.mode_0x0005_0x02=str_constant +hwmon_in.str_cons_0x0005_0x02=ucd90160 +hwmon_in.mode_0x0005_0x03=constant +hwmon_in.int_cons_0x0005_0x03=5500 +hwmon_in.mode_0x0005_0x05=constant +hwmon_in.int_cons_0x0005_0x05=4500 +hwmon_in.mode_0x0005_0x08=constant +hwmon_in.int_cons_0x0005_0x08=5000 + +# vol6 PHY_VDD1V8 +monitor_flag_hwmon_in.mode_0x0006_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.mode_0x0006_0x00=config +hwmon_in.int_cons_0x0006_0x00=0 +hwmon_in.src_0x0006_0x00=file +hwmon_in.frmt_0x0006_0x00=buf +hwmon_in.fpath_0x0006_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0006_0x00=0 +hwmon_in.len_0x0006_0x00=8 +hwmon_in.bit_offset_0x0006_0x00= +hwmon_in.str_cons_0x0006_0x00=in6_input +hwmon_in.mode_0x0006_0x01=str_constant +hwmon_in.str_cons_0x0006_0x01=VDD3V3_STBY +hwmon_in.mode_0x0006_0x02=str_constant +hwmon_in.str_cons_0x0006_0x02=ucd90160 +hwmon_in.mode_0x0006_0x03=constant +hwmon_in.int_cons_0x0006_0x03=3630 +hwmon_in.mode_0x0006_0x05=constant +hwmon_in.int_cons_0x0006_0x05=2970 +hwmon_in.mode_0x0006_0x08=constant +hwmon_in.int_cons_0x0006_0x08=3300 + +# vol7 +hwmon_in.mode_0x0007_0x00=config +hwmon_in.int_cons_0x0007_0x00=0 +hwmon_in.src_0x0007_0x00=file +hwmon_in.frmt_0x0007_0x00=buf +hwmon_in.fpath_0x0007_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0007_0x00=0 +hwmon_in.len_0x0007_0x00=8 +hwmon_in.bit_offset_0x0007_0x00= +hwmon_in.str_cons_0x0007_0x00=in7_input +hwmon_in.mode_0x0007_0x01=str_constant +hwmon_in.str_cons_0x0007_0x01=BMC_VCC3.3V_OUT +hwmon_in.mode_0x0007_0x02=str_constant +hwmon_in.str_cons_0x0007_0x02=ucd90160 +hwmon_in.mode_0x0007_0x03=constant +hwmon_in.int_cons_0x0007_0x03=3630 +hwmon_in.mode_0x0007_0x05=constant +hwmon_in.int_cons_0x0007_0x05=2970 +hwmon_in.mode_0x0007_0x08=constant +hwmon_in.int_cons_0x0007_0x08=3300 + +# vol8 +hwmon_in.mode_0x0008_0x00=config +hwmon_in.int_cons_0x0008_0x00=0 +hwmon_in.src_0x0008_0x00=file +hwmon_in.frmt_0x0008_0x00=buf +hwmon_in.fpath_0x0008_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0008_0x00=0 +hwmon_in.len_0x0008_0x00=8 +hwmon_in.bit_offset_0x0008_0x00= +hwmon_in.str_cons_0x0008_0x00=in8_input +hwmon_in.mode_0x0008_0x01=str_constant +hwmon_in.str_cons_0x0008_0x01=VDD3.3V_PWRCYCLE +hwmon_in.mode_0x0008_0x02=str_constant +hwmon_in.str_cons_0x0008_0x02=ucd90160 +hwmon_in.mode_0x0008_0x03=constant +hwmon_in.int_cons_0x0008_0x03=3630 +hwmon_in.mode_0x0008_0x05=constant +hwmon_in.int_cons_0x0008_0x05=2970 +hwmon_in.mode_0x0008_0x08=constant +hwmon_in.int_cons_0x0008_0x08=3300 + +# vol9 +hwmon_in.mode_0x0009_0x00=config +hwmon_in.int_cons_0x0009_0x00=0 +hwmon_in.src_0x0009_0x00=file +hwmon_in.frmt_0x0009_0x00=buf +hwmon_in.fpath_0x0009_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x0009_0x00=0 +hwmon_in.len_0x0009_0x00=8 +hwmon_in.bit_offset_0x0009_0x00= +hwmon_in.str_cons_0x0009_0x00=in9_input +hwmon_in.mode_0x0009_0x01=str_constant +hwmon_in.str_cons_0x0009_0x01=VDD3.3V +hwmon_in.mode_0x0009_0x02=str_constant +hwmon_in.str_cons_0x0009_0x02=ucd90160 +hwmon_in.mode_0x0009_0x03=constant +hwmon_in.int_cons_0x0009_0x03=3630 +hwmon_in.mode_0x0009_0x05=constant +hwmon_in.int_cons_0x0009_0x05=2970 +hwmon_in.mode_0x0009_0x08=constant +hwmon_in.int_cons_0x0009_0x08=3300 + +# vol10 +monitor_flag_hwmon_in.mode_0x000a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.mode_0x000a_0x00=config +hwmon_in.int_cons_0x000a_0x00=0 +hwmon_in.src_0x000a_0x00=file +hwmon_in.frmt_0x000a_0x00=buf +hwmon_in.fpath_0x000a_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x000a_0x00=0 +hwmon_in.len_0x000a_0x00=8 +hwmon_in.bit_offset_0x000a_0x00= +hwmon_in.str_cons_0x000a_0x00=in10_input +hwmon_in.mode_0x000a_0x01=str_constant +hwmon_in.str_cons_0x000a_0x01=VDD3.3_CLK +hwmon_in.mode_0x000a_0x02=str_constant +hwmon_in.str_cons_0x000a_0x02=ucd90160 +hwmon_in.mode_0x000a_0x03=constant +hwmon_in.int_cons_0x000a_0x03=3630 +hwmon_in.mode_0x000a_0x05=constant +hwmon_in.int_cons_0x000a_0x05=2970 +hwmon_in.mode_0x000a_0x08=constant +hwmon_in.int_cons_0x000a_0x08=3300 + +# vol11 +hwmon_in.mode_0x000b_0x00=config +hwmon_in.int_cons_0x000b_0x00=0 +hwmon_in.src_0x000b_0x00=file +hwmon_in.frmt_0x000b_0x00=buf +hwmon_in.fpath_0x000b_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x000b_0x00=0 +hwmon_in.len_0x000b_0x00=8 +hwmon_in.bit_offset_0x000b_0x00= +hwmon_in.str_cons_0x000b_0x00=in11_input +hwmon_in.mode_0x000b_0x01=str_constant +hwmon_in.str_cons_0x000b_0x01=SSD_VDD3.3V +hwmon_in.mode_0x000b_0x02=str_constant +hwmon_in.str_cons_0x000b_0x02=ucd90160 +hwmon_in.mode_0x000b_0x03=constant +hwmon_in.int_cons_0x000b_0x03=3630 +hwmon_in.mode_0x000b_0x05=constant +hwmon_in.int_cons_0x000b_0x05=2970 +hwmon_in.mode_0x000b_0x08=constant +hwmon_in.int_cons_0x000b_0x08=3300 + +# vol12 VDD1.8V +monitor_flag_hwmon_in.mode_0x000c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x000c_0x00=0 +hwmon_in.mode_0x000c_0x00=config +hwmon_in.int_cons_0x000c_0x00=0 +hwmon_in.src_0x000c_0x00=file +hwmon_in.frmt_0x000c_0x00=buf +hwmon_in.fpath_0x000c_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x000c_0x00=0 +hwmon_in.len_0x000c_0x00=8 +hwmon_in.bit_offset_0x000c_0x00= +hwmon_in.str_cons_0x000c_0x00=in12_input +hwmon_in.mode_0x000c_0x01=str_constant +hwmon_in.str_cons_0x000c_0x01=SSD2_VDD3.3V +hwmon_in.mode_0x000c_0x02=str_constant +hwmon_in.str_cons_0x000c_0x02=ucd90160 +hwmon_in.mode_0x000c_0x03=constant +hwmon_in.int_cons_0x000c_0x03=3630 +hwmon_in.mode_0x000c_0x05=constant +hwmon_in.int_cons_0x000c_0x05=2970 +hwmon_in.mode_0x000c_0x08=constant +hwmon_in.int_cons_0x000c_0x08=3300 + +# vol13 +hwmon_in.mode_0x000d_0x00=config +hwmon_in.int_cons_0x000d_0x00=0 +hwmon_in.src_0x000d_0x00=file +hwmon_in.frmt_0x000d_0x00=buf +hwmon_in.fpath_0x000d_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x000d_0x00=0 +hwmon_in.len_0x000d_0x00=8 +hwmon_in.bit_offset_0x000d_0x00= +hwmon_in.str_cons_0x000d_0x00=in13_input +hwmon_in.mode_0x000d_0x01=str_constant +hwmon_in.str_cons_0x000d_0x01=PHY_VDD1V8 +hwmon_in.mode_0x000d_0x02=str_constant +hwmon_in.str_cons_0x000d_0x02=ucd90160 +hwmon_in.mode_0x000d_0x03=constant +hwmon_in.int_cons_0x000d_0x03=1980 +hwmon_in.mode_0x000d_0x05=constant +hwmon_in.int_cons_0x000d_0x05=1620 +hwmon_in.mode_0x000d_0x08=constant +hwmon_in.int_cons_0x000d_0x08=1800 + +# vol14 +hwmon_in.mode_0x000e_0x00=config +hwmon_in.int_cons_0x000e_0x00=0 +hwmon_in.src_0x000e_0x00=file +hwmon_in.frmt_0x000e_0x00=buf +hwmon_in.fpath_0x000e_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x000e_0x00=0 +hwmon_in.len_0x000e_0x00=8 +hwmon_in.bit_offset_0x000e_0x00= +hwmon_in.str_cons_0x000e_0x00=in14_input +hwmon_in.mode_0x000e_0x01=str_constant +hwmon_in.str_cons_0x000e_0x01=PHY_VDD1V0 +hwmon_in.mode_0x000e_0x02=str_constant +hwmon_in.str_cons_0x000e_0x02=ucd90160 +hwmon_in.mode_0x000e_0x03=constant +hwmon_in.int_cons_0x000e_0x03=1100 +hwmon_in.mode_0x000e_0x05=constant +hwmon_in.int_cons_0x000e_0x05=900 +hwmon_in.mode_0x000e_0x08=constant +hwmon_in.int_cons_0x000e_0x08=1000 + +# vol15 +hwmon_in.mode_0x000f_0x00=config +hwmon_in.int_cons_0x000f_0x00=0 +hwmon_in.src_0x000f_0x00=file +hwmon_in.frmt_0x000f_0x00=buf +hwmon_in.fpath_0x000f_0x00=/sys/bus/i2c/devices/69-005b/hwmon/ +hwmon_in.addr_0x000f_0x00=0 +hwmon_in.len_0x000f_0x00=8 +hwmon_in.bit_offset_0x000f_0x00= +hwmon_in.str_cons_0x000f_0x00=in15_input +hwmon_in.mode_0x000f_0x01=str_constant +hwmon_in.str_cons_0x000f_0x01=VDD1.1V_HUB +hwmon_in.mode_0x000f_0x02=str_constant +hwmon_in.str_cons_0x000f_0x02=ucd90160 +hwmon_in.mode_0x000f_0x03=constant +hwmon_in.int_cons_0x000f_0x03=1210 +hwmon_in.mode_0x000f_0x05=constant +hwmon_in.int_cons_0x000f_0x05=990 +hwmon_in.mode_0x000f_0x08=constant +hwmon_in.int_cons_0x000f_0x08=1100 + +# vol16 +hwmon_in.mode_0x0010_0x00=config +hwmon_in.int_cons_0x0010_0x00=0 +hwmon_in.src_0x0010_0x00=file +hwmon_in.frmt_0x0010_0x00=buf +hwmon_in.fpath_0x0010_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0010_0x00=0 +hwmon_in.len_0x0010_0x00=8 +hwmon_in.bit_offset_0x0010_0x00= +hwmon_in.str_cons_0x0010_0x00=in1_input +hwmon_in.mode_0x0010_0x01=str_constant +hwmon_in.str_cons_0x0010_0x01=VDD12V_MAC1 +hwmon_in.mode_0x0010_0x02=str_constant +hwmon_in.str_cons_0x0010_0x02=ucd90160 +hwmon_in.mode_0x0010_0x03=constant +hwmon_in.int_cons_0x0010_0x03=13200 +hwmon_in.mode_0x0010_0x05=constant +hwmon_in.int_cons_0x0010_0x05=10800 +hwmon_in.mode_0x0010_0x08=constant +hwmon_in.int_cons_0x0010_0x08=12000 + +# vol17 +hwmon_in.mode_0x0011_0x00=config +hwmon_in.int_cons_0x0011_0x00=0 +hwmon_in.src_0x0011_0x00=file +hwmon_in.frmt_0x0011_0x00=buf +hwmon_in.fpath_0x0011_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0011_0x00=0 +hwmon_in.len_0x0011_0x00=8 +hwmon_in.bit_offset_0x0011_0x00= +hwmon_in.str_cons_0x0011_0x00=in2_input +hwmon_in.mode_0x0011_0x01=str_constant +hwmon_in.str_cons_0x0011_0x01=VDD1.8_CLK +hwmon_in.mode_0x0011_0x02=str_constant +hwmon_in.str_cons_0x0011_0x02=ucd90160 +hwmon_in.mode_0x0011_0x03=constant +hwmon_in.int_cons_0x0011_0x03=1980 +hwmon_in.mode_0x0011_0x05=constant +hwmon_in.int_cons_0x0011_0x05=1620 +hwmon_in.mode_0x0011_0x08=constant +hwmon_in.int_cons_0x0011_0x08=1800 + +# vol18 +hwmon_in.mode_0x0012_0x00=config +hwmon_in.int_cons_0x0012_0x00=0 +hwmon_in.src_0x0012_0x00=file +hwmon_in.frmt_0x0012_0x00=buf +hwmon_in.fpath_0x0012_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0012_0x00=0 +hwmon_in.len_0x0012_0x00=8 +hwmon_in.bit_offset_0x0012_0x00= +hwmon_in.str_cons_0x0012_0x00=in3_input +hwmon_in.mode_0x0012_0x01=str_constant +hwmon_in.str_cons_0x0012_0x01=VDD3.3_CLK_MAC +hwmon_in.mode_0x0012_0x02=str_constant +hwmon_in.str_cons_0x0012_0x02=ucd90160 +hwmon_in.mode_0x0012_0x03=constant +hwmon_in.int_cons_0x0012_0x03=3630 +hwmon_in.mode_0x0012_0x05=constant +hwmon_in.int_cons_0x0012_0x05=2970 +hwmon_in.mode_0x0012_0x08=constant +hwmon_in.int_cons_0x0012_0x08=3300 + +# vol19 +hwmon_in.mode_0x0013_0x00=config +hwmon_in.int_cons_0x0013_0x00=0 +hwmon_in.src_0x0013_0x00=file +hwmon_in.frmt_0x0013_0x00=buf +hwmon_in.fpath_0x0013_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0013_0x00=0 +hwmon_in.len_0x0013_0x00=8 +hwmon_in.bit_offset_0x0013_0x00= +hwmon_in.str_cons_0x0013_0x00=in4_input +hwmon_in.mode_0x0013_0x01=str_constant +hwmon_in.str_cons_0x0013_0x01=VDD1.0V_FPGA +hwmon_in.mode_0x0013_0x02=str_constant +hwmon_in.str_cons_0x0013_0x02=ucd90160 +hwmon_in.mode_0x0013_0x03=constant +hwmon_in.int_cons_0x0013_0x03=1100 +hwmon_in.mode_0x0013_0x05=constant +hwmon_in.int_cons_0x0013_0x05=900 +hwmon_in.mode_0x0013_0x08=constant +hwmon_in.int_cons_0x0013_0x08=1000 + +# vol20 +hwmon_in.mode_0x0014_0x00=config +hwmon_in.int_cons_0x0014_0x00=0 +hwmon_in.src_0x0014_0x00=file +hwmon_in.frmt_0x0014_0x00=buf +hwmon_in.fpath_0x0014_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0014_0x00=0 +hwmon_in.len_0x0014_0x00=8 +hwmon_in.bit_offset_0x0014_0x00= +hwmon_in.str_cons_0x0014_0x00=in5_input +hwmon_in.mode_0x0014_0x01=str_constant +hwmon_in.str_cons_0x0014_0x01=VDD1.8V_FPGA +hwmon_in.mode_0x0014_0x02=str_constant +hwmon_in.str_cons_0x0014_0x02=ucd90160 +hwmon_in.mode_0x0014_0x03=constant +hwmon_in.int_cons_0x0014_0x03=1980 +hwmon_in.mode_0x0014_0x05=constant +hwmon_in.int_cons_0x0014_0x05=1620 +hwmon_in.mode_0x0014_0x08=constant +hwmon_in.int_cons_0x0014_0x08=1800 + +# vol21 +monitor_flag_hwmon_in.mode_0x0015_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0015_0x00=0 +hwmon_in.mode_0x0015_0x00=config +hwmon_in.int_cons_0x0015_0x00=0 +hwmon_in.src_0x0015_0x00=file +hwmon_in.frmt_0x0015_0x00=buf +hwmon_in.fpath_0x0015_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0015_0x00=0 +hwmon_in.len_0x0015_0x00=8 +hwmon_in.bit_offset_0x0015_0x00= +hwmon_in.str_cons_0x0015_0x00=in6_input +hwmon_in.mode_0x0015_0x01=str_constant +hwmon_in.str_cons_0x0015_0x01=VDD1.2V_FPGA +hwmon_in.mode_0x0015_0x02=str_constant +hwmon_in.str_cons_0x0015_0x02=ucd90160 +hwmon_in.mode_0x0015_0x03=constant +hwmon_in.int_cons_0x0015_0x03=1320 +hwmon_in.mode_0x0015_0x05=constant +hwmon_in.int_cons_0x0015_0x05=1080 +hwmon_in.mode_0x0015_0x08=constant +hwmon_in.int_cons_0x0015_0x08=1200 + +# vol22 +monitor_flag_hwmon_in.mode_0x0016_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0016_0x00=0 +hwmon_in.mode_0x0016_0x00=config +hwmon_in.int_cons_0x0016_0x00=0 +hwmon_in.src_0x0016_0x00=file +hwmon_in.frmt_0x0016_0x00=buf +hwmon_in.fpath_0x0016_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0016_0x00=0 +hwmon_in.len_0x0016_0x00=8 +hwmon_in.bit_offset_0x0016_0x00= +hwmon_in.str_cons_0x0016_0x00=in7_input +hwmon_in.mode_0x0016_0x01=str_constant +hwmon_in.str_cons_0x0016_0x01=VDD3.3V +hwmon_in.mode_0x0016_0x02=str_constant +hwmon_in.str_cons_0x0016_0x02=ucd90160 +hwmon_in.mode_0x0016_0x03=constant +hwmon_in.int_cons_0x0016_0x03=3630 +hwmon_in.mode_0x0016_0x05=constant +hwmon_in.int_cons_0x0016_0x05=2970 +hwmon_in.mode_0x0016_0x08=constant +hwmon_in.int_cons_0x0016_0x08=3300 + +# vol23 +hwmon_in.mode_0x0017_0x00=config +hwmon_in.int_cons_0x0017_0x00=0 +hwmon_in.src_0x0017_0x00=file +hwmon_in.frmt_0x0017_0x00=buf +hwmon_in.fpath_0x0017_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0017_0x00=0 +hwmon_in.len_0x0017_0x00=8 +hwmon_in.bit_offset_0x0017_0x00= +hwmon_in.str_cons_0x0017_0x00=in8_input +hwmon_in.mode_0x0017_0x01=str_constant +hwmon_in.str_cons_0x0017_0x01=VDD3.3V_standby +hwmon_in.mode_0x0017_0x02=str_constant +hwmon_in.str_cons_0x0017_0x02=ucd90160 +hwmon_in.mode_0x0017_0x03=constant +hwmon_in.int_cons_0x0017_0x03=3630 +hwmon_in.mode_0x0017_0x05=constant +hwmon_in.int_cons_0x0017_0x05=2970 +hwmon_in.mode_0x0017_0x08=constant +hwmon_in.int_cons_0x0017_0x08=3300 + +# vol24 +hwmon_in.mode_0x0018_0x00=config +hwmon_in.int_cons_0x0018_0x00=0 +hwmon_in.src_0x0018_0x00=file +hwmon_in.frmt_0x0018_0x00=buf +hwmon_in.fpath_0x0018_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0018_0x00=0 +hwmon_in.len_0x0018_0x00=8 +hwmon_in.bit_offset_0x0018_0x00=0 +hwmon_in.str_cons_0x0018_0x00=in9_input +hwmon_in.mode_0x0018_0x01=str_constant +hwmon_in.str_cons_0x0018_0x01=VDD3.3V_FPGA +hwmon_in.mode_0x0018_0x02=str_constant +hwmon_in.str_cons_0x0018_0x02=ucd90160 +hwmon_in.mode_0x0018_0x03=constant +hwmon_in.int_cons_0x0018_0x03=3630 +hwmon_in.mode_0x0018_0x05=constant +hwmon_in.int_cons_0x0018_0x05=2970 +hwmon_in.mode_0x0018_0x08=constant +hwmon_in.int_cons_0x0018_0x08=3300 + +# vol25 +hwmon_in.mode_0x0019_0x00=config +hwmon_in.int_cons_0x0019_0x00=0 +hwmon_in.src_0x0019_0x00=file +hwmon_in.frmt_0x0019_0x00=buf +hwmon_in.fpath_0x0019_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x0019_0x00=0 +hwmon_in.len_0x0019_0x00=8 +hwmon_in.bit_offset_0x0019_0x00=0 +hwmon_in.str_cons_0x0019_0x00=in11_input +hwmon_in.mode_0x0019_0x01=str_constant +hwmon_in.str_cons_0x0019_0x01=VDD3.3V_PHY +hwmon_in.mode_0x0019_0x02=str_constant +hwmon_in.str_cons_0x0019_0x02=ucd90160 +hwmon_in.mode_0x0019_0x03=constant +hwmon_in.int_cons_0x0019_0x03=3630 +hwmon_in.mode_0x0019_0x05=constant +hwmon_in.int_cons_0x0019_0x05=2970 +hwmon_in.mode_0x0019_0x08=constant +hwmon_in.int_cons_0x0019_0x08=3300 + +# vol26 +hwmon_in.mode_0x001a_0x00=config +hwmon_in.int_cons_0x001a_0x00=0 +hwmon_in.src_0x001a_0x00=file +hwmon_in.frmt_0x001a_0x00=buf +hwmon_in.fpath_0x001a_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x001a_0x00=0 +hwmon_in.len_0x001a_0x00=8 +hwmon_in.bit_offset_0x001a_0x00= +hwmon_in.str_cons_0x001a_0x00=in12_input +hwmon_in.mode_0x001a_0x01=str_constant +hwmon_in.str_cons_0x001a_0x01=VDD3V8_CLK +hwmon_in.mode_0x001a_0x02=str_constant +hwmon_in.str_cons_0x001a_0x02=ucd90160 +hwmon_in.mode_0x001a_0x03=constant +hwmon_in.int_cons_0x001a_0x03=4180 +hwmon_in.mode_0x001a_0x05=constant +hwmon_in.int_cons_0x001a_0x05=3420 +hwmon_in.mode_0x001a_0x08=constant +hwmon_in.int_cons_0x001a_0x08=3800 + +# vol27 +hwmon_in.mode_0x001b_0x00=config +hwmon_in.int_cons_0x001b_0x00=0 +hwmon_in.src_0x001b_0x00=file +hwmon_in.frmt_0x001b_0x00=buf +hwmon_in.fpath_0x001b_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x001b_0x00=0 +hwmon_in.len_0x001b_0x00=8 +hwmon_in.bit_offset_0x001b_0x00= +hwmon_in.str_cons_0x001b_0x00=in13_input +hwmon_in.mode_0x001b_0x01=str_constant +hwmon_in.str_cons_0x001b_0x01=VDD5V_VR_0 +hwmon_in.mode_0x001b_0x02=str_constant +hwmon_in.str_cons_0x001b_0x02=ucd90160 +hwmon_in.mode_0x001b_0x03=constant +hwmon_in.int_cons_0x001b_0x03=5500 +hwmon_in.mode_0x001b_0x05=constant +hwmon_in.int_cons_0x001b_0x05=4500 +hwmon_in.mode_0x001b_0x08=constant +hwmon_in.int_cons_0x001b_0x08=5000 + +# vol28 +monitor_flag_hwmon_in.mode_0x001c_0x00=constant +monitor_flag_hwmon_in.int_cons_0x001c_0x00=0 +hwmon_in.mode_0x001c_0x00=config +hwmon_in.int_cons_0x001c_0x00=0 +hwmon_in.src_0x001c_0x00=file +hwmon_in.frmt_0x001c_0x00=buf +hwmon_in.fpath_0x001c_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x001c_0x00=0 +hwmon_in.len_0x001c_0x00=8 +hwmon_in.bit_offset_0x001c_0x00= +hwmon_in.str_cons_0x001c_0x00=in14_input +hwmon_in.mode_0x001c_0x01=str_constant +hwmon_in.str_cons_0x001c_0x01=VDD5V_VR_1 +hwmon_in.mode_0x001c_0x02=str_constant +hwmon_in.str_cons_0x001c_0x02=ucd90160 +hwmon_in.mode_0x001c_0x03=constant +hwmon_in.int_cons_0x001c_0x03=5500 +hwmon_in.mode_0x001c_0x05=constant +hwmon_in.int_cons_0x001c_0x05=4500 +hwmon_in.mode_0x001c_0x08=constant +hwmon_in.int_cons_0x001c_0x08=5000 + +# vol29 +hwmon_in.mode_0x001d_0x00=config +hwmon_in.int_cons_0x001d_0x00=0 +hwmon_in.src_0x001d_0x00=file +hwmon_in.frmt_0x001d_0x00=buf +hwmon_in.fpath_0x001d_0x00=/sys/bus/i2c/devices/83-005b/hwmon/ +hwmon_in.addr_0x001d_0x00=0 +hwmon_in.len_0x001d_0x00=8 +hwmon_in.bit_offset_0x001d_0x00= +hwmon_in.str_cons_0x001d_0x00=in15_input +hwmon_in.mode_0x001d_0x01=str_constant +hwmon_in.str_cons_0x001d_0x01=VDD5V_VR_2 +hwmon_in.mode_0x001d_0x02=str_constant +hwmon_in.str_cons_0x001d_0x02=ucd90160 +hwmon_in.mode_0x001d_0x03=constant +hwmon_in.int_cons_0x001d_0x03=5500 +hwmon_in.mode_0x001d_0x05=constant +hwmon_in.int_cons_0x001d_0x05=4500 +hwmon_in.mode_0x001d_0x08=constant +hwmon_in.int_cons_0x001d_0x08=5000 + +# vol30 +hwmon_in.mode_0x001e_0x00=config +hwmon_in.int_cons_0x001e_0x00=0 +hwmon_in.src_0x001e_0x00=file +hwmon_in.frmt_0x001e_0x00=buf +hwmon_in.fpath_0x001e_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x001e_0x00=0 +hwmon_in.len_0x001e_0x00=8 +hwmon_in.bit_offset_0x001e_0x00= +hwmon_in.str_cons_0x001e_0x00=in1_input +hwmon_in.mode_0x001e_0x01=str_constant +hwmon_in.str_cons_0x001e_0x01=VDD12V_MAC2 +hwmon_in.mode_0x001e_0x02=str_constant +hwmon_in.str_cons_0x001e_0x02=ucd90160 +hwmon_in.mode_0x001e_0x03=constant +hwmon_in.int_cons_0x001e_0x03=13200 +hwmon_in.mode_0x001e_0x05=constant +hwmon_in.int_cons_0x001e_0x05=10800 +hwmon_in.mode_0x001e_0x08=constant +hwmon_in.int_cons_0x001e_0x08=12000 + +# vol31 +hwmon_in.mode_0x001f_0x00=config +hwmon_in.int_cons_0x001f_0x00=0 +hwmon_in.src_0x001f_0x00=file +hwmon_in.frmt_0x001f_0x00=buf +hwmon_in.fpath_0x001f_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x001f_0x00=0 +hwmon_in.len_0x001f_0x00=8 +hwmon_in.bit_offset_0x001f_0x00=0 +hwmon_in.str_cons_0x001f_0x00=in2_input +hwmon_in.mode_0x001f_0x01=str_constant +hwmon_in.str_cons_0x001f_0x01=VDDO1.8V +hwmon_in.mode_0x001f_0x02=str_constant +hwmon_in.str_cons_0x001f_0x02=ucd90160 +hwmon_in.mode_0x001f_0x03=constant +hwmon_in.int_cons_0x001f_0x03=1980 +hwmon_in.mode_0x001f_0x05=constant +hwmon_in.int_cons_0x001f_0x05=1620 +hwmon_in.mode_0x001f_0x08=constant +hwmon_in.int_cons_0x001f_0x08=1800 + +# vol32 +hwmon_in.mode_0x0020_0x00=config +hwmon_in.int_cons_0x0020_0x00=0 +hwmon_in.src_0x0020_0x00=file +hwmon_in.frmt_0x0020_0x00=buf +hwmon_in.fpath_0x0020_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0020_0x00=0 +hwmon_in.len_0x0020_0x00=8 +hwmon_in.bit_offset_0x0020_0x00=0 +hwmon_in.str_cons_0x0020_0x00=in3_input +hwmon_in.mode_0x0020_0x01=str_constant +hwmon_in.str_cons_0x0020_0x01=VDD1.5V +hwmon_in.mode_0x0020_0x02=str_constant +hwmon_in.str_cons_0x0020_0x02=ucd90160 +hwmon_in.mode_0x0020_0x03=constant +hwmon_in.int_cons_0x0020_0x03=1650 +hwmon_in.mode_0x0020_0x05=constant +hwmon_in.int_cons_0x0020_0x05=1350 +hwmon_in.mode_0x0020_0x08=constant +hwmon_in.int_cons_0x0020_0x08=1500 + +# vol33 +hwmon_in.mode_0x0021_0x00=config +hwmon_in.int_cons_0x0021_0x00=0 +hwmon_in.src_0x0021_0x00=file +hwmon_in.frmt_0x0021_0x00=buf +hwmon_in.fpath_0x0021_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0021_0x00=0 +hwmon_in.len_0x0021_0x00=8 +hwmon_in.bit_offset_0x0021_0x00=0 +hwmon_in.str_cons_0x0021_0x00=in4_input +hwmon_in.mode_0x0021_0x01=str_constant +hwmon_in.str_cons_0x0021_0x01=VDDP1.5V +hwmon_in.mode_0x0021_0x02=str_constant +hwmon_in.str_cons_0x0021_0x02=ucd90160 +hwmon_in.mode_0x0021_0x03=constant +hwmon_in.int_cons_0x0021_0x03=1650 +hwmon_in.mode_0x0021_0x05=constant +hwmon_in.int_cons_0x0021_0x05=1350 +hwmon_in.mode_0x0021_0x08=constant +hwmon_in.int_cons_0x0021_0x08=1500 + +# vol34 +monitor_flag_hwmon_in.mode_0x0022_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0022_0x00=0 +hwmon_in.mode_0x0022_0x00=config +hwmon_in.int_cons_0x0022_0x00=0 +hwmon_in.src_0x0022_0x00=file +hwmon_in.frmt_0x0022_0x00=buf +hwmon_in.fpath_0x0022_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0022_0x00=0 +hwmon_in.len_0x0022_0x00=8 +hwmon_in.bit_offset_0x0022_0x00=0 +hwmon_in.str_cons_0x0022_0x00=in5_input +hwmon_in.mode_0x0022_0x01=str_constant +hwmon_in.str_cons_0x0022_0x01=VDD1.45V_1 +hwmon_in.mode_0x0022_0x02=str_constant +hwmon_in.str_cons_0x0022_0x02=ucd90160 +hwmon_in.mode_0x0022_0x03=constant +hwmon_in.int_cons_0x0022_0x03=1650 +hwmon_in.mode_0x0022_0x05=constant +hwmon_in.int_cons_0x0022_0x05=1350 +hwmon_in.mode_0x0022_0x08=constant +hwmon_in.int_cons_0x0022_0x08=1500 + +# vol35 +monitor_flag_hwmon_in.mode_0x0023_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0023_0x00=0 +hwmon_in.mode_0x0023_0x00=config +hwmon_in.int_cons_0x0023_0x00=0 +hwmon_in.src_0x0023_0x00=file +hwmon_in.frmt_0x0023_0x00=buf +hwmon_in.fpath_0x0023_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0023_0x00=0 +hwmon_in.len_0x0023_0x00=8 +hwmon_in.bit_offset_0x0023_0x00=0 +hwmon_in.str_cons_0x0023_0x00=in6_input +hwmon_in.mode_0x0023_0x01=str_constant +hwmon_in.str_cons_0x0023_0x01=VDD_0P9_ANA_0 +hwmon_in.mode_0x0023_0x02=str_constant +hwmon_in.str_cons_0x0023_0x02=ucd90160 +hwmon_in.mode_0x0023_0x03=constant +hwmon_in.int_cons_0x0023_0x03=927 +hwmon_in.mode_0x0023_0x05=constant +hwmon_in.int_cons_0x0023_0x05=873 +hwmon_in.mode_0x0023_0x08=constant +hwmon_in.int_cons_0x0023_0x08=900 + +# vol36 +monitor_flag_hwmon_in.mode_0x0024_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0024_0x00=0 +hwmon_in.mode_0x0024_0x00=config +hwmon_in.int_cons_0x0024_0x00=0 +hwmon_in.src_0x0024_0x00=file +hwmon_in.frmt_0x0024_0x00=buf +hwmon_in.fpath_0x0024_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0024_0x00=0 +hwmon_in.len_0x0024_0x00=8 +hwmon_in.bit_offset_0x0024_0x00=0 +hwmon_in.str_cons_0x0024_0x00=in7_input +hwmon_in.mode_0x0024_0x01=str_constant +hwmon_in.str_cons_0x0024_0x01=VDDA_0P72_PHY0 +hwmon_in.mode_0x0024_0x02=str_constant +hwmon_in.str_cons_0x0024_0x02=ucd90160 +hwmon_in.mode_0x0024_0x03=constant +hwmon_in.int_cons_0x0024_0x03=741 +hwmon_in.mode_0x0024_0x05=constant +hwmon_in.int_cons_0x0024_0x05=699 +hwmon_in.mode_0x0024_0x08=constant +hwmon_in.int_cons_0x0024_0x08=720 + +# vol37 +hwmon_in.mode_0x0025_0x00=config +hwmon_in.int_cons_0x0025_0x00=0 +hwmon_in.src_0x0025_0x00=file +hwmon_in.frmt_0x0025_0x00=buf +hwmon_in.fpath_0x0025_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0025_0x00=0 +hwmon_in.len_0x0025_0x00=8 +hwmon_in.bit_offset_0x0025_0x00=0 +hwmon_in.str_cons_0x0025_0x00=in9_input +hwmon_in.mode_0x0025_0x01=str_constant +hwmon_in.str_cons_0x0025_0x01=VDDA1.2V +hwmon_in.mode_0x0025_0x02=str_constant +hwmon_in.str_cons_0x0025_0x02=ucd90160 +hwmon_in.mode_0x0025_0x03=constant +hwmon_in.int_cons_0x0025_0x03=1320 +hwmon_in.mode_0x0025_0x05=constant +hwmon_in.int_cons_0x0025_0x05=1080 +hwmon_in.mode_0x0025_0x08=constant +hwmon_in.int_cons_0x0025_0x08=1200 + +# vol38 +monitor_flag_hwmon_in.mode_0x0026_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0026_0x00=0 +hwmon_in.mode_0x0026_0x00=config +hwmon_in.int_cons_0x0026_0x00=0 +hwmon_in.src_0x0026_0x00=file +hwmon_in.frmt_0x0026_0x00=buf +hwmon_in.fpath_0x0026_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0026_0x00=0 +hwmon_in.len_0x0026_0x00=8 +hwmon_in.bit_offset_0x0026_0x00= +hwmon_in.str_cons_0x0026_0x00=in10_input +hwmon_in.mode_0x0026_0x01=str_constant +hwmon_in.str_cons_0x0026_0x01=VDD_CORE +hwmon_in.mode_0x0026_0x02=str_constant +hwmon_in.str_cons_0x0026_0x02=ucd90160 +hwmon_in.mode_0x0026_0x03=constant +hwmon_in.int_cons_0x0026_0x03=900 +hwmon_in.mode_0x0026_0x05=constant +hwmon_in.int_cons_0x0026_0x05=600 +hwmon_in.mode_0x0026_0x08=constant +hwmon_in.int_cons_0x0026_0x08=800 + +# vol39 +monitor_flag_hwmon_in.mode_0x0027_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0027_0x00=0 +hwmon_in.mode_0x0027_0x00=config +hwmon_in.int_cons_0x0027_0x00=0 +hwmon_in.src_0x0027_0x00=file +hwmon_in.frmt_0x0027_0x00=buf +hwmon_in.fpath_0x0027_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0027_0x00=0 +hwmon_in.len_0x0027_0x00=8 +hwmon_in.bit_offset_0x0027_0x00= +hwmon_in.str_cons_0x0027_0x00=in10_input +hwmon_in.mode_0x0027_0x01=str_constant +hwmon_in.str_cons_0x0027_0x01=VDD_PHYTILE0 +hwmon_in.mode_0x0027_0x02=str_constant +hwmon_in.str_cons_0x0027_0x02=ucd90160 +hwmon_in.mode_0x0027_0x03=constant +hwmon_in.int_cons_0x0027_0x03=808 +hwmon_in.mode_0x0027_0x05=constant +hwmon_in.int_cons_0x0027_0x05=792 +hwmon_in.mode_0x0027_0x08=constant +hwmon_in.int_cons_0x0027_0x08=800 + +# vol40 +hwmon_in.mode_0x0028_0x00=config +hwmon_in.int_cons_0x0028_0x00=0 +hwmon_in.src_0x0028_0x00=file +hwmon_in.frmt_0x0028_0x00=buf +hwmon_in.fpath_0x0028_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0028_0x00=0 +hwmon_in.len_0x0028_0x00=8 +hwmon_in.bit_offset_0x0028_0x00= +hwmon_in.str_cons_0x0028_0x00=in12_input +hwmon_in.mode_0x0028_0x01=str_constant +hwmon_in.str_cons_0x0028_0x01=VDDA0.8V +hwmon_in.mode_0x0028_0x02=str_constant +hwmon_in.str_cons_0x0028_0x02=ucd90160 +hwmon_in.mode_0x0028_0x03=constant +hwmon_in.int_cons_0x0028_0x03=880 +hwmon_in.mode_0x0028_0x05=constant +hwmon_in.int_cons_0x0028_0x05=600 +hwmon_in.mode_0x0028_0x08=constant +hwmon_in.int_cons_0x0028_0x08=800 + +# vol41 +monitor_flag_hwmon_in.mode_0x0029_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0029_0x00=0 +hwmon_in.mode_0x0029_0x00=config +hwmon_in.int_cons_0x0029_0x00=0 +hwmon_in.src_0x0029_0x00=file +hwmon_in.frmt_0x0029_0x00=buf +hwmon_in.fpath_0x0029_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x0029_0x00=0 +hwmon_in.len_0x0029_0x00=8 +hwmon_in.bit_offset_0x0029_0x00=0 +hwmon_in.str_cons_0x0029_0x00=in14_input +hwmon_in.mode_0x0029_0x01=str_constant +hwmon_in.str_cons_0x0029_0x01=VDD_0.9V_PLL0 +hwmon_in.mode_0x0029_0x02=str_constant +hwmon_in.str_cons_0x0029_0x02=990 +hwmon_in.mode_0x0029_0x03=constant +hwmon_in.int_cons_0x0029_0x03=810 +hwmon_in.mode_0x0029_0x05=constant +hwmon_in.int_cons_0x0029_0x05=900 + +# vol42 +monitor_flag_hwmon_in.mode_0x002a_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002a_0x00=0 +hwmon_in.mode_0x002a_0x00=config +hwmon_in.int_cons_0x002a_0x00=0 +hwmon_in.src_0x002a_0x00=file +hwmon_in.frmt_0x002a_0x00=buf +hwmon_in.fpath_0x002a_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x002a_0x00=0 +hwmon_in.len_0x002a_0x00=8 +hwmon_in.bit_offset_0x002a_0x00= +hwmon_in.str_cons_0x002a_0x00=in15_input +hwmon_in.mode_0x002a_0x01=str_constant +hwmon_in.str_cons_0x002a_0x01=VDD_0P75_ANA_0 +hwmon_in.mode_0x002a_0x02=str_constant +hwmon_in.str_cons_0x002a_0x02=ucd90160 +hwmon_in.mode_0x002a_0x03=constant +hwmon_in.int_cons_0x002a_0x03=825 +hwmon_in.mode_0x002a_0x05=constant +hwmon_in.int_cons_0x002a_0x05=675 +hwmon_in.mode_0x002a_0x08=constant +hwmon_in.int_cons_0x002a_0x08=750 + +# vol43 +monitor_flag_hwmon_in.mode_0x002b_0x00=constant +monitor_flag_hwmon_in.int_cons_0x002b_0x00=0 +hwmon_in.mode_0x002b_0x00=config +hwmon_in.int_cons_0x002b_0x00=0 +hwmon_in.src_0x002b_0x00=file +hwmon_in.frmt_0x002b_0x00=buf +hwmon_in.fpath_0x002b_0x00=/sys/bus/i2c/devices/84-005b/hwmon/ +hwmon_in.addr_0x002b_0x00=0 +hwmon_in.len_0x002b_0x00=8 +hwmon_in.bit_offset_0x002b_0x00= +hwmon_in.str_cons_0x002b_0x00=in16_input +hwmon_in.mode_0x002b_0x01=str_constant +hwmon_in.str_cons_0x002b_0x01=VDDO1.2V +hwmon_in.mode_0x002b_0x02=str_constant +hwmon_in.str_cons_0x002b_0x02=ucd90160 +hwmon_in.mode_0x002b_0x03=constant +hwmon_in.int_cons_0x002b_0x03=13200 +hwmon_in.mode_0x002b_0x05=constant +hwmon_in.int_cons_0x002b_0x05=10800 +hwmon_in.mode_0x002b_0x08=constant +hwmon_in.int_cons_0x002b_0x08=12000 + +# vol44 +hwmon_in.mode_0x002c_0x00=config +hwmon_in.int_cons_0x002c_0x00=0 +hwmon_in.src_0x002c_0x00=file +hwmon_in.frmt_0x002c_0x00=buf +hwmon_in.fpath_0x002c_0x00=/sys/bus/i2c/devices/85-0060/hwmon/ +hwmon_in.addr_0x002c_0x00=0 +hwmon_in.len_0x002c_0x00=8 +hwmon_in.bit_offset_0x002c_0x00= +hwmon_in.str_cons_0x002c_0x00=in3_input +hwmon_in.mode_0x002c_0x01=str_constant +hwmon_in.str_cons_0x002c_0x01=VDD_CORE +hwmon_in.mode_0x002c_0x02=str_constant +hwmon_in.str_cons_0x002c_0x02=xdpe1a2g5b +hwmon_in.mode_0x002c_0x03=constant +hwmon_in.int_cons_0x002c_0x03=920 +hwmon_in.mode_0x002c_0x05=constant +hwmon_in.int_cons_0x002c_0x05=580 +hwmon_in.mode_0x002c_0x08=constant +hwmon_in.int_cons_0x002c_0x08=800 + +# vol45 +hwmon_in.mode_0x002d_0x00=config +hwmon_in.int_cons_0x002d_0x00=3 +hwmon_in.src_0x002d_0x00=file +hwmon_in.frmt_0x002d_0x00=buf +hwmon_in.fpath_0x002d_0x00=/sys/bus/i2c/devices/91-0060/hwmon/ +hwmon_in.addr_0x002d_0x00=0 +hwmon_in.len_0x002d_0x00=8 +hwmon_in.bit_offset_0x002d_0x00= +hwmon_in.str_cons_0x002d_0x00=in3_input +hwmon_in.mode_0x002d_0x01=str_constant +hwmon_in.str_cons_0x002d_0x01=OSFP_VDD3.3V_A1 +hwmon_in.mode_0x002d_0x02=str_constant +hwmon_in.str_cons_0x002d_0x02=xdpe12284c +hwmon_in.mode_0x002d_0x03=constant +hwmon_in.int_cons_0x002d_0x03=3630 +hwmon_in.mode_0x002d_0x05=constant +hwmon_in.int_cons_0x002d_0x05=2970 +hwmon_in.mode_0x002d_0x08=constant +hwmon_in.int_cons_0x002d_0x08=3300 +hwmon_in.int_extra1_0x002d_0x00=1500 + +# vol46 +hwmon_in.mode_0x002e_0x00=config +hwmon_in.int_cons_0x002e_0x00=3 +hwmon_in.src_0x002e_0x00=file +hwmon_in.frmt_0x002e_0x00=buf +hwmon_in.fpath_0x002e_0x00=/sys/bus/i2c/devices/92-0060/hwmon/ +hwmon_in.addr_0x002e_0x00=0 +hwmon_in.len_0x002e_0x00=8 +hwmon_in.bit_offset_0x002e_0x00=0 +hwmon_in.str_cons_0x002e_0x00=in3_input +hwmon_in.mode_0x002e_0x01=str_constant +hwmon_in.str_cons_0x002e_0x01=OSFP_VDD3.3V_A2 +hwmon_in.mode_0x002e_0x02=str_constant +hwmon_in.str_cons_0x002e_0x02=xdpe12284c +hwmon_in.mode_0x002e_0x03=constant +hwmon_in.int_cons_0x002e_0x03=3630 +hwmon_in.mode_0x002e_0x05=constant +hwmon_in.int_cons_0x002e_0x05=2970 +hwmon_in.mode_0x002e_0x08=constant +hwmon_in.int_cons_0x002e_0x08=3300 +hwmon_in.int_extra1_0x002e_0x00=1500 + +# vol47 +hwmon_in.mode_0x002f_0x00=config +hwmon_in.int_cons_0x002f_0x00=3 +hwmon_in.src_0x002f_0x00=file +hwmon_in.frmt_0x002f_0x00=buf +hwmon_in.fpath_0x002f_0x00=/sys/bus/i2c/devices/91-0062/hwmon/ +hwmon_in.addr_0x002f_0x00=0 +hwmon_in.len_0x002f_0x00=8 +hwmon_in.bit_offset_0x002f_0x00=0 +hwmon_in.str_cons_0x002f_0x00=in3_input +hwmon_in.mode_0x002f_0x01=str_constant +hwmon_in.str_cons_0x002f_0x01=OSFP_VDD3.3V_A3 +hwmon_in.mode_0x002f_0x02=str_constant +hwmon_in.str_cons_0x002f_0x02=xdpe12284c +hwmon_in.mode_0x002f_0x03=constant +hwmon_in.int_cons_0x002f_0x03=3630 +hwmon_in.mode_0x002f_0x05=constant +hwmon_in.int_cons_0x002f_0x05=2970 +hwmon_in.mode_0x002f_0x08=constant +hwmon_in.int_cons_0x002f_0x08=3300 +hwmon_in.int_extra1_0x002f_0x00=1500 + +# vol48 +hwmon_in.mode_0x0030_0x00=config +hwmon_in.int_cons_0x0030_0x00=3 +hwmon_in.src_0x0030_0x00=file +hwmon_in.frmt_0x0030_0x00=buf +hwmon_in.fpath_0x0030_0x00=/sys/bus/i2c/devices/91-0062/hwmon/ +hwmon_in.addr_0x0030_0x00=0 +hwmon_in.len_0x0030_0x00=8 +hwmon_in.bit_offset_0x0030_0x00=0 +hwmon_in.str_cons_0x0030_0x00=in4_input +hwmon_in.mode_0x0030_0x01=str_constant +hwmon_in.str_cons_0x0030_0x01=OSFP_VDD3.3V_B3 +hwmon_in.mode_0x0030_0x02=str_constant +hwmon_in.str_cons_0x0030_0x02=xdpe12284c +hwmon_in.mode_0x0030_0x03=constant +hwmon_in.int_cons_0x0030_0x03=3630 +hwmon_in.mode_0x0030_0x05=constant +hwmon_in.int_cons_0x0030_0x05=2970 +hwmon_in.mode_0x0030_0x08=constant +hwmon_in.int_cons_0x0030_0x08=3300 +hwmon_in.int_extra1_0x0030_0x00=1500 + +# vol49 +hwmon_in.mode_0x0031_0x00=config +hwmon_in.int_cons_0x0031_0x00=3 +hwmon_in.src_0x0031_0x00=file +hwmon_in.frmt_0x0031_0x00=buf +hwmon_in.fpath_0x0031_0x00=/sys/bus/i2c/devices/92-0062/hwmon/ +hwmon_in.addr_0x0031_0x00=0 +hwmon_in.len_0x0031_0x00=8 +hwmon_in.bit_offset_0x0031_0x00=0 +hwmon_in.str_cons_0x0031_0x00=in3_input +hwmon_in.mode_0x0031_0x01=str_constant +hwmon_in.str_cons_0x0031_0x01=OSFP_VDD3.3V_A4 +hwmon_in.mode_0x0031_0x02=str_constant +hwmon_in.str_cons_0x0031_0x02=xdpe12284c +hwmon_in.mode_0x0031_0x03=constant +hwmon_in.int_cons_0x0031_0x03=3630 +hwmon_in.mode_0x0031_0x05=constant +hwmon_in.int_cons_0x0031_0x05=2970 +hwmon_in.mode_0x0031_0x08=constant +hwmon_in.int_cons_0x0031_0x08=3300 +hwmon_in.int_extra1_0x0031_0x00=1500 + +# vol50 +hwmon_in.mode_0x0032_0x00=config +hwmon_in.int_cons_0x0032_0x00=3 +hwmon_in.src_0x0032_0x00=file +hwmon_in.frmt_0x0032_0x00=buf +hwmon_in.fpath_0x0032_0x00=/sys/bus/i2c/devices/92-0062/hwmon/ +hwmon_in.addr_0x0032_0x00=0 +hwmon_in.len_0x0032_0x00=8 +hwmon_in.bit_offset_0x0032_0x00=0 +hwmon_in.str_cons_0x0032_0x00=in4_input +hwmon_in.mode_0x0032_0x01=str_constant +hwmon_in.str_cons_0x0032_0x01=OSFP_VDD3.3V_B4 +hwmon_in.mode_0x0032_0x02=str_constant +hwmon_in.str_cons_0x0032_0x02=xdpe12284c +hwmon_in.mode_0x0032_0x03=constant +hwmon_in.int_cons_0x0032_0x03=3630 +hwmon_in.mode_0x0032_0x05=constant +hwmon_in.int_cons_0x0032_0x05=2970 +hwmon_in.mode_0x0032_0x08=constant +hwmon_in.int_cons_0x0032_0x08=3300 +hwmon_in.int_extra1_0x0032_0x00=1500 + +# vol51 +hwmon_in.mode_0x0033_0x00=config +hwmon_in.int_cons_0x0033_0x00=0 +hwmon_in.src_0x0033_0x00=file +hwmon_in.frmt_0x0033_0x00=buf +hwmon_in.fpath_0x0033_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_in.addr_0x0033_0x00=0 +hwmon_in.len_0x0033_0x00=8 +hwmon_in.bit_offset_0x0033_0x00=0 +hwmon_in.str_cons_0x0033_0x00=in3_input +hwmon_in.mode_0x0033_0x01=str_constant +hwmon_in.str_cons_0x0033_0x01=VDD_PHYTILE6 +hwmon_in.mode_0x0033_0x02=str_constant +hwmon_in.str_cons_0x0033_0x02=xdpe12284c +hwmon_in.mode_0x0033_0x03=constant +hwmon_in.int_cons_0x0033_0x03=880 +hwmon_in.mode_0x0033_0x05=constant +hwmon_in.int_cons_0x0033_0x05=600 +hwmon_in.mode_0x0033_0x08=constant +hwmon_in.int_cons_0x0033_0x08=800 + +# vol52 +hwmon_in.mode_0x0034_0x00=config +hwmon_in.int_cons_0x0034_0x00=0 +hwmon_in.src_0x0034_0x00=file +hwmon_in.frmt_0x0034_0x00=buf +hwmon_in.fpath_0x0034_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_in.addr_0x0034_0x00=0 +hwmon_in.len_0x0034_0x00=8 +hwmon_in.bit_offset_0x0034_0x00=0 +hwmon_in.str_cons_0x0034_0x00=in4_input +hwmon_in.mode_0x0034_0x01=str_constant +hwmon_in.str_cons_0x0034_0x01=VDD_PHYTILE7 +hwmon_in.mode_0x0034_0x02=str_constant +hwmon_in.str_cons_0x0034_0x02=xdpe12284c +hwmon_in.mode_0x0034_0x03=constant +hwmon_in.int_cons_0x0034_0x03=880 +hwmon_in.mode_0x0034_0x05=constant +hwmon_in.int_cons_0x0034_0x05=600 +hwmon_in.mode_0x0034_0x08=constant +hwmon_in.int_cons_0x0034_0x08=800 + +# vol53 +hwmon_in.mode_0x0035_0x00=config +hwmon_in.int_cons_0x0035_0x00=0 +hwmon_in.src_0x0035_0x00=file +hwmon_in.frmt_0x0035_0x00=buf +hwmon_in.fpath_0x0035_0x00=/sys/bus/i2c/devices/85-0074/hwmon/ +hwmon_in.addr_0x0035_0x00=0 +hwmon_in.len_0x0035_0x00=8 +hwmon_in.bit_offset_0x0035_0x00=0 +hwmon_in.str_cons_0x0035_0x00=in3_input +hwmon_in.mode_0x0035_0x01=str_constant +hwmon_in.str_cons_0x0035_0x01=VDDA_0P72_PHY2 +hwmon_in.mode_0x0035_0x02=str_constant +hwmon_in.str_cons_0x0035_0x02=xdpe12284c +hwmon_in.mode_0x0035_0x03=constant +hwmon_in.int_cons_0x0035_0x03=820 +hwmon_in.mode_0x0035_0x05=constant +hwmon_in.int_cons_0x0035_0x05=650 +hwmon_in.mode_0x0035_0x08=constant +hwmon_in.int_cons_0x0035_0x08=720 + +# vol54 +hwmon_in.mode_0x0036_0x00=config +hwmon_in.int_cons_0x0036_0x00=0 +hwmon_in.src_0x0036_0x00=file +hwmon_in.frmt_0x0036_0x00=buf +hwmon_in.fpath_0x0036_0x00=/sys/bus/i2c/devices/85-0074/hwmon/ +hwmon_in.addr_0x0036_0x00=0 +hwmon_in.len_0x0036_0x00=8 +hwmon_in.bit_offset_0x0036_0x00=0 +hwmon_in.str_cons_0x0036_0x00=in4_input +hwmon_in.mode_0x0036_0x01=str_constant +hwmon_in.str_cons_0x0036_0x01=VDDA_0P72_PHY1 +hwmon_in.mode_0x0036_0x02=str_constant +hwmon_in.str_cons_0x0036_0x02=xdpe12284c +hwmon_in.mode_0x0036_0x03=constant +hwmon_in.int_cons_0x0036_0x03=820 +hwmon_in.mode_0x0036_0x05=constant +hwmon_in.int_cons_0x0036_0x05=620 +hwmon_in.mode_0x0036_0x08=constant +hwmon_in.int_cons_0x0036_0x08=720 + +# vol55 +hwmon_in.mode_0x0037_0x00=config +hwmon_in.int_cons_0x0037_0x00=0 +hwmon_in.src_0x0037_0x00=file +hwmon_in.frmt_0x0037_0x00=buf +hwmon_in.fpath_0x0037_0x00=/sys/bus/i2c/devices/87-0074/hwmon/ +hwmon_in.addr_0x0037_0x00=0 +hwmon_in.len_0x0037_0x00=8 +hwmon_in.bit_offset_0x0037_0x00=0 +hwmon_in.str_cons_0x0037_0x00=in4_input +hwmon_in.mode_0x0037_0x01=str_constant +hwmon_in.str_cons_0x0037_0x01=VDDA_0P72_PHY0 +hwmon_in.mode_0x0037_0x02=str_constant +hwmon_in.str_cons_0x0037_0x02=xdpe12284c +hwmon_in.mode_0x0037_0x03=constant +hwmon_in.int_cons_0x0037_0x03=820 +hwmon_in.mode_0x0037_0x05=constant +hwmon_in.int_cons_0x0037_0x05=650 +hwmon_in.mode_0x0037_0x08=constant +hwmon_in.int_cons_0x0037_0x08=720 + +# vol56 +hwmon_in.mode_0x0038_0x00=config +hwmon_in.int_cons_0x0038_0x00=0 +hwmon_in.src_0x0038_0x00=file +hwmon_in.frmt_0x0038_0x00=buf +hwmon_in.fpath_0x0038_0x00=/sys/bus/i2c/devices/87-0074/hwmon/ +hwmon_in.addr_0x0038_0x00=0 +hwmon_in.len_0x0038_0x00=8 +hwmon_in.bit_offset_0x0038_0x00=0 +hwmon_in.str_cons_0x0038_0x00=in4_input +hwmon_in.mode_0x0038_0x01=str_constant +hwmon_in.str_cons_0x0038_0x01=VDDA_0P72_PHY3 +hwmon_in.mode_0x0038_0x02=str_constant +hwmon_in.str_cons_0x0038_0x02=xdpe12284c +hwmon_in.mode_0x0038_0x03=constant +hwmon_in.int_cons_0x0038_0x03=820 +hwmon_in.mode_0x0038_0x05=constant +hwmon_in.int_cons_0x0038_0x05=650 +hwmon_in.mode_0x0038_0x08=constant +hwmon_in.int_cons_0x0038_0x08=720 + +# vol57 +hwmon_in.mode_0x0039_0x00=config +hwmon_in.int_cons_0x0039_0x00=0 +hwmon_in.src_0x0039_0x00=file +hwmon_in.frmt_0x0039_0x00=buf +hwmon_in.fpath_0x0039_0x00=/sys/bus/i2c/devices/89-0074/hwmon/ +hwmon_in.addr_0x0039_0x00=0 +hwmon_in.len_0x0039_0x00=8 +hwmon_in.bit_offset_0x0039_0x00=0 +hwmon_in.str_cons_0x0039_0x00=in3_input +hwmon_in.mode_0x0039_0x01=str_constant +hwmon_in.str_cons_0x0039_0x01=VDD_1P5V_0 +hwmon_in.mode_0x0039_0x02=str_constant +hwmon_in.str_cons_0x0039_0x02=xdpe12284c +hwmon_in.mode_0x0039_0x03=constant +hwmon_in.int_cons_0x0039_0x03=1650 +hwmon_in.mode_0x0039_0x05=constant +hwmon_in.int_cons_0x0039_0x05=1350 +hwmon_in.mode_0x0039_0x08=constant +hwmon_in.int_cons_0x0039_0x08=1500 + +# vol58 +hwmon_in.mode_0x003a_0x00=config +hwmon_in.int_cons_0x003a_0x00=0 +hwmon_in.src_0x003a_0x00=file +hwmon_in.frmt_0x003a_0x00=buf +hwmon_in.fpath_0x003a_0x00=/sys/bus/i2c/devices/89-0074/hwmon/ +hwmon_in.addr_0x003a_0x00=0 +hwmon_in.len_0x003a_0x00=8 +hwmon_in.bit_offset_0x003a_0x00=0 +hwmon_in.str_cons_0x003a_0x00=in4_input +hwmon_in.mode_0x003a_0x01=str_constant +hwmon_in.str_cons_0x003a_0x01=VDD_1P5V_1 +hwmon_in.mode_0x003a_0x02=str_constant +hwmon_in.str_cons_0x003a_0x02=xdpe12284c +hwmon_in.mode_0x003a_0x03=constant +hwmon_in.int_cons_0x003a_0x03=1650 +hwmon_in.mode_0x003a_0x05=constant +hwmon_in.int_cons_0x003a_0x05=1350 +hwmon_in.mode_0x003a_0x08=constant +hwmon_in.int_cons_0x003a_0x08=1500 + +# vol59 +hwmon_in.mode_0x003b_0x00=config +hwmon_in.int_cons_0x003b_0x00=0 +hwmon_in.src_0x003b_0x00=file +hwmon_in.frmt_0x003b_0x00=buf +hwmon_in.fpath_0x003b_0x00=/sys/bus/i2c/devices/85-0062/hwmon/ +hwmon_in.addr_0x003b_0x00=0 +hwmon_in.len_0x003b_0x00=8 +hwmon_in.bit_offset_0x003b_0x00=0 +hwmon_in.str_cons_0x003b_0x00=in3_input +hwmon_in.mode_0x003b_0x01=str_constant +hwmon_in.str_cons_0x003b_0x01=VDD0_9V_ANLG0 +hwmon_in.mode_0x003b_0x02=str_constant +hwmon_in.str_cons_0x003b_0x02=xdpe12284c +hwmon_in.mode_0x003b_0x03=constant +hwmon_in.int_cons_0x003b_0x03=990 +hwmon_in.mode_0x003b_0x05=constant +hwmon_in.int_cons_0x003b_0x05=810 +hwmon_in.mode_0x003b_0x08=constant +hwmon_in.int_cons_0x003b_0x08=900 + +# vol60 +hwmon_in.mode_0x003c_0x00=config +hwmon_in.int_cons_0x003c_0x00=0 +hwmon_in.src_0x003c_0x00=file +hwmon_in.frmt_0x003c_0x00=buf +hwmon_in.fpath_0x003c_0x00=/sys/bus/i2c/devices/85-0062/hwmon/ +hwmon_in.addr_0x003c_0x00=0 +hwmon_in.len_0x003c_0x00=8 +hwmon_in.bit_offset_0x003c_0x00=0 +hwmon_in.str_cons_0x003c_0x00=in4_input +hwmon_in.mode_0x003c_0x01=str_constant +hwmon_in.str_cons_0x003c_0x01=VDD0_75V_ANLG0 +hwmon_in.mode_0x003c_0x02=str_constant +hwmon_in.str_cons_0x003c_0x02=xdpe12284c +hwmon_in.mode_0x003c_0x03=constant +hwmon_in.int_cons_0x003c_0x03=825 +hwmon_in.mode_0x003c_0x05=constant +hwmon_in.int_cons_0x003c_0x05=675 +hwmon_in.mode_0x003c_0x08=constant +hwmon_in.int_cons_0x003c_0x08=750 + +# vol61 +hwmon_in.mode_0x003d_0x00=config +hwmon_in.int_cons_0x003d_0x00=0 +hwmon_in.src_0x003d_0x00=file +hwmon_in.frmt_0x003d_0x00=buf +hwmon_in.fpath_0x003d_0x00=/sys/bus/i2c/devices/87-0062/hwmon/ +hwmon_in.addr_0x003d_0x00=0 +hwmon_in.len_0x003d_0x00=8 +hwmon_in.bit_offset_0x003d_0x00=0 +hwmon_in.str_cons_0x003d_0x00=in3_input +hwmon_in.mode_0x003d_0x01=str_constant +hwmon_in.str_cons_0x003d_0x01=VDD0_9V_ANLG1 +hwmon_in.mode_0x003d_0x02=str_constant +hwmon_in.str_cons_0x003d_0x02=xdpe12284c +hwmon_in.mode_0x003d_0x03=constant +hwmon_in.int_cons_0x003d_0x03=990 +hwmon_in.mode_0x003d_0x05=constant +hwmon_in.int_cons_0x003d_0x05=810 +hwmon_in.mode_0x003d_0x08=constant +hwmon_in.int_cons_0x003d_0x08=900 + +# vol62 +hwmon_in.mode_0x003e_0x00=config +hwmon_in.int_cons_0x003e_0x00=0 +hwmon_in.src_0x003e_0x00=file +hwmon_in.frmt_0x003e_0x00=buf +hwmon_in.fpath_0x003e_0x00=/sys/bus/i2c/devices/87-0062/hwmon/ +hwmon_in.addr_0x003e_0x00=0 +hwmon_in.len_0x003e_0x00=8 +hwmon_in.bit_offset_0x003e_0x00=0 +hwmon_in.str_cons_0x003e_0x00=in4_input +hwmon_in.mode_0x003e_0x01=str_constant +hwmon_in.str_cons_0x003e_0x01=VDD0_75V_ANLG1 +hwmon_in.mode_0x003e_0x02=str_constant +hwmon_in.str_cons_0x003e_0x02=xdpe12284c +hwmon_in.mode_0x003e_0x03=constant +hwmon_in.int_cons_0x003e_0x03=825 +hwmon_in.mode_0x003e_0x05=constant +hwmon_in.int_cons_0x003e_0x05=675 +hwmon_in.mode_0x003e_0x08=constant +hwmon_in.int_cons_0x003e_0x08=750 + +# vol63 +hwmon_in.mode_0x003f_0x00=config +hwmon_in.int_cons_0x003f_0x00=0 +hwmon_in.src_0x003f_0x00=file +hwmon_in.frmt_0x003f_0x00=buf +hwmon_in.fpath_0x003f_0x00=/sys/bus/i2c/devices/87-0060/hwmon/ +hwmon_in.addr_0x003f_0x00=0 +hwmon_in.len_0x003f_0x00=8 +hwmon_in.bit_offset_0x003f_0x00=0 +hwmon_in.str_cons_0x003f_0x00=in3_input +hwmon_in.mode_0x003f_0x01=str_constant +hwmon_in.str_cons_0x003f_0x01=VDD_PHYTILE1 +hwmon_in.mode_0x003f_0x02=str_constant +hwmon_in.str_cons_0x003f_0x02=xdpe12284c +hwmon_in.mode_0x003f_0x03=constant +hwmon_in.int_cons_0x003f_0x03=880 +hwmon_in.mode_0x003f_0x05=constant +hwmon_in.int_cons_0x003f_0x05=600 +hwmon_in.mode_0x003f_0x08=constant +hwmon_in.int_cons_0x003f_0x08=800 + +# vol64 +hwmon_in.mode_0x0040_0x00=config +hwmon_in.int_cons_0x0040_0x00=0 +hwmon_in.src_0x0040_0x00=file +hwmon_in.frmt_0x0040_0x00=buf +hwmon_in.fpath_0x0040_0x00=/sys/bus/i2c/devices/87-0060/hwmon/ +hwmon_in.addr_0x0040_0x00=0 +hwmon_in.len_0x0040_0x00=8 +hwmon_in.bit_offset_0x0040_0x00=0 +hwmon_in.str_cons_0x0040_0x00=in4_input +hwmon_in.mode_0x0040_0x01=str_constant +hwmon_in.str_cons_0x0040_0x01=VDD_PHYTILE0 +hwmon_in.mode_0x0040_0x02=str_constant +hwmon_in.str_cons_0x0040_0x02=xdpe12284c +hwmon_in.mode_0x0040_0x03=constant +hwmon_in.int_cons_0x0040_0x03=880 +hwmon_in.mode_0x0040_0x05=constant +hwmon_in.int_cons_0x0040_0x05=600 +hwmon_in.mode_0x0040_0x08=constant +hwmon_in.int_cons_0x0040_0x08=800 + +# vol65 +hwmon_in.mode_0x0041_0x00=config +hwmon_in.int_cons_0x0041_0x00=0 +hwmon_in.src_0x0041_0x00=file +hwmon_in.frmt_0x0041_0x00=buf +hwmon_in.fpath_0x0041_0x00=/sys/bus/i2c/devices/89-0060/hwmon/ +hwmon_in.addr_0x0041_0x00=0 +hwmon_in.len_0x0041_0x00=8 +hwmon_in.bit_offset_0x0041_0x00=0 +hwmon_in.str_cons_0x0041_0x00=in3_input +hwmon_in.mode_0x0041_0x01=str_constant +hwmon_in.str_cons_0x0041_0x01=VDD_PHYTILE2 +hwmon_in.mode_0x0041_0x02=str_constant +hwmon_in.str_cons_0x0041_0x02=xdpe12284c +hwmon_in.mode_0x0041_0x03=constant +hwmon_in.int_cons_0x0041_0x03=880 +hwmon_in.mode_0x0041_0x05=constant +hwmon_in.int_cons_0x0041_0x05=600 +hwmon_in.mode_0x0041_0x08=constant +hwmon_in.int_cons_0x0041_0x08=800 + +# vol66 +hwmon_in.mode_0x0042_0x00=config +hwmon_in.int_cons_0x0042_0x00=0 +hwmon_in.src_0x0042_0x00=file +hwmon_in.frmt_0x0042_0x00=buf +hwmon_in.fpath_0x0042_0x00=/sys/bus/i2c/devices/89-0060/hwmon/ +hwmon_in.addr_0x0042_0x00=0 +hwmon_in.len_0x0042_0x00=8 +hwmon_in.bit_offset_0x0042_0x00=0 +hwmon_in.str_cons_0x0042_0x00=in4_input +hwmon_in.mode_0x0042_0x01=str_constant +hwmon_in.str_cons_0x0042_0x01=VDD_PHYTILE3 +hwmon_in.mode_0x0042_0x02=str_constant +hwmon_in.str_cons_0x0042_0x02=xdpe12284c +hwmon_in.mode_0x0042_0x03=constant +hwmon_in.int_cons_0x0042_0x03=880 +hwmon_in.mode_0x0042_0x05=constant +hwmon_in.int_cons_0x0042_0x05=600 +hwmon_in.mode_0x0042_0x08=constant +hwmon_in.int_cons_0x0042_0x08=800 + +# vol67 +hwmon_in.mode_0x0043_0x00=config +hwmon_in.int_cons_0x0043_0x00=0 +hwmon_in.src_0x0043_0x00=file +hwmon_in.frmt_0x0043_0x00=buf +hwmon_in.fpath_0x0043_0x00=/sys/bus/i2c/devices/90-0060/hwmon/ +hwmon_in.addr_0x0043_0x00=0 +hwmon_in.len_0x0043_0x00=8 +hwmon_in.bit_offset_0x0043_0x00=0 +hwmon_in.str_cons_0x0043_0x00=in3_input +hwmon_in.mode_0x0043_0x01=str_constant +hwmon_in.str_cons_0x0043_0x01=VDD_PHYTILE4 +hwmon_in.mode_0x0043_0x02=str_constant +hwmon_in.str_cons_0x0043_0x02=xdpe12284c +hwmon_in.mode_0x0043_0x03=constant +hwmon_in.int_cons_0x0043_0x03=880 +hwmon_in.mode_0x0043_0x05=constant +hwmon_in.int_cons_0x0043_0x05=600 +hwmon_in.mode_0x0043_0x08=constant +hwmon_in.int_cons_0x0043_0x08=800 + +# vol68 +hwmon_in.mode_0x0044_0x00=config +hwmon_in.int_cons_0x0044_0x00=0 +hwmon_in.src_0x0044_0x00=file +hwmon_in.frmt_0x0044_0x00=buf +hwmon_in.fpath_0x0044_0x00=/sys/bus/i2c/devices/90-0060/hwmon/ +hwmon_in.addr_0x0044_0x00=0 +hwmon_in.len_0x0044_0x00=8 +hwmon_in.bit_offset_0x0044_0x00=0 +hwmon_in.str_cons_0x0044_0x00=in4_input +hwmon_in.mode_0x0044_0x01=str_constant +hwmon_in.str_cons_0x0044_0x01=VDD_PHYTILE5 +hwmon_in.mode_0x0044_0x02=str_constant +hwmon_in.str_cons_0x0044_0x02=xdpe12284c +hwmon_in.mode_0x0044_0x03=constant +hwmon_in.int_cons_0x0044_0x03=880 +hwmon_in.mode_0x0044_0x05=constant +hwmon_in.int_cons_0x0044_0x05=600 +hwmon_in.mode_0x0044_0x08=constant +hwmon_in.int_cons_0x0044_0x08=800 + +# vol69 +hwmon_in.mode_0x0045_0x00=config +hwmon_in.int_cons_0x0045_0x00=0 +hwmon_in.src_0x0045_0x00=file +hwmon_in.frmt_0x0045_0x00=buf +hwmon_in.fpath_0x0045_0x00=/sys/bus/i2c/devices/98-0040/hwmon/ +hwmon_in.addr_0x0045_0x00=0 +hwmon_in.len_0x0045_0x00=8 +hwmon_in.bit_offset_0x0045_0x00=0 +hwmon_in.str_cons_0x0045_0x00=in1_input +hwmon_in.mode_0x0045_0x01=str_constant +hwmon_in.str_cons_0x0045_0x01=VDDO1.2V +hwmon_in.mode_0x0045_0x02=str_constant +hwmon_in.str_cons_0x0045_0x02=xdpe12284c +hwmon_in.mode_0x0045_0x03=constant +hwmon_in.int_cons_0x0045_0x03=1320 +hwmon_in.mode_0x0045_0x05=constant +hwmon_in.int_cons_0x0045_0x05=800 +hwmon_in.mode_0x0045_0x08=constant +hwmon_in.int_cons_0x0045_0x08=1200 + +# vol70 +hwmon_in.mode_0x0046_0x00=config +hwmon_in.int_cons_0x0046_0x00=0 +hwmon_in.src_0x0046_0x00=file +hwmon_in.frmt_0x0046_0x00=buf +hwmon_in.fpath_0x0046_0x00=/sys/bus/i2c/devices/98-0040/hwmon/ +hwmon_in.addr_0x0046_0x00=0 +hwmon_in.len_0x0046_0x00=8 +hwmon_in.bit_offset_0x0046_0x00=0 +hwmon_in.str_cons_0x0046_0x00=in2_input +hwmon_in.mode_0x0046_0x01=str_constant +hwmon_in.str_cons_0x0046_0x01=VDDO1.8V +hwmon_in.mode_0x0046_0x02=str_constant +hwmon_in.str_cons_0x0046_0x02=INA322 +hwmon_in.mode_0x0046_0x03=constant +hwmon_in.int_cons_0x0046_0x03=1980 +hwmon_in.mode_0x0046_0x05=constant +hwmon_in.int_cons_0x0046_0x05=1620 +hwmon_in.mode_0x0046_0x08=constant +hwmon_in.int_cons_0x0046_0x08=1800 + +# vol71 +hwmon_in.mode_0x0047_0x00=config +hwmon_in.int_cons_0x0047_0x00=0 +hwmon_in.src_0x0047_0x00=file +hwmon_in.frmt_0x0047_0x00=buf +hwmon_in.fpath_0x0047_0x00=/sys/bus/i2c/devices/98-0040/hwmon/ +hwmon_in.addr_0x0047_0x00=0 +hwmon_in.len_0x0047_0x00=8 +hwmon_in.bit_offset_0x0047_0x00=0 +hwmon_in.str_cons_0x0047_0x00=in3_input +hwmon_in.mode_0x0047_0x01=str_constant +hwmon_in.str_cons_0x0047_0x01=VDD2.2V +hwmon_in.mode_0x0047_0x02=str_constant +hwmon_in.str_cons_0x0047_0x02=INA322 +hwmon_in.mode_0x0047_0x03=constant +hwmon_in.int_cons_0x0047_0x03=2420 +hwmon_in.mode_0x0047_0x05=constant +hwmon_in.int_cons_0x0047_0x05=1980 +hwmon_in.mode_0x0047_0x08=constant +hwmon_in.int_cons_0x0047_0x08=2200 + +# vol72 +hwmon_in.mode_0x0048_0x00=config +hwmon_in.int_cons_0x0048_0x00=0 +hwmon_in.src_0x0048_0x00=file +hwmon_in.frmt_0x0048_0x00=buf +hwmon_in.fpath_0x0048_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x0048_0x00=0 +hwmon_in.len_0x0048_0x00=8 +hwmon_in.bit_offset_0x0048_0x00=0 +hwmon_in.str_cons_0x0048_0x00=in0_input +hwmon_in.mode_0x0048_0x01=str_constant +hwmon_in.str_cons_0x0048_0x01=VDD_0.9V_PLL0 +hwmon_in.mode_0x0048_0x02=str_constant +hwmon_in.str_cons_0x0048_0x02=INA322 +hwmon_in.mode_0x0048_0x03=constant +hwmon_in.int_cons_0x0048_0x03=990 +hwmon_in.mode_0x0048_0x05=constant +hwmon_in.int_cons_0x0048_0x05=810 +hwmon_in.mode_0x0048_0x08=constant +hwmon_in.int_cons_0x0048_0x08=900 + +# vol73 +hwmon_in.mode_0x0049_0x00=config +hwmon_in.int_cons_0x0049_0x00=0 +hwmon_in.src_0x0049_0x00=file +hwmon_in.frmt_0x0049_0x00=buf +hwmon_in.fpath_0x0049_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x0049_0x00=0 +hwmon_in.len_0x0049_0x00=8 +hwmon_in.bit_offset_0x0049_0x00=0 +hwmon_in.str_cons_0x0049_0x00=in1_input +hwmon_in.mode_0x0049_0x01=str_constant +hwmon_in.str_cons_0x0049_0x01=VDD_0.9V_PLL1 +hwmon_in.mode_0x0049_0x02=str_constant +hwmon_in.str_cons_0x0049_0x02=ADS7828E +hwmon_in.mode_0x0049_0x03=constant +hwmon_in.int_cons_0x0049_0x03=990 +hwmon_in.mode_0x0049_0x05=constant +hwmon_in.int_cons_0x0049_0x05=810 +hwmon_in.mode_0x0049_0x08=constant +hwmon_in.int_cons_0x0049_0x08=900 + +# vol74 +hwmon_in.mode_0x004a_0x00=config +hwmon_in.int_cons_0x004a_0x00=0 +hwmon_in.src_0x004a_0x00=file +hwmon_in.frmt_0x004a_0x00=buf +hwmon_in.fpath_0x004a_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x004a_0x00=0 +hwmon_in.len_0x004a_0x00=8 +hwmon_in.bit_offset_0x004a_0x00=0 +hwmon_in.str_cons_0x004a_0x00=in2_input +hwmon_in.mode_0x004a_0x01=str_constant +hwmon_in.str_cons_0x004a_0x01=VDD_0.9V_PLL2 +hwmon_in.mode_0x004a_0x02=str_constant +hwmon_in.str_cons_0x004a_0x02=ADS7828E +hwmon_in.mode_0x004a_0x03=constant +hwmon_in.int_cons_0x004a_0x03=990 +hwmon_in.mode_0x004a_0x05=constant +hwmon_in.int_cons_0x004a_0x05=810 +hwmon_in.mode_0x004a_0x08=constant +hwmon_in.int_cons_0x004a_0x08=900 + +# vol75 +hwmon_in.mode_0x004b_0x00=config +hwmon_in.int_cons_0x004b_0x00=0 +hwmon_in.src_0x004b_0x00=file +hwmon_in.frmt_0x004b_0x00=buf +hwmon_in.fpath_0x004b_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x004b_0x00=0 +hwmon_in.len_0x004b_0x00=8 +hwmon_in.bit_offset_0x004b_0x00=0 +hwmon_in.str_cons_0x004b_0x00=in3_input +hwmon_in.mode_0x004b_0x01=str_constant +hwmon_in.str_cons_0x004b_0x01=VDD_0.9V_PLL3 +hwmon_in.mode_0x004b_0x02=str_constant +hwmon_in.str_cons_0x004b_0x02=ADS7828E +hwmon_in.mode_0x004b_0x03=constant +hwmon_in.int_cons_0x004b_0x03=990 +hwmon_in.mode_0x004b_0x05=constant +hwmon_in.int_cons_0x004b_0x05=810 +hwmon_in.mode_0x004b_0x08=constant +hwmon_in.int_cons_0x004b_0x08=900 + +# vol76 +hwmon_in.mode_0x004c_0x00=config +hwmon_in.int_cons_0x004c_0x00=0 +hwmon_in.src_0x004c_0x00=file +hwmon_in.frmt_0x004c_0x00=buf +hwmon_in.fpath_0x004c_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x004c_0x00=0 +hwmon_in.len_0x004c_0x00=8 +hwmon_in.bit_offset_0x004c_0x00=0 +hwmon_in.str_cons_0x004c_0x00=in4_input +hwmon_in.mode_0x004c_0x01=str_constant +hwmon_in.str_cons_0x004c_0x01=VDD_0.9V_PLL4 +hwmon_in.mode_0x004c_0x02=str_constant +hwmon_in.str_cons_0x004c_0x02=ADS7828E +hwmon_in.mode_0x004c_0x03=constant +hwmon_in.int_cons_0x004c_0x03=990 +hwmon_in.mode_0x004c_0x05=constant +hwmon_in.int_cons_0x004c_0x05=810 +hwmon_in.mode_0x004c_0x08=constant +hwmon_in.int_cons_0x004c_0x08=900 + +# vol77 +hwmon_in.mode_0x004d_0x00=config +hwmon_in.int_cons_0x004d_0x00=0 +hwmon_in.src_0x004d_0x00=file +hwmon_in.frmt_0x004d_0x00=buf +hwmon_in.fpath_0x004d_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x004d_0x00=0 +hwmon_in.len_0x004d_0x00=8 +hwmon_in.bit_offset_0x004d_0x00=0 +hwmon_in.str_cons_0x004d_0x00=in5_input +hwmon_in.mode_0x004d_0x01=str_constant +hwmon_in.str_cons_0x004d_0x01=VDD_0.9V_PLL5 +hwmon_in.mode_0x004d_0x02=str_constant +hwmon_in.str_cons_0x004d_0x02=ADS7828E +hwmon_in.mode_0x004d_0x03=constant +hwmon_in.int_cons_0x004d_0x03=990 +hwmon_in.mode_0x004d_0x05=constant +hwmon_in.int_cons_0x004d_0x05=810 +hwmon_in.mode_0x004d_0x08=constant +hwmon_in.int_cons_0x004d_0x08=900 + +# vol78 +hwmon_in.mode_0x004e_0x00=config +hwmon_in.int_cons_0x004e_0x00=0 +hwmon_in.src_0x004e_0x00=file +hwmon_in.frmt_0x004e_0x00=buf +hwmon_in.fpath_0x004e_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x004e_0x00=0 +hwmon_in.len_0x004e_0x00=8 +hwmon_in.bit_offset_0x004e_0x00=0 +hwmon_in.str_cons_0x004e_0x00=in6_input +hwmon_in.mode_0x004e_0x01=str_constant +hwmon_in.str_cons_0x004e_0x01=VDD_0.9V_PLL6 +hwmon_in.mode_0x004e_0x02=str_constant +hwmon_in.str_cons_0x004e_0x02=ADS7828E +hwmon_in.mode_0x004e_0x03=constant +hwmon_in.int_cons_0x004e_0x03=990 +hwmon_in.mode_0x004e_0x05=constant +hwmon_in.int_cons_0x004e_0x05=810 +hwmon_in.mode_0x004e_0x08=constant +hwmon_in.int_cons_0x004e_0x08=900 + +# vol79 +hwmon_in.mode_0x004f_0x00=config +hwmon_in.int_cons_0x004f_0x00=0 +hwmon_in.src_0x004f_0x00=file +hwmon_in.frmt_0x004f_0x00=buf +hwmon_in.fpath_0x004f_0x00=/sys/bus/i2c/devices/97-0048/hwmon/ +hwmon_in.addr_0x004f_0x00=0 +hwmon_in.len_0x004f_0x00=8 +hwmon_in.bit_offset_0x004f_0x00=0 +hwmon_in.str_cons_0x004f_0x00=in7_input +hwmon_in.mode_0x004f_0x01=str_constant +hwmon_in.str_cons_0x004f_0x01=VDD_0.9V_PLL7 +hwmon_in.mode_0x004f_0x02=str_constant +hwmon_in.str_cons_0x004f_0x02=ADS7828E +hwmon_in.mode_0x004f_0x03=constant +hwmon_in.int_cons_0x004f_0x03=990 +hwmon_in.mode_0x004f_0x05=constant +hwmon_in.int_cons_0x004f_0x05=810 +hwmon_in.mode_0x004f_0x08=constant +hwmon_in.int_cons_0x004f_0x08=900 + +# vol80 +hwmon_in.mode_0x0050_0x00=config +hwmon_in.int_cons_0x0050_0x00=0 +hwmon_in.src_0x0050_0x00=file +hwmon_in.frmt_0x0050_0x00=buf +hwmon_in.fpath_0x0050_0x00=/sys/bus/i2c/devices/97-004a/hwmon/ +hwmon_in.addr_0x0050_0x00=0 +hwmon_in.len_0x0050_0x00=8 +hwmon_in.bit_offset_0x0050_0x00=0 +hwmon_in.str_cons_0x0050_0x00=in0_input +hwmon_in.mode_0x0050_0x01=str_constant +hwmon_in.str_cons_0x0050_0x01=VDD1.45V_1 +hwmon_in.mode_0x0050_0x02=str_constant +hwmon_in.str_cons_0x0050_0x02=ADS7828E +hwmon_in.mode_0x0050_0x03=constant +hwmon_in.int_cons_0x0050_0x03=1650 +hwmon_in.mode_0x0050_0x05=constant +hwmon_in.int_cons_0x0050_0x05=1350 +hwmon_in.mode_0x0050_0x08=constant +hwmon_in.int_cons_0x0050_0x08=1500 + +# vol81 +hwmon_in.mode_0x0051_0x00=config +hwmon_in.int_cons_0x0051_0x00=0 +hwmon_in.src_0x0051_0x00=file +hwmon_in.frmt_0x0051_0x00=buf +hwmon_in.fpath_0x0051_0x00=/sys/bus/i2c/devices/97-004a/hwmon/ +hwmon_in.addr_0x0051_0x00=0 +hwmon_in.len_0x0051_0x00=8 +hwmon_in.bit_offset_0x0051_0x00=0 +hwmon_in.str_cons_0x0051_0x00=in1_input +hwmon_in.mode_0x0051_0x01=str_constant +hwmon_in.str_cons_0x0051_0x01=VDD_1.45V_2 +hwmon_in.mode_0x0051_0x02=str_constant +hwmon_in.str_cons_0x0051_0x02=ADS7828E +hwmon_in.mode_0x0051_0x03=constant +hwmon_in.int_cons_0x0051_0x03=1650 +hwmon_in.mode_0x0051_0x05=constant +hwmon_in.int_cons_0x0051_0x05=1350 +hwmon_in.mode_0x0051_0x08=constant +hwmon_in.int_cons_0x0051_0x08=1500 + +# vol82 +hwmon_in.mode_0x0052_0x00=config +hwmon_in.int_cons_0x0052_0x00=0 +hwmon_in.src_0x0052_0x00=file +hwmon_in.frmt_0x0052_0x00=buf +hwmon_in.fpath_0x0052_0x00=/sys/bus/i2c/devices/97-004a/hwmon/ +hwmon_in.addr_0x0052_0x00=0 +hwmon_in.len_0x0052_0x00=8 +hwmon_in.bit_offset_0x0052_0x00=0 +hwmon_in.str_cons_0x0052_0x00=in2_input +hwmon_in.mode_0x0052_0x01=str_constant +hwmon_in.str_cons_0x0052_0x01=VDD_1.45V_3 +hwmon_in.mode_0x0052_0x02=str_constant +hwmon_in.str_cons_0x0052_0x02=ADS7828E +hwmon_in.mode_0x0052_0x03=constant +hwmon_in.int_cons_0x0052_0x03=1650 +hwmon_in.mode_0x0052_0x05=constant +hwmon_in.int_cons_0x0052_0x05=1350 +hwmon_in.mode_0x0052_0x08=constant +hwmon_in.int_cons_0x0052_0x08=1500 + +# vol83 +hwmon_in.mode_0x0053_0x00=config +hwmon_in.int_cons_0x0053_0x00=0 +hwmon_in.src_0x0053_0x00=file +hwmon_in.frmt_0x0053_0x00=buf +hwmon_in.fpath_0x0053_0x00=/sys/bus/i2c/devices/97-004a/hwmon/ +hwmon_in.addr_0x0053_0x00=0 +hwmon_in.len_0x0053_0x00=8 +hwmon_in.bit_offset_0x0053_0x00=0 +hwmon_in.str_cons_0x0053_0x00=in3_input +hwmon_in.mode_0x0053_0x01=str_constant +hwmon_in.str_cons_0x0053_0x01=VDD_1.45V_4 +hwmon_in.mode_0x0053_0x02=str_constant +hwmon_in.str_cons_0x0053_0x02=ADS7828E +hwmon_in.mode_0x0053_0x03=constant +hwmon_in.int_cons_0x0053_0x03=1650 +hwmon_in.mode_0x0053_0x05=constant +hwmon_in.int_cons_0x0053_0x05=1350 +hwmon_in.mode_0x0053_0x08=constant +hwmon_in.int_cons_0x0053_0x08=1500 + +# vol84 +hwmon_in.mode_0x0054_0x00=config +hwmon_in.int_cons_0x0054_0x00=0 +hwmon_in.src_0x0054_0x00=file +hwmon_in.frmt_0x0054_0x00=buf +hwmon_in.fpath_0x0054_0x00=/sys/bus/i2c/devices/97-004a/hwmon/ +hwmon_in.addr_0x0054_0x00=0 +hwmon_in.len_0x0054_0x00=8 +hwmon_in.bit_offset_0x0054_0x00=0 +hwmon_in.str_cons_0x0054_0x00=in4_input +hwmon_in.mode_0x0054_0x01=str_constant +hwmon_in.str_cons_0x0054_0x01=VDDO1.8V_OTP +hwmon_in.mode_0x0054_0x02=str_constant +hwmon_in.str_cons_0x0054_0x02=ADS7828E +hwmon_in.mode_0x0054_0x03=constant +hwmon_in.int_cons_0x0054_0x03=1980 +hwmon_in.mode_0x0054_0x05=constant +hwmon_in.int_cons_0x0054_0x05=1620 +hwmon_in.mode_0x0054_0x08=constant +hwmon_in.int_cons_0x0054_0x08=1800 + +# vol85 +hwmon_in.mode_0x0055_0x00=config +hwmon_in.int_cons_0x0055_0x00=0 +hwmon_in.src_0x0055_0x00=file +hwmon_in.frmt_0x0055_0x00=buf +hwmon_in.fpath_0x0055_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0055_0x00=0 +hwmon_in.len_0x0055_0x00=8 +hwmon_in.bit_offset_0x0055_0x00=0 +hwmon_in.str_cons_0x0055_0x00=in1_input +hwmon_in.mode_0x0055_0x01=str_constant +hwmon_in.str_cons_0x0055_0x01=VDD12V_F +hwmon_in.mode_0x0055_0x02=str_constant +hwmon_in.str_cons_0x0055_0x02=ucd9081 +hwmon_in.mode_0x0055_0x03=constant +hwmon_in.int_cons_0x0055_0x03=13800 +hwmon_in.mode_0x0055_0x05=constant +hwmon_in.int_cons_0x0055_0x05=11800 +hwmon_in.mode_0x0055_0x08=constant +hwmon_in.int_cons_0x0055_0x08=12000 + +# vol86 +hwmon_in.mode_0x0056_0x00=config +hwmon_in.int_cons_0x0056_0x00=0 +hwmon_in.src_0x0056_0x00=file +hwmon_in.frmt_0x0056_0x00=buf +hwmon_in.fpath_0x0056_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0056_0x00=0 +hwmon_in.len_0x0056_0x00=8 +hwmon_in.bit_offset_0x0056_0x00= +hwmon_in.str_cons_0x0056_0x00=in2_input +hwmon_in.mode_0x0056_0x01=str_constant +hwmon_in.str_cons_0x0056_0x01=VCC_P5V0_STBY +hwmon_in.mode_0x0056_0x02=str_constant +hwmon_in.str_cons_0x0056_0x02=ucd9081 +hwmon_in.mode_0x0056_0x03=constant +hwmon_in.int_cons_0x0056_0x03=5500 +hwmon_in.mode_0x0056_0x05=constant +hwmon_in.int_cons_0x0056_0x05=4500 +hwmon_in.mode_0x0056_0x08=constant +hwmon_in.int_cons_0x0056_0x08=5000 + +# vol87 +hwmon_in.mode_0x0057_0x00=config +hwmon_in.int_cons_0x0057_0x00=0 +hwmon_in.src_0x0057_0x00=file +hwmon_in.frmt_0x0057_0x00=buf +hwmon_in.fpath_0x0057_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0057_0x00=0 +hwmon_in.len_0x0057_0x00=8 +hwmon_in.bit_offset_0x0057_0x00= +hwmon_in.str_cons_0x0057_0x00=in3_input +hwmon_in.mode_0x0057_0x01=str_constant +hwmon_in.str_cons_0x0057_0x01=VDD_P3V3_FR_S5DM +hwmon_in.mode_0x0057_0x02=str_constant +hwmon_in.str_cons_0x0057_0x02=ucd9081 +hwmon_in.mode_0x0057_0x03=constant +hwmon_in.int_cons_0x0057_0x03=3630 +hwmon_in.mode_0x0057_0x05=constant +hwmon_in.int_cons_0x0057_0x05=2970 +hwmon_in.mode_0x0057_0x08=constant +hwmon_in.int_cons_0x0057_0x08=3300 + +# vol88 +hwmon_in.mode_0x0058_0x00=config +hwmon_in.int_cons_0x0058_0x00=0 +hwmon_in.src_0x0058_0x00=file +hwmon_in.frmt_0x0058_0x00=buf +hwmon_in.fpath_0x0058_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0058_0x00=0 +hwmon_in.len_0x0058_0x00=8 +hwmon_in.bit_offset_0x0058_0x00= +hwmon_in.str_cons_0x0058_0x00=in4_input +hwmon_in.mode_0x0058_0x01=str_constant +hwmon_in.str_cons_0x0058_0x01=VDD_P1V8_FR_S5DM +hwmon_in.mode_0x0058_0x02=str_constant +hwmon_in.str_cons_0x0058_0x02=ucd9081 +hwmon_in.mode_0x0058_0x03=constant +hwmon_in.int_cons_0x0058_0x03=1980 +hwmon_in.mode_0x0058_0x05=constant +hwmon_in.int_cons_0x0058_0x05=1620 +hwmon_in.mode_0x0058_0x08=constant +hwmon_in.int_cons_0x0058_0x08=1800 + +# vol89 +hwmon_in.mode_0x0059_0x00=config +hwmon_in.int_cons_0x0059_0x00=0 +hwmon_in.src_0x0059_0x00=file +hwmon_in.frmt_0x0059_0x00=buf +hwmon_in.fpath_0x0059_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0059_0x00=0 +hwmon_in.len_0x0059_0x00=8 +hwmon_in.bit_offset_0x0059_0x00= +hwmon_in.str_cons_0x0059_0x00=in5_input +hwmon_in.mode_0x0059_0x01=str_constant +hwmon_in.str_cons_0x0059_0x01=VDD_P0V75_FR_MISC_S5DM +hwmon_in.mode_0x0059_0x02=str_constant +hwmon_in.str_cons_0x0059_0x02=ucd9081 +hwmon_in.mode_0x0059_0x03=constant +hwmon_in.int_cons_0x0059_0x03=825 +hwmon_in.mode_0x0059_0x05=constant +hwmon_in.int_cons_0x0059_0x05=675 +hwmon_in.mode_0x0059_0x08=constant +hwmon_in.int_cons_0x0059_0x08=750 + +# vol90 +hwmon_in.mode_0x005a_0x00=config +hwmon_in.int_cons_0x005a_0x00=0 +hwmon_in.src_0x005a_0x00=file +hwmon_in.frmt_0x005a_0x00=buf +hwmon_in.fpath_0x005a_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x005a_0x00=0 +hwmon_in.len_0x005a_0x00=8 +hwmon_in.bit_offset_0x005a_0x00= +hwmon_in.str_cons_0x005a_0x00=in6_input +hwmon_in.mode_0x005a_0x01=str_constant +hwmon_in.str_cons_0x005a_0x01=VDD_P3V3_FR_S0DM +hwmon_in.mode_0x005a_0x02=str_constant +hwmon_in.str_cons_0x005a_0x02=ucd9081 +hwmon_in.mode_0x005a_0x03=constant +hwmon_in.int_cons_0x005a_0x03=3630 +hwmon_in.mode_0x005a_0x05=constant +hwmon_in.int_cons_0x005a_0x05=2970 +hwmon_in.mode_0x005a_0x08=constant +hwmon_in.int_cons_0x005a_0x08=3300 + +# vol91 +hwmon_in.mode_0x005b_0x00=config +hwmon_in.int_cons_0x005b_0x00=0 +hwmon_in.src_0x005b_0x00=file +hwmon_in.frmt_0x005b_0x00=buf +hwmon_in.fpath_0x005b_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x005b_0x00=0 +hwmon_in.len_0x005b_0x00=8 +hwmon_in.bit_offset_0x005b_0x00= +hwmon_in.str_cons_0x005b_0x00=in7_input +hwmon_in.mode_0x005b_0x01=str_constant +hwmon_in.str_cons_0x005b_0x01=VDD_P1V8_FR_S0DM +hwmon_in.mode_0x005b_0x02=str_constant +hwmon_in.str_cons_0x005b_0x02=ucd9081 +hwmon_in.mode_0x005b_0x03=constant +hwmon_in.int_cons_0x005b_0x03=1980 +hwmon_in.mode_0x005b_0x05=constant +hwmon_in.int_cons_0x005b_0x05=1620 +hwmon_in.mode_0x005b_0x08=constant +hwmon_in.int_cons_0x005b_0x08=1800 + +# vol92 +hwmon_in.mode_0x005c_0x00=config +hwmon_in.int_cons_0x005c_0x00=0 +hwmon_in.src_0x005c_0x00=file +hwmon_in.frmt_0x005c_0x00=buf +hwmon_in.fpath_0x005c_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x005c_0x00=0 +hwmon_in.len_0x005c_0x00=8 +hwmon_in.bit_offset_0x005c_0x00= +hwmon_in.str_cons_0x005c_0x00=in8_input +hwmon_in.mode_0x005c_0x01=str_constant +hwmon_in.str_cons_0x005c_0x01=VDD_P1V1_NIC_AVDDH +hwmon_in.mode_0x005c_0x02=str_constant +hwmon_in.str_cons_0x005c_0x02=ucd9081 +hwmon_in.mode_0x005c_0x03=constant +hwmon_in.int_cons_0x005c_0x03=1200 +hwmon_in.mode_0x005c_0x05=constant +hwmon_in.int_cons_0x005c_0x05=990 +hwmon_in.mode_0x005c_0x08=constant +hwmon_in.int_cons_0x005c_0x08=1100 + +# vol93 +hwmon_in.mode_0x005d_0x00=config +hwmon_in.int_cons_0x005d_0x00=0 +hwmon_in.src_0x005d_0x00=file +hwmon_in.frmt_0x005d_0x00=buf +hwmon_in.fpath_0x005d_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x005d_0x00=0 +hwmon_in.len_0x005d_0x00=8 +hwmon_in.bit_offset_0x005d_0x00= +hwmon_in.str_cons_0x005d_0x00=in9_input +hwmon_in.mode_0x005d_0x01=str_constant +hwmon_in.str_cons_0x005d_0x01=VDD_P0V9_NIC_AVDD_PCIE +hwmon_in.mode_0x005d_0x02=str_constant +hwmon_in.str_cons_0x005d_0x02=ucd9081 +hwmon_in.mode_0x005d_0x03=constant +hwmon_in.int_cons_0x005d_0x03=990 +hwmon_in.mode_0x005d_0x05=constant +hwmon_in.int_cons_0x005d_0x05=810 +hwmon_in.mode_0x005d_0x08=constant +hwmon_in.int_cons_0x005d_0x08=900 + +# vol94 +hwmon_in.mode_0x005e_0x00=config +hwmon_in.int_cons_0x005e_0x00=0 +hwmon_in.src_0x005e_0x00=file +hwmon_in.frmt_0x005e_0x00=buf +hwmon_in.fpath_0x005e_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x005e_0x00=0 +hwmon_in.len_0x005e_0x00=8 +hwmon_in.bit_offset_0x005e_0x00= +hwmon_in.str_cons_0x005e_0x00=in10_input +hwmon_in.mode_0x005e_0x01=str_constant +hwmon_in.str_cons_0x005e_0x01=VDD_P0V9_NIC_AVDD_ETH +hwmon_in.mode_0x005e_0x02=str_constant +hwmon_in.str_cons_0x005e_0x02=ucd9081 +hwmon_in.mode_0x005e_0x03=constant +hwmon_in.int_cons_0x005e_0x03=990 +hwmon_in.mode_0x005e_0x05=constant +hwmon_in.int_cons_0x005e_0x05=810 +hwmon_in.mode_0x005e_0x08=constant +hwmon_in.int_cons_0x005e_0x08=900 + +# vol95 +hwmon_in.mode_0x005f_0x00=config +hwmon_in.int_cons_0x005f_0x00=0 +hwmon_in.src_0x005f_0x00=file +hwmon_in.frmt_0x005f_0x00=buf +hwmon_in.fpath_0x005f_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x005f_0x00=0 +hwmon_in.len_0x005f_0x00=8 +hwmon_in.bit_offset_0x005f_0x00= +hwmon_in.str_cons_0x005f_0x00=in11_input +hwmon_in.mode_0x005f_0x01=str_constant +hwmon_in.str_cons_0x005f_0x01=VDD_P0V8_NIC_VDD +hwmon_in.mode_0x005f_0x02=str_constant +hwmon_in.str_cons_0x005f_0x02=ucd9081 +hwmon_in.mode_0x005f_0x03=constant +hwmon_in.int_cons_0x005f_0x03=880 +hwmon_in.mode_0x005f_0x05=constant +hwmon_in.int_cons_0x005f_0x05=720 +hwmon_in.mode_0x005f_0x08=constant +hwmon_in.int_cons_0x005f_0x08=800 + +# vol96 +hwmon_in.mode_0x0060_0x00=config +hwmon_in.int_cons_0x0060_0x00=0 +hwmon_in.src_0x0060_0x00=file +hwmon_in.frmt_0x0060_0x00=buf +hwmon_in.fpath_0x0060_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0060_0x00=0 +hwmon_in.len_0x0060_0x00=8 +hwmon_in.bit_offset_0x0060_0x00= +hwmon_in.str_cons_0x0060_0x00=in12_input +hwmon_in.mode_0x0060_0x01=str_constant +hwmon_in.str_cons_0x0060_0x01=VDD_VR_P1V1_FR_MEM_S3DM +hwmon_in.mode_0x0060_0x02=str_constant +hwmon_in.str_cons_0x0060_0x02=ucd9081 +hwmon_in.mode_0x0060_0x03=constant +hwmon_in.int_cons_0x0060_0x03=1210 +hwmon_in.mode_0x0060_0x05=constant +hwmon_in.int_cons_0x0060_0x05=990 +hwmon_in.mode_0x0060_0x08=constant +hwmon_in.int_cons_0x0060_0x08=1100 + +# vol97 +hwmon_in.mode_0x0061_0x00=config +hwmon_in.int_cons_0x0061_0x00=0 +hwmon_in.src_0x0061_0x00=file +hwmon_in.frmt_0x0061_0x00=buf +hwmon_in.fpath_0x0061_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0061_0x00=0 +hwmon_in.len_0x0061_0x00=8 +hwmon_in.bit_offset_0x0061_0x00= +hwmon_in.str_cons_0x0061_0x00=in13_input +hwmon_in.mode_0x0061_0x01=str_constant +hwmon_in.str_cons_0x0061_0x01=VDD_VR_P0V8_FR_MISC_S0DM +hwmon_in.mode_0x0061_0x02=str_constant +hwmon_in.str_cons_0x0061_0x02=ucd9081 +hwmon_in.mode_0x0061_0x03=constant +hwmon_in.int_cons_0x0061_0x03=1200 +hwmon_in.mode_0x0061_0x05=constant +hwmon_in.int_cons_0x0061_0x05=600 +hwmon_in.mode_0x0061_0x08=constant +hwmon_in.int_cons_0x0061_0x08=800 + +# vol98 +hwmon_in.mode_0x0062_0x00=config +hwmon_in.int_cons_0x0062_0x00=0 +hwmon_in.src_0x0062_0x00=file +hwmon_in.frmt_0x0062_0x00=buf +hwmon_in.fpath_0x0062_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0062_0x00=0 +hwmon_in.len_0x0062_0x00=8 +hwmon_in.bit_offset_0x0062_0x00= +hwmon_in.str_cons_0x0062_0x00=in14_input +hwmon_in.mode_0x0062_0x01=str_constant +hwmon_in.str_cons_0x0062_0x01=VDD_VR_P0V8_FR_SOC +hwmon_in.mode_0x0062_0x02=str_constant +hwmon_in.str_cons_0x0062_0x02=ucd9081 +hwmon_in.mode_0x0062_0x03=constant +hwmon_in.int_cons_0x0062_0x03=1200 +hwmon_in.mode_0x0062_0x05=constant +hwmon_in.int_cons_0x0062_0x05=600 +hwmon_in.mode_0x0062_0x08=constant +hwmon_in.int_cons_0x0062_0x08=800 + +# vol99 +hwmon_in.mode_0x0063_0x00=config +hwmon_in.int_cons_0x0063_0x00=0 +hwmon_in.src_0x0063_0x00=file +hwmon_in.frmt_0x0063_0x00=buf +hwmon_in.fpath_0x0063_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0063_0x00=0 +hwmon_in.len_0x0063_0x00=8 +hwmon_in.bit_offset_0x0063_0x00= +hwmon_in.str_cons_0x0063_0x00=in15_input +hwmon_in.mode_0x0063_0x01=str_constant +hwmon_in.str_cons_0x0063_0x01=VDD_VR_P0V8_FR_CORE +hwmon_in.mode_0x0063_0x02=str_constant +hwmon_in.str_cons_0x0063_0x02=ucd9081 +hwmon_in.mode_0x0063_0x03=constant +hwmon_in.int_cons_0x0063_0x03=1550 +hwmon_in.mode_0x0063_0x05=constant +hwmon_in.int_cons_0x0063_0x05=600 +hwmon_in.mode_0x0063_0x08=constant +hwmon_in.int_cons_0x0063_0x08=800 + +# vol100 +hwmon_in.mode_0x0064_0x00=config +hwmon_in.int_cons_0x0064_0x00=0 +hwmon_in.src_0x0064_0x00=file +hwmon_in.frmt_0x0064_0x00=buf +hwmon_in.fpath_0x0064_0x00=/sys/bus/i2c/devices/70-005f/hwmon/ +hwmon_in.addr_0x0064_0x00=0 +hwmon_in.len_0x0064_0x00=8 +hwmon_in.bit_offset_0x0064_0x00= +hwmon_in.str_cons_0x0064_0x00=in16_input +hwmon_in.mode_0x0064_0x01=str_constant +hwmon_in.str_cons_0x0064_0x01=VCC_P1V8_STBY +hwmon_in.mode_0x0064_0x02=str_constant +hwmon_in.str_cons_0x0064_0x02=ucd9081 +hwmon_in.mode_0x0064_0x03=constant +hwmon_in.int_cons_0x0064_0x03=1980 +hwmon_in.mode_0x0064_0x05=constant +hwmon_in.int_cons_0x0064_0x05=1620 +hwmon_in.mode_0x0064_0x08=constant +hwmon_in.int_cons_0x0064_0x08=1800 + +# vol101 +hwmon_in.mode_0x0065_0x00=config +hwmon_in.int_cons_0x0065_0x00=0 +hwmon_in.src_0x0065_0x00=file +hwmon_in.frmt_0x0065_0x00=buf +hwmon_in.fpath_0x0065_0x00=/sys/bus/i2c/devices/70-0072/hwmon/ +hwmon_in.addr_0x0065_0x00=0 +hwmon_in.len_0x0065_0x00=8 +hwmon_in.bit_offset_0x0065_0x00= +hwmon_in.str_cons_0x0065_0x00=in3_input +hwmon_in.mode_0x0065_0x01=str_constant +hwmon_in.str_cons_0x0065_0x01=VDD_P0V8_FR_CORE +hwmon_in.mode_0x0065_0x02=str_constant +hwmon_in.str_cons_0x0065_0x02=ucd9081 +hwmon_in.mode_0x0065_0x03=constant +hwmon_in.int_cons_0x0065_0x03=1550 +hwmon_in.mode_0x0065_0x05=constant +hwmon_in.int_cons_0x0065_0x05=600 +hwmon_in.mode_0x0065_0x08=constant +hwmon_in.int_cons_0x0065_0x08=800 + +# vol102 +hwmon_in.mode_0x0066_0x00=config +hwmon_in.int_cons_0x0066_0x00=0 +hwmon_in.src_0x0066_0x00=file +hwmon_in.frmt_0x0066_0x00=buf +hwmon_in.fpath_0x0066_0x00=/sys/bus/i2c/devices/70-0072/hwmon/ +hwmon_in.addr_0x0066_0x00=0 +hwmon_in.len_0x0066_0x00=8 +hwmon_in.bit_offset_0x0066_0x00= +hwmon_in.str_cons_0x0066_0x00=in4_input +hwmon_in.mode_0x0066_0x01=str_constant +hwmon_in.str_cons_0x0066_0x01=VDD_P0V8_FR_SOC +hwmon_in.mode_0x0066_0x02=str_constant +hwmon_in.str_cons_0x0066_0x02=ucd9081 +hwmon_in.mode_0x0066_0x03=constant +hwmon_in.int_cons_0x0066_0x03=1550 +hwmon_in.mode_0x0066_0x05=constant +hwmon_in.int_cons_0x0066_0x05=600 +hwmon_in.mode_0x0066_0x08=constant +hwmon_in.int_cons_0x0066_0x08=800 + +# vol103 +hwmon_in.mode_0x0067_0x00=config +hwmon_in.int_cons_0x0067_0x00=0 +hwmon_in.src_0x0067_0x00=file +hwmon_in.frmt_0x0067_0x00=buf +hwmon_in.fpath_0x0067_0x00=/sys/bus/i2c/devices/70-0074/hwmon/ +hwmon_in.addr_0x0067_0x00=0 +hwmon_in.len_0x0067_0x00=8 +hwmon_in.bit_offset_0x0067_0x00= +hwmon_in.str_cons_0x0067_0x00=in3_input +hwmon_in.mode_0x0067_0x01=str_constant +hwmon_in.str_cons_0x0067_0x01=VDD_P0V8_FR_MISC_S0DM +hwmon_in.mode_0x0067_0x02=str_constant +hwmon_in.str_cons_0x0067_0x02=ucd9081 +hwmon_in.mode_0x0067_0x03=constant +hwmon_in.int_cons_0x0067_0x03=1550 +hwmon_in.mode_0x0067_0x05=constant +hwmon_in.int_cons_0x0067_0x05=600 +hwmon_in.mode_0x0067_0x08=constant +hwmon_in.int_cons_0x0067_0x08=800 + +# vol104 +hwmon_in.mode_0x0068_0x00=config +hwmon_in.int_cons_0x0068_0x00=0 +hwmon_in.src_0x0068_0x00=file +hwmon_in.frmt_0x0068_0x00=buf +hwmon_in.fpath_0x0068_0x00=/sys/bus/i2c/devices/70-0074/hwmon/ +hwmon_in.addr_0x0068_0x00=0 +hwmon_in.len_0x0068_0x00=8 +hwmon_in.bit_offset_0x0068_0x00= +hwmon_in.str_cons_0x0068_0x00=in4_input +hwmon_in.mode_0x0068_0x01=str_constant +hwmon_in.str_cons_0x0068_0x01=VDD_P1V1_FR_MEM_S3DM +hwmon_in.mode_0x0068_0x02=str_constant +hwmon_in.str_cons_0x0068_0x02=ucd9081 +hwmon_in.mode_0x0068_0x03=constant +hwmon_in.int_cons_0x0068_0x03=1210 +hwmon_in.mode_0x0068_0x05=constant +hwmon_in.int_cons_0x0068_0x05=990 +hwmon_in.mode_0x0068_0x08=constant +hwmon_in.int_cons_0x0068_0x08=1100 + +# vol105 +hwmon_in.mode_0x0069_0x00=config +hwmon_in.int_cons_0x0069_0x00=3 +hwmon_in.src_0x0069_0x00=file +hwmon_in.frmt_0x0069_0x00=buf +hwmon_in.fpath_0x0069_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x0069_0x00=0 +hwmon_in.len_0x0069_0x00=8 +hwmon_in.bit_offset_0x0069_0x00= +hwmon_in.str_cons_0x0069_0x00=in0_input +hwmon_in.mode_0x0069_0x01=str_constant +hwmon_in.str_cons_0x0069_0x01=IO_OSFP_VDD3.3V_A1 +hwmon_in.mode_0x0069_0x02=str_constant +hwmon_in.str_cons_0x0069_0x02=ADS7848E +hwmon_in.mode_0x0069_0x03=constant +hwmon_in.int_cons_0x0069_0x03=3630 +hwmon_in.mode_0x0069_0x05=constant +hwmon_in.int_cons_0x0069_0x05=2970 +hwmon_in.mode_0x0069_0x08=constant +hwmon_in.int_cons_0x0069_0x08=3300 +hwmon_in.int_extra1_0x0069_0x00=1833 + +# vol106 +hwmon_in.mode_0x006a_0x00=config +hwmon_in.int_cons_0x006a_0x00=3 +hwmon_in.src_0x006a_0x00=file +hwmon_in.frmt_0x006a_0x00=buf +hwmon_in.fpath_0x006a_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x006a_0x00=0 +hwmon_in.len_0x006a_0x00=8 +hwmon_in.bit_offset_0x006a_0x00= +hwmon_in.str_cons_0x006a_0x00=in1_input +hwmon_in.mode_0x006a_0x01=str_constant +hwmon_in.str_cons_0x006a_0x01=IO_OSFP_VDD3.3V_A2 +hwmon_in.mode_0x006a_0x02=str_constant +hwmon_in.str_cons_0x006a_0x02=ADS7848E +hwmon_in.mode_0x006a_0x03=constant +hwmon_in.int_cons_0x006a_0x03=3630 +hwmon_in.mode_0x006a_0x05=constant +hwmon_in.int_cons_0x006a_0x05=2970 +hwmon_in.mode_0x006a_0x08=constant +hwmon_in.int_cons_0x006a_0x08=3300 +hwmon_in.int_extra1_0x006a_0x00=1833 + +# vol107 +hwmon_in.mode_0x006b_0x00=config +hwmon_in.int_cons_0x006b_0x00=3 +hwmon_in.src_0x006b_0x00=file +hwmon_in.frmt_0x006b_0x00=buf +hwmon_in.fpath_0x006b_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x006b_0x00=0 +hwmon_in.len_0x006b_0x00=8 +hwmon_in.bit_offset_0x006b_0x00= +hwmon_in.str_cons_0x006b_0x00=in2_input +hwmon_in.mode_0x006b_0x01=str_constant +hwmon_in.str_cons_0x006b_0x01=IO_VDD3.3V_FPGA +hwmon_in.mode_0x006b_0x02=str_constant +hwmon_in.str_cons_0x006b_0x02=ADS7848E +hwmon_in.mode_0x006b_0x03=constant +hwmon_in.int_cons_0x006b_0x03=3630 +hwmon_in.mode_0x006b_0x05=constant +hwmon_in.int_cons_0x006b_0x05=2970 +hwmon_in.mode_0x006b_0x08=constant +hwmon_in.int_cons_0x006b_0x08=3300 +hwmon_in.int_extra1_0x006b_0x00=1833 + +# vol108 +hwmon_in.mode_0x006c_0x00=config +hwmon_in.int_cons_0x006c_0x00=0 +hwmon_in.src_0x006c_0x00=file +hwmon_in.frmt_0x006c_0x00=buf +hwmon_in.fpath_0x006c_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x006c_0x00=0 +hwmon_in.len_0x006c_0x00=8 +hwmon_in.bit_offset_0x006c_0x00= +hwmon_in.str_cons_0x006c_0x00=in3_input +hwmon_in.mode_0x006c_0x01=str_constant +hwmon_in.str_cons_0x006c_0x01=IO_VDD1.8V_FPGA +hwmon_in.mode_0x006c_0x02=str_constant +hwmon_in.str_cons_0x006c_0x02=ADS7848E +hwmon_in.mode_0x006c_0x03=constant +hwmon_in.int_cons_0x006c_0x03=1980 +hwmon_in.mode_0x006c_0x05=constant +hwmon_in.int_cons_0x006c_0x05=1620 +hwmon_in.mode_0x006c_0x08=constant +hwmon_in.int_cons_0x006c_0x08=1800 + +# vol109 +hwmon_in.mode_0x006d_0x00=config +hwmon_in.int_cons_0x006d_0x00=0 +hwmon_in.src_0x006d_0x00=file +hwmon_in.frmt_0x006d_0x00=buf +hwmon_in.fpath_0x006d_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x006d_0x00=0 +hwmon_in.len_0x006d_0x00=8 +hwmon_in.bit_offset_0x006d_0x00= +hwmon_in.str_cons_0x006d_0x00=in4_input +hwmon_in.mode_0x006d_0x01=str_constant +hwmon_in.str_cons_0x006d_0x01=IO_VDD1.2V_FPGA +hwmon_in.mode_0x006d_0x02=str_constant +hwmon_in.str_cons_0x006d_0x02=ADS7848E +hwmon_in.mode_0x006d_0x03=constant +hwmon_in.int_cons_0x006d_0x03=1310 +hwmon_in.mode_0x006d_0x05=constant +hwmon_in.int_cons_0x006d_0x05=1080 +hwmon_in.mode_0x006d_0x08=constant +hwmon_in.int_cons_0x006d_0x08=1200 + +# vol110 +hwmon_in.mode_0x006e_0x00=config +hwmon_in.int_cons_0x006e_0x00=0 +hwmon_in.src_0x006e_0x00=file +hwmon_in.frmt_0x006e_0x00=buf +hwmon_in.fpath_0x006e_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x006e_0x00=0 +hwmon_in.len_0x006e_0x00=8 +hwmon_in.bit_offset_0x006e_0x00= +hwmon_in.str_cons_0x006e_0x00=in5_input +hwmon_in.mode_0x006e_0x01=str_constant +hwmon_in.str_cons_0x006e_0x01=IO_VDD1.0V_FPGA +hwmon_in.mode_0x006e_0x02=str_constant +hwmon_in.str_cons_0x006e_0x02=ADS7848E +hwmon_in.mode_0x006e_0x03=constant +hwmon_in.int_cons_0x006e_0x03=1090 +hwmon_in.mode_0x006e_0x05=constant +hwmon_in.int_cons_0x006e_0x05=900 +hwmon_in.mode_0x006e_0x08=constant +hwmon_in.int_cons_0x006e_0x08=1000 + +# vol111 +hwmon_in.mode_0x006f_0x00=config +hwmon_in.int_cons_0x006f_0x00=3 +hwmon_in.src_0x006f_0x00=file +hwmon_in.frmt_0x006f_0x00=buf +hwmon_in.fpath_0x006f_0x00=/sys/bus/i2c/devices/13-0048/hwmon/ +hwmon_in.addr_0x006f_0x00=0 +hwmon_in.len_0x006f_0x00=8 +hwmon_in.bit_offset_0x006f_0x00= +hwmon_in.str_cons_0x006f_0x00=in6_input +hwmon_in.mode_0x006f_0x01=str_constant +hwmon_in.str_cons_0x006f_0x01=IO_VDD3.3V +hwmon_in.mode_0x006f_0x02=str_constant +hwmon_in.str_cons_0x006f_0x02=ADS7848E +hwmon_in.mode_0x006f_0x03=constant +hwmon_in.int_cons_0x006f_0x03=3630 +hwmon_in.mode_0x006f_0x05=constant +hwmon_in.int_cons_0x006f_0x05=2970 +hwmon_in.mode_0x006f_0x08=constant +hwmon_in.int_cons_0x006f_0x08=3300 +hwmon_in.int_extra1_0x006f_0x00=1833 + +# vol112 +hwmon_in.mode_0x0070_0x00=config +hwmon_in.int_cons_0x0070_0x00=3 +hwmon_in.src_0x0070_0x00=file +hwmon_in.frmt_0x0070_0x00=buf +hwmon_in.fpath_0x0070_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0070_0x00=0 +hwmon_in.len_0x0070_0x00=8 +hwmon_in.bit_offset_0x0070_0x00= +hwmon_in.str_cons_0x0070_0x00=in0_input +hwmon_in.mode_0x0070_0x01=str_constant +hwmon_in.str_cons_0x0070_0x01=IO_VDD3.3V_NIC +hwmon_in.mode_0x0070_0x02=str_constant +hwmon_in.str_cons_0x0070_0x02=ADS7848E +hwmon_in.mode_0x0070_0x03=constant +hwmon_in.int_cons_0x0070_0x03=3630 +hwmon_in.mode_0x0070_0x05=constant +hwmon_in.int_cons_0x0070_0x05=2970 +hwmon_in.mode_0x0070_0x08=constant +hwmon_in.int_cons_0x0070_0x08=3300 +hwmon_in.int_extra1_0x0070_0x00=1833 + +# vol113 +hwmon_in.mode_0x0071_0x00=config +hwmon_in.int_cons_0x0071_0x00=0 +hwmon_in.src_0x0071_0x00=file +hwmon_in.frmt_0x0071_0x00=buf +hwmon_in.fpath_0x0071_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0071_0x00=0 +hwmon_in.len_0x0071_0x00=8 +hwmon_in.bit_offset_0x0071_0x00= +hwmon_in.str_cons_0x0071_0x00=in1_input +hwmon_in.mode_0x0071_0x01=str_constant +hwmon_in.str_cons_0x0071_0x01=IO_VDD1.8V +hwmon_in.mode_0x0071_0x02=str_constant +hwmon_in.str_cons_0x0071_0x02=ADS7848E +hwmon_in.mode_0x0071_0x03=constant +hwmon_in.int_cons_0x0071_0x03=1980 +hwmon_in.mode_0x0071_0x05=constant +hwmon_in.int_cons_0x0071_0x05=1620 +hwmon_in.mode_0x0071_0x08=constant +hwmon_in.int_cons_0x0071_0x08=1800 + +# vol114 +hwmon_in.mode_0x0072_0x00=config +hwmon_in.int_cons_0x0072_0x00=0 +hwmon_in.src_0x0072_0x00=file +hwmon_in.frmt_0x0072_0x00=buf +hwmon_in.fpath_0x0072_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0072_0x00=0 +hwmon_in.len_0x0072_0x00=8 +hwmon_in.bit_offset_0x0072_0x00= +hwmon_in.str_cons_0x0072_0x00=in2_input +hwmon_in.mode_0x0072_0x01=str_constant +hwmon_in.str_cons_0x0072_0x01=IO_VDD0.85V +hwmon_in.mode_0x0072_0x02=str_constant +hwmon_in.str_cons_0x0072_0x02=ADS7848E +hwmon_in.mode_0x0072_0x03=constant +hwmon_in.int_cons_0x0072_0x03=930 +hwmon_in.mode_0x0072_0x05=constant +hwmon_in.int_cons_0x0072_0x05=770 +hwmon_in.mode_0x0072_0x08=constant +hwmon_in.int_cons_0x0072_0x08=850 + +# vol115 +hwmon_in.mode_0x0073_0x00=config +hwmon_in.int_cons_0x0073_0x00=0 +hwmon_in.src_0x0073_0x00=file +hwmon_in.frmt_0x0073_0x00=buf +hwmon_in.fpath_0x0073_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0073_0x00=0 +hwmon_in.len_0x0073_0x00=8 +hwmon_in.bit_offset_0x0073_0x00= +hwmon_in.str_cons_0x0073_0x00=in3_input +hwmon_in.mode_0x0073_0x01=str_constant +hwmon_in.str_cons_0x0073_0x01=IO_VDD2.3V +hwmon_in.mode_0x0073_0x02=str_constant +hwmon_in.str_cons_0x0073_0x02=ADS7848E +hwmon_in.mode_0x0073_0x03=constant +hwmon_in.int_cons_0x0073_0x03=2510 +hwmon_in.mode_0x0073_0x05=constant +hwmon_in.int_cons_0x0073_0x05=2070 +hwmon_in.mode_0x0073_0x08=constant +hwmon_in.int_cons_0x0073_0x08=2300 + +# vol116 +hwmon_in.mode_0x0074_0x00=config +hwmon_in.int_cons_0x0074_0x00=0 +hwmon_in.src_0x0074_0x00=file +hwmon_in.frmt_0x0074_0x00=buf +hwmon_in.fpath_0x0074_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0074_0x00=0 +hwmon_in.len_0x0074_0x00=8 +hwmon_in.bit_offset_0x0074_0x00= +hwmon_in.str_cons_0x0074_0x00=in4_input +hwmon_in.mode_0x0074_0x01=str_constant +hwmon_in.str_cons_0x0074_0x01=IO_VDD0.9V +hwmon_in.mode_0x0074_0x02=str_constant +hwmon_in.str_cons_0x0074_0x02=ADS7848E +hwmon_in.mode_0x0074_0x03=constant +hwmon_in.int_cons_0x0074_0x03=980 +hwmon_in.mode_0x0074_0x05=constant +hwmon_in.int_cons_0x0074_0x05=810 +hwmon_in.mode_0x0074_0x08=constant +hwmon_in.int_cons_0x0074_0x08=900 + +# vol117 +hwmon_in.mode_0x0075_0x00=config +hwmon_in.int_cons_0x0075_0x00=0 +hwmon_in.src_0x0075_0x00=file +hwmon_in.frmt_0x0075_0x00=buf +hwmon_in.fpath_0x0075_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0075_0x00=0 +hwmon_in.len_0x0075_0x00=8 +hwmon_in.bit_offset_0x0075_0x00= +hwmon_in.str_cons_0x0075_0x00=in5_input +hwmon_in.mode_0x0075_0x01=str_constant +hwmon_in.str_cons_0x0075_0x01=IO_VDD0.65V +hwmon_in.mode_0x0075_0x02=str_constant +hwmon_in.str_cons_0x0075_0x02=ADS7848E +hwmon_in.mode_0x0075_0x03=constant +hwmon_in.int_cons_0x0075_0x03=710 +hwmon_in.mode_0x0075_0x05=constant +hwmon_in.int_cons_0x0075_0x05=590 +hwmon_in.mode_0x0075_0x08=constant +hwmon_in.int_cons_0x0075_0x08=650 + +# vol118 +monitor_flag_hwmon_in.mode_0x0076_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0076_0x00=0 +hwmon_in.mode_0x0076_0x00=config +hwmon_in.int_cons_0x0076_0x00=0 +hwmon_in.src_0x0076_0x00=file +hwmon_in.frmt_0x0076_0x00=buf +hwmon_in.fpath_0x0076_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0076_0x00=0 +hwmon_in.len_0x0076_0x00=8 +hwmon_in.bit_offset_0x0076_0x00= +hwmon_in.str_cons_0x0076_0x00=in6_input +hwmon_in.mode_0x0076_0x01=str_constant +hwmon_in.str_cons_0x0076_0x01=IO_VDD0.75V +hwmon_in.mode_0x0076_0x02=str_constant +hwmon_in.str_cons_0x0076_0x02=ADS7848E +hwmon_in.mode_0x0076_0x03=constant +hwmon_in.int_cons_0x0076_0x03=820 +hwmon_in.mode_0x0076_0x05=constant +hwmon_in.int_cons_0x0076_0x05=680 +hwmon_in.mode_0x0076_0x08=constant +hwmon_in.int_cons_0x0076_0x08=750 + +# vol119 +monitor_flag_hwmon_in.mode_0x0077_0x00=constant +monitor_flag_hwmon_in.int_cons_0x0077_0x00=0 +hwmon_in.mode_0x0077_0x00=config +hwmon_in.int_cons_0x0077_0x00=0 +hwmon_in.src_0x0077_0x00=file +hwmon_in.frmt_0x0077_0x00=buf +hwmon_in.fpath_0x0077_0x00=/sys/bus/i2c/devices/14-0048/hwmon/ +hwmon_in.addr_0x0077_0x00=0 +hwmon_in.len_0x0077_0x00=8 +hwmon_in.bit_offset_0x0077_0x00= +hwmon_in.str_cons_0x0077_0x00=in7_input +hwmon_in.mode_0x0077_0x01=str_constant +hwmon_in.str_cons_0x0077_0x01=IO_VDD1.2V +hwmon_in.mode_0x0077_0x02=str_constant +hwmon_in.str_cons_0x0077_0x02=ADS7848E +hwmon_in.mode_0x0077_0x03=constant +hwmon_in.int_cons_0x0077_0x03=1310 +hwmon_in.mode_0x0077_0x05=constant +hwmon_in.int_cons_0x0077_0x05=1080 +hwmon_in.mode_0x0077_0x08=constant +hwmon_in.int_cons_0x0077_0x08=1200 + +# vol120 +hwmon_in.mode_0x0078_0x00=config +hwmon_in.int_cons_0x0078_0x00=0 +hwmon_in.src_0x0078_0x00=file +hwmon_in.frmt_0x0078_0x00=buf +hwmon_in.fpath_0x0078_0x00=/sys/bus/i2c/devices/57-0040/hwmon/ +hwmon_in.addr_0x0078_0x00=0 +hwmon_in.len_0x0078_0x00=8 +hwmon_in.bit_offset_0x0078_0x00=0 +hwmon_in.str_cons_0x0078_0x00=in1_input +hwmon_in.mode_0x0078_0x01=str_constant +hwmon_in.str_cons_0x0078_0x01=VCC54V_OUT_1_R_V +hwmon_in.mode_0x0078_0x02=str_constant +hwmon_in.str_cons_0x0078_0x02=INA238 +hwmon_in.mode_0x0078_0x03=str_constant +hwmon_in.str_cons_0x0078_0x03=60000 +hwmon_in.mode_0x0078_0x05=str_constant +hwmon_in.str_cons_0x0078_0x05=40000 +hwmon_in.mode_0x0078_0x08=constant +hwmon_in.int_cons_0x0078_0x08=54000 + +# vol121 +hwmon_in.mode_0x0079_0x00=config +hwmon_in.int_cons_0x0079_0x00=0 +hwmon_in.src_0x0079_0x00=file +hwmon_in.frmt_0x0079_0x00=buf +hwmon_in.fpath_0x0079_0x00=/sys/bus/i2c/devices/58-0041/hwmon/ +hwmon_in.addr_0x0079_0x00=0 +hwmon_in.len_0x0079_0x00=8 +hwmon_in.bit_offset_0x0079_0x00=0 +hwmon_in.str_cons_0x0079_0x00=in1_input +hwmon_in.mode_0x0079_0x01=str_constant +hwmon_in.str_cons_0x0079_0x01=VCC54V_OUT_2_R_V +hwmon_in.mode_0x0079_0x02=str_constant +hwmon_in.str_cons_0x0079_0x02=INA238 +hwmon_in.mode_0x0079_0x03=str_constant +hwmon_in.str_cons_0x0079_0x03=60000 +hwmon_in.mode_0x0079_0x05=str_constant +hwmon_in.str_cons_0x0079_0x05=40000 +hwmon_in.mode_0x0079_0x08=constant +hwmon_in.int_cons_0x0079_0x08=54000 + +# curr1 +hwmon_curr.mode_0x0001_0x00=config +hwmon_curr.int_cons_0x0001_0x00=3 +hwmon_curr.src_0x0001_0x00=file +hwmon_curr.frmt_0x0001_0x00=buf +hwmon_curr.fpath_0x0001_0x00=/sys/bus/i2c/devices/57-0040/hwmon/ +hwmon_curr.addr_0x0001_0x00=0 +hwmon_curr.len_0x0001_0x00=8 +hwmon_curr.bit_offset_0x0001_0x00= +hwmon_curr.str_cons_0x0001_0x00=curr1_input +hwmon_curr.mode_0x0001_0x01=str_constant +hwmon_curr.str_cons_0x0001_0x01=VCC54V_OUT_1_R_C +hwmon_curr.mode_0x0001_0x02=str_constant +hwmon_curr.str_cons_0x0001_0x02=INA238 +hwmon_curr.mode_0x0001_0x03=constant +hwmon_curr.int_cons_0x0001_0x03=100000 +hwmon_curr.mode_0x0001_0x05=constant +hwmon_curr.int_cons_0x0001_0x05=-5000 +hwmon_curr.mode_0x0001_0x08=constant +hwmon_curr.int_cons_0x0001_0x08=80000 +hwmon_curr.int_extra1_0x0001_0x00=15000 + +# curr2 +hwmon_curr.mode_0x0002_0x00=config +hwmon_curr.int_cons_0x0002_0x00=3 +hwmon_curr.src_0x0002_0x00=file +hwmon_curr.frmt_0x0002_0x00=buf +hwmon_curr.fpath_0x0002_0x00=/sys/bus/i2c/devices/58-0041/hwmon/ +hwmon_curr.addr_0x0002_0x00=0 +hwmon_curr.len_0x0002_0x00=8 +hwmon_curr.bit_offset_0x0002_0x00= +hwmon_curr.str_cons_0x0002_0x00=curr1_input +hwmon_curr.mode_0x0002_0x01=str_constant +hwmon_curr.str_cons_0x0002_0x01=VCC54V_OUT_2_R_C +hwmon_curr.mode_0x0002_0x02=str_constant +hwmon_curr.str_cons_0x0002_0x02=INA238 +hwmon_curr.mode_0x0002_0x03=constant +hwmon_curr.int_cons_0x0002_0x03=100000 +hwmon_curr.mode_0x0002_0x05=constant +hwmon_curr.int_cons_0x0002_0x05=-5000 +hwmon_curr.mode_0x0002_0x08=constant +hwmon_curr.int_cons_0x0002_0x08=80000 +hwmon_curr.int_extra1_0x0002_0x00=15000 + +# curr3 +hwmon_curr.mode_0x0003_0x00=config +hwmon_curr.int_cons_0x0003_0x00=0 +hwmon_curr.src_0x0003_0x00=file +hwmon_curr.frmt_0x0003_0x00=buf +hwmon_curr.fpath_0x0003_0x00=/sys/bus/i2c/devices/85-0060/hwmon/ +hwmon_curr.addr_0x0003_0x00=0 +hwmon_curr.len_0x0003_0x00=8 +hwmon_curr.bit_offset_0x0003_0x00= +hwmon_curr.str_cons_0x0003_0x00=curr3_input +hwmon_curr.mode_0x0003_0x01=str_constant +hwmon_curr.str_cons_0x0003_0x01=VDD_CORE_C +hwmon_curr.mode_0x0003_0x02=str_constant +hwmon_curr.str_cons_0x0003_0x02=xdpe1a2g5b +hwmon_curr.mode_0x0003_0x03=constant +hwmon_curr.int_cons_0x0003_0x03=1276000 +hwmon_curr.mode_0x0003_0x05=constant +hwmon_curr.int_cons_0x0003_0x05=-24000 + +# curr4 +hwmon_curr.mode_0x0004_0x00=config +hwmon_curr.int_cons_0x0004_0x00=0 +hwmon_curr.src_0x0004_0x00=file +hwmon_curr.frmt_0x0004_0x00=buf +hwmon_curr.fpath_0x0004_0x00=/sys/bus/i2c/devices/91-0060/hwmon/ +hwmon_curr.addr_0x0004_0x00=0 +hwmon_curr.len_0x0004_0x00=8 +hwmon_curr.bit_offset_0x0004_0x00= +hwmon_curr.str_cons_0x0004_0x00=curr3_input +hwmon_curr.mode_0x0004_0x01=str_constant +hwmon_curr.str_cons_0x0004_0x01=OSFP_VDD3.3V_A1_C +hwmon_curr.mode_0x0004_0x02=str_constant +hwmon_curr.str_cons_0x0004_0x02=xdpe12284c +hwmon_curr.mode_0x0004_0x03=constant +hwmon_curr.int_cons_0x0004_0x03=150000 +hwmon_curr.mode_0x0004_0x05=constant +hwmon_curr.int_cons_0x0004_0x05=-9000 + +# curr5 +hwmon_curr.mode_0x0005_0x00=config +hwmon_curr.int_cons_0x0005_0x00=0 +hwmon_curr.src_0x0005_0x00=file +hwmon_curr.frmt_0x0005_0x00=buf +hwmon_curr.fpath_0x0005_0x00=/sys/bus/i2c/devices/92-0060/hwmon/ +hwmon_curr.addr_0x0005_0x00=0 +hwmon_curr.len_0x0005_0x00=8 +hwmon_curr.bit_offset_0x0005_0x00= +hwmon_curr.str_cons_0x0005_0x00=curr3_input +hwmon_curr.mode_0x0005_0x01=str_constant +hwmon_curr.str_cons_0x0005_0x01=OSFP_VDD3.3V_A2_C +hwmon_curr.mode_0x0005_0x02=str_constant +hwmon_curr.str_cons_0x0005_0x02=xdpe12284c +hwmon_curr.mode_0x0005_0x03=constant +hwmon_curr.int_cons_0x0005_0x03=150000 +hwmon_curr.mode_0x0005_0x05=constant +hwmon_curr.int_cons_0x0005_0x05=-9000 + +# curr6 +hwmon_curr.mode_0x0006_0x00=config +hwmon_curr.int_cons_0x0006_0x00=0 +hwmon_curr.src_0x0006_0x00=file +hwmon_curr.frmt_0x0006_0x00=buf +hwmon_curr.fpath_0x0006_0x00=/sys/bus/i2c/devices/91-0062/hwmon/ +hwmon_curr.addr_0x0006_0x00=0 +hwmon_curr.len_0x0006_0x00=8 +hwmon_curr.bit_offset_0x0006_0x00= +hwmon_curr.str_cons_0x0006_0x00=curr3_input +hwmon_curr.mode_0x0006_0x01=str_constant +hwmon_curr.str_cons_0x0006_0x01=OSFP_VDD3.3V_A3_C +hwmon_curr.mode_0x0006_0x02=str_constant +hwmon_curr.str_cons_0x0006_0x02=xdpe12284c +hwmon_curr.mode_0x0006_0x03=constant +hwmon_curr.int_cons_0x0006_0x03=73000 +hwmon_curr.mode_0x0006_0x05=constant +hwmon_curr.int_cons_0x0006_0x05=-4500 + +# curr7 +hwmon_curr.mode_0x0007_0x00=config +hwmon_curr.int_cons_0x0007_0x00=0 +hwmon_curr.src_0x0007_0x00=file +hwmon_curr.frmt_0x0007_0x00=buf +hwmon_curr.fpath_0x0007_0x00=/sys/bus/i2c/devices/91-0062/hwmon/ +hwmon_curr.addr_0x0007_0x00=0 +hwmon_curr.len_0x0007_0x00=8 +hwmon_curr.bit_offset_0x0007_0x00= +hwmon_curr.str_cons_0x0007_0x00=curr4_input +hwmon_curr.mode_0x0007_0x01=str_constant +hwmon_curr.str_cons_0x0007_0x01=OSFP_VDD3.3V_B3_C +hwmon_curr.mode_0x0007_0x02=str_constant +hwmon_curr.str_cons_0x0007_0x02=xdpe12284c +hwmon_curr.mode_0x0007_0x03=constant +hwmon_curr.int_cons_0x0007_0x03=73000 +hwmon_curr.mode_0x0007_0x05=constant +hwmon_curr.int_cons_0x0007_0x05=-4500 + +# curr8 +hwmon_curr.mode_0x0008_0x00=config +hwmon_curr.int_cons_0x0008_0x00=0 +hwmon_curr.src_0x0008_0x00=file +hwmon_curr.frmt_0x0008_0x00=buf +hwmon_curr.fpath_0x0008_0x00=/sys/bus/i2c/devices/92-0062/hwmon/ +hwmon_curr.addr_0x0008_0x00=0 +hwmon_curr.len_0x0008_0x00=8 +hwmon_curr.bit_offset_0x0008_0x00= +hwmon_curr.str_cons_0x0008_0x00=curr3_input +hwmon_curr.mode_0x0008_0x01=str_constant +hwmon_curr.str_cons_0x0008_0x01=OSFP_VDD3.3V_A4_C +hwmon_curr.mode_0x0008_0x02=str_constant +hwmon_curr.str_cons_0x0008_0x02=xdpe12284c +hwmon_curr.mode_0x0008_0x03=constant +hwmon_curr.int_cons_0x0008_0x03=73000 +hwmon_curr.mode_0x0008_0x05=constant +hwmon_curr.int_cons_0x0008_0x05=-4500 + +# curr9 +hwmon_curr.mode_0x0009_0x00=config +hwmon_curr.int_cons_0x0009_0x00=0 +hwmon_curr.src_0x0009_0x00=file +hwmon_curr.frmt_0x0009_0x00=buf +hwmon_curr.fpath_0x0009_0x00=/sys/bus/i2c/devices/92-0062/hwmon/ +hwmon_curr.addr_0x0009_0x00=0 +hwmon_curr.len_0x0009_0x00=8 +hwmon_curr.bit_offset_0x0009_0x00= +hwmon_curr.str_cons_0x0009_0x00=curr4_input +hwmon_curr.mode_0x0009_0x01=str_constant +hwmon_curr.str_cons_0x0009_0x01=OSFP_VDD3.3V_B4_C +hwmon_curr.mode_0x0009_0x02=str_constant +hwmon_curr.str_cons_0x0009_0x02=xdpe12284c +hwmon_curr.mode_0x0009_0x03=constant +hwmon_curr.int_cons_0x0009_0x03=73000 +hwmon_curr.mode_0x0009_0x05=constant +hwmon_curr.int_cons_0x0009_0x05=-4500 + +# curr10 +hwmon_curr.mode_0x000a_0x00=config +hwmon_curr.int_cons_0x000a_0x00=0 +hwmon_curr.src_0x000a_0x00=file +hwmon_curr.frmt_0x000a_0x00=buf +hwmon_curr.fpath_0x000a_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_curr.addr_0x000a_0x00=0 +hwmon_curr.len_0x000a_0x00=8 +hwmon_curr.bit_offset_0x000a_0x00= +hwmon_curr.str_cons_0x000a_0x00=curr3_input +hwmon_curr.mode_0x000a_0x01=str_constant +hwmon_curr.str_cons_0x000a_0x01=VDD_PHYTILE6_C +hwmon_curr.mode_0x000a_0x02=str_constant +hwmon_curr.str_cons_0x000a_0x02=xdpe12284c +hwmon_curr.mode_0x000a_0x03=constant +hwmon_curr.int_cons_0x000a_0x03=64000 +hwmon_curr.mode_0x000a_0x05=constant +hwmon_curr.int_cons_0x000a_0x05=-3000 + +# curr11 +hwmon_curr.mode_0x000b_0x00=config +hwmon_curr.int_cons_0x000b_0x00=0 +hwmon_curr.src_0x000b_0x00=file +hwmon_curr.frmt_0x000b_0x00=buf +hwmon_curr.fpath_0x000b_0x00=/sys/bus/i2c/devices/95-0060/hwmon/ +hwmon_curr.addr_0x000b_0x00=0 +hwmon_curr.len_0x000b_0x00=8 +hwmon_curr.bit_offset_0x000b_0x00= +hwmon_curr.str_cons_0x000b_0x00=curr4_input +hwmon_curr.mode_0x000b_0x01=str_constant +hwmon_curr.str_cons_0x000b_0x01=VDD_PHYTILE7_C +hwmon_curr.mode_0x000b_0x02=str_constant +hwmon_curr.str_cons_0x000b_0x02=xdpe12284c +hwmon_curr.mode_0x000b_0x03=constant +hwmon_curr.int_cons_0x000b_0x03=64000 +hwmon_curr.mode_0x000b_0x05=constant +hwmon_curr.int_cons_0x000b_0x05=-3000 + +# curr12 +hwmon_curr.mode_0x000c_0x00=config +hwmon_curr.int_cons_0x000c_0x00=0 +hwmon_curr.src_0x000c_0x00=file +hwmon_curr.frmt_0x000c_0x00=buf +hwmon_curr.fpath_0x000c_0x00=/sys/bus/i2c/devices/85-0074/hwmon/ +hwmon_curr.addr_0x000c_0x00=0 +hwmon_curr.len_0x000c_0x00=8 +hwmon_curr.bit_offset_0x000c_0x00= +hwmon_curr.str_cons_0x000c_0x00=curr3_input +hwmon_curr.mode_0x000c_0x01=str_constant +hwmon_curr.str_cons_0x000c_0x01=VDDA_0P72_PHY2_C +hwmon_curr.mode_0x000c_0x02=str_constant +hwmon_curr.str_cons_0x000c_0x02=xdpe12284c +hwmon_curr.mode_0x000c_0x03=constant +hwmon_curr.int_cons_0x000c_0x03=50000 +hwmon_curr.mode_0x000c_0x05=constant +hwmon_curr.int_cons_0x000c_0x05=-3000 + +# curr13 +hwmon_curr.mode_0x000d_0x00=config +hwmon_curr.int_cons_0x000d_0x00=0 +hwmon_curr.src_0x000d_0x00=file +hwmon_curr.frmt_0x000d_0x00=buf +hwmon_curr.fpath_0x000d_0x00=/sys/bus/i2c/devices/85-0062/hwmon/ +hwmon_curr.addr_0x000d_0x00=0 +hwmon_curr.len_0x000d_0x00=8 +hwmon_curr.bit_offset_0x000d_0x00= +hwmon_curr.str_cons_0x000d_0x00=curr4_input +hwmon_curr.mode_0x000d_0x01=str_constant +hwmon_curr.str_cons_0x000d_0x01=VDDA_0P72_PHY1_C +hwmon_curr.mode_0x000d_0x02=str_constant +hwmon_curr.str_cons_0x000d_0x02=xdpe12284c +hwmon_curr.mode_0x000d_0x03=constant +hwmon_curr.int_cons_0x000d_0x03=50000 +hwmon_curr.mode_0x000d_0x05=constant +hwmon_curr.int_cons_0x000d_0x05=-3000 + +# curr14 +hwmon_curr.mode_0x000e_0x00=config +hwmon_curr.int_cons_0x000e_0x00=0 +hwmon_curr.src_0x000e_0x00=file +hwmon_curr.frmt_0x000e_0x00=buf +hwmon_curr.fpath_0x000e_0x00=/sys/bus/i2c/devices/87-0074/hwmon/ +hwmon_curr.addr_0x000e_0x00=0 +hwmon_curr.len_0x000e_0x00=8 +hwmon_curr.bit_offset_0x000e_0x00= +hwmon_curr.str_cons_0x000e_0x00=curr3_input +hwmon_curr.mode_0x000e_0x01=str_constant +hwmon_curr.str_cons_0x000e_0x01=VDDA_0P72_PHY0_C +hwmon_curr.mode_0x000e_0x02=str_constant +hwmon_curr.str_cons_0x000e_0x02=xdpe12284c +hwmon_curr.mode_0x000e_0x03=constant +hwmon_curr.int_cons_0x000e_0x03=50000 +hwmon_curr.mode_0x000e_0x05=constant +hwmon_curr.int_cons_0x000e_0x05=-3000 + +# curr15 +hwmon_curr.mode_0x000f_0x00=config +hwmon_curr.int_cons_0x000f_0x00=0 +hwmon_curr.src_0x000f_0x00=file +hwmon_curr.frmt_0x000f_0x00=buf +hwmon_curr.fpath_0x000f_0x00=/sys/bus/i2c/devices/87-0074/hwmon/ +hwmon_curr.addr_0x000f_0x00=0 +hwmon_curr.len_0x000f_0x00=8 +hwmon_curr.bit_offset_0x000f_0x00= +hwmon_curr.str_cons_0x000f_0x00=curr4_input +hwmon_curr.mode_0x000f_0x01=str_constant +hwmon_curr.str_cons_0x000f_0x01=VDDA_0P72_PHY4_C +hwmon_curr.mode_0x000f_0x02=str_constant +hwmon_curr.str_cons_0x000f_0x02=xdpe12284c +hwmon_curr.mode_0x000f_0x03=constant +hwmon_curr.int_cons_0x000f_0x03=50000 +hwmon_curr.mode_0x000f_0x05=constant +hwmon_curr.int_cons_0x000f_0x05=-3000 + +# curr16 +hwmon_curr.mode_0x0010_0x00=config +hwmon_curr.int_cons_0x0010_0x00=0 +hwmon_curr.src_0x0010_0x00=file +hwmon_curr.frmt_0x0010_0x00=buf +hwmon_curr.fpath_0x0010_0x00=/sys/bus/i2c/devices/89-0074/hwmon/ +hwmon_curr.addr_0x0010_0x00=0 +hwmon_curr.len_0x0010_0x00=8 +hwmon_curr.bit_offset_0x0010_0x00= +hwmon_curr.str_cons_0x0010_0x00=curr3_input +hwmon_curr.mode_0x0010_0x01=str_constant +hwmon_curr.str_cons_0x0010_0x01=VDD_1P5V_0_C +hwmon_curr.mode_0x0010_0x02=str_constant +hwmon_curr.str_cons_0x0010_0x02=xdpe12284c +hwmon_curr.mode_0x0010_0x03=constant +hwmon_curr.int_cons_0x0010_0x03=22000 +hwmon_curr.mode_0x0010_0x05=constant +hwmon_curr.int_cons_0x0010_0x05=-3000 + +# curr17 +hwmon_curr.mode_0x0011_0x00=config +hwmon_curr.int_cons_0x0011_0x00=0 +hwmon_curr.src_0x0011_0x00=file +hwmon_curr.frmt_0x0011_0x00=buf +hwmon_curr.fpath_0x0011_0x00=/sys/bus/i2c/devices/89-0074/hwmon/ +hwmon_curr.addr_0x0011_0x00=0 +hwmon_curr.len_0x0011_0x00=8 +hwmon_curr.bit_offset_0x0011_0x00= +hwmon_curr.str_cons_0x0011_0x00=curr4_input +hwmon_curr.mode_0x0011_0x01=str_constant +hwmon_curr.str_cons_0x0011_0x01=VDD_1P5V_1_C +hwmon_curr.mode_0x0011_0x02=str_constant +hwmon_curr.str_cons_0x0011_0x02=xdpe12284c +hwmon_curr.mode_0x0011_0x03=constant +hwmon_curr.int_cons_0x0011_0x03=22000 +hwmon_curr.mode_0x0011_0x05=constant +hwmon_curr.int_cons_0x0011_0x05=-3000 + +# curr18 +hwmon_curr.mode_0x0012_0x00=config +hwmon_curr.int_cons_0x0012_0x00=0 +hwmon_curr.src_0x0012_0x00=file +hwmon_curr.frmt_0x0012_0x00=buf +hwmon_curr.fpath_0x0012_0x00=/sys/bus/i2c/devices/85-0062/hwmon/ +hwmon_curr.addr_0x0012_0x00=0 +hwmon_curr.len_0x0012_0x00=8 +hwmon_curr.bit_offset_0x0012_0x00= +hwmon_curr.str_cons_0x0012_0x00=curr3_input +hwmon_curr.mode_0x0012_0x01=str_constant +hwmon_curr.str_cons_0x0012_0x01=VDD0_9V_ANLG0_C +hwmon_curr.mode_0x0012_0x02=str_constant +hwmon_curr.str_cons_0x0012_0x02=xdpe12284c +hwmon_curr.mode_0x0012_0x03=constant +hwmon_curr.int_cons_0x0012_0x03=120000 +hwmon_curr.mode_0x0012_0x05=constant +hwmon_curr.int_cons_0x0012_0x05=-6000 + +# curr19 +hwmon_curr.mode_0x0013_0x00=config +hwmon_curr.int_cons_0x0013_0x00=0 +hwmon_curr.src_0x0013_0x00=file +hwmon_curr.frmt_0x0013_0x00=buf +hwmon_curr.fpath_0x0013_0x00=/sys/bus/i2c/devices/85-0062/hwmon/ +hwmon_curr.addr_0x0013_0x00=0 +hwmon_curr.len_0x0013_0x00=8 +hwmon_curr.bit_offset_0x0013_0x00= +hwmon_curr.str_cons_0x0013_0x00=curr4_input +hwmon_curr.mode_0x0013_0x01=str_constant +hwmon_curr.str_cons_0x0013_0x01=VDD0_75V_ANLG0_C +hwmon_curr.mode_0x0013_0x02=str_constant +hwmon_curr.str_cons_0x0013_0x02=xdpe12284c +hwmon_curr.mode_0x0013_0x03=constant +hwmon_curr.int_cons_0x0013_0x03=60000 +hwmon_curr.mode_0x0013_0x05=constant +hwmon_curr.int_cons_0x0013_0x05=-3000 + +# curr20 +hwmon_curr.mode_0x0014_0x00=config +hwmon_curr.int_cons_0x0014_0x00=0 +hwmon_curr.src_0x0014_0x00=file +hwmon_curr.frmt_0x0014_0x00=buf +hwmon_curr.fpath_0x0014_0x00=/sys/bus/i2c/devices/87-0062/hwmon/ +hwmon_curr.addr_0x0014_0x00=0 +hwmon_curr.len_0x0014_0x00=8 +hwmon_curr.bit_offset_0x0014_0x00= +hwmon_curr.str_cons_0x0014_0x00=curr3_input +hwmon_curr.mode_0x0014_0x01=str_constant +hwmon_curr.str_cons_0x0014_0x01=VDD0_9V_ANLG1_C +hwmon_curr.mode_0x0014_0x02=str_constant +hwmon_curr.str_cons_0x0014_0x02=xdpe12284c +hwmon_curr.mode_0x0014_0x03=constant +hwmon_curr.int_cons_0x0014_0x03=120000 +hwmon_curr.mode_0x0014_0x05=constant +hwmon_curr.int_cons_0x0014_0x05=-6000 + +# curr21 +hwmon_curr.mode_0x0015_0x00=config +hwmon_curr.int_cons_0x0015_0x00=0 +hwmon_curr.src_0x0015_0x00=file +hwmon_curr.frmt_0x0015_0x00=buf +hwmon_curr.fpath_0x0015_0x00=/sys/bus/i2c/devices/87-0062/hwmon/ +hwmon_curr.addr_0x0015_0x00=0 +hwmon_curr.len_0x0015_0x00=8 +hwmon_curr.bit_offset_0x0015_0x00= +hwmon_curr.str_cons_0x0015_0x00=curr4_input +hwmon_curr.mode_0x0015_0x01=str_constant +hwmon_curr.str_cons_0x0015_0x01=VDD0_75V_ANLG1_C +hwmon_curr.mode_0x0015_0x02=str_constant +hwmon_curr.str_cons_0x0015_0x02=xdpe12284c +hwmon_curr.mode_0x0015_0x03=constant +hwmon_curr.int_cons_0x0015_0x03=60000 +hwmon_curr.mode_0x0015_0x05=constant +hwmon_curr.int_cons_0x0015_0x05=-3000 + +# curr22 +hwmon_curr.mode_0x0016_0x00=config +hwmon_curr.int_cons_0x0016_0x00=0 +hwmon_curr.src_0x0016_0x00=file +hwmon_curr.frmt_0x0016_0x00=buf +hwmon_curr.fpath_0x0016_0x00=/sys/bus/i2c/devices/87-0060/hwmon/ +hwmon_curr.addr_0x0016_0x00=0 +hwmon_curr.len_0x0016_0x00=8 +hwmon_curr.bit_offset_0x0016_0x00= +hwmon_curr.str_cons_0x0016_0x00=curr3_input +hwmon_curr.mode_0x0016_0x01=str_constant +hwmon_curr.str_cons_0x0016_0x01=VDD_PHYTILE1_C +hwmon_curr.mode_0x0016_0x02=str_constant +hwmon_curr.str_cons_0x0016_0x02=xdpe12284c +hwmon_curr.mode_0x0016_0x03=constant +hwmon_curr.int_cons_0x0016_0x03=64000 +hwmon_curr.mode_0x0016_0x05=constant +hwmon_curr.int_cons_0x0016_0x05=-3000 + +# curr23 +hwmon_curr.mode_0x0017_0x00=config +hwmon_curr.int_cons_0x0017_0x00=0 +hwmon_curr.src_0x0017_0x00=file +hwmon_curr.frmt_0x0017_0x00=buf +hwmon_curr.fpath_0x0017_0x00=/sys/bus/i2c/devices/87-0060/hwmon/ +hwmon_curr.addr_0x0017_0x00=0 +hwmon_curr.len_0x0017_0x00=8 +hwmon_curr.bit_offset_0x0017_0x00= +hwmon_curr.str_cons_0x0017_0x00=curr4_input +hwmon_curr.mode_0x0017_0x01=str_constant +hwmon_curr.str_cons_0x0017_0x01=VDD_PHYTILE0_C +hwmon_curr.mode_0x0017_0x02=str_constant +hwmon_curr.str_cons_0x0017_0x02=xdpe12284c +hwmon_curr.mode_0x0017_0x03=constant +hwmon_curr.int_cons_0x0017_0x03=64000 +hwmon_curr.mode_0x0017_0x05=constant +hwmon_curr.int_cons_0x0017_0x05=-3000 + +# curr24 +hwmon_curr.mode_0x0018_0x00=config +hwmon_curr.int_cons_0x0018_0x00=0 +hwmon_curr.src_0x0018_0x00=file +hwmon_curr.frmt_0x0018_0x00=buf +hwmon_curr.fpath_0x0018_0x00=/sys/bus/i2c/devices/89-0060/hwmon/ +hwmon_curr.addr_0x0018_0x00=0 +hwmon_curr.len_0x0018_0x00=8 +hwmon_curr.bit_offset_0x0018_0x00= +hwmon_curr.str_cons_0x0018_0x00=curr3_input +hwmon_curr.mode_0x0018_0x01=str_constant +hwmon_curr.str_cons_0x0018_0x01=VDD_PHYTILE2_C +hwmon_curr.mode_0x0018_0x02=str_constant +hwmon_curr.str_cons_0x0018_0x02=xdpe12284c +hwmon_curr.mode_0x0018_0x03=constant +hwmon_curr.int_cons_0x0018_0x03=64000 +hwmon_curr.mode_0x0018_0x05=constant +hwmon_curr.int_cons_0x0018_0x05=-3000 + +# curr25 +hwmon_curr.mode_0x0019_0x00=config +hwmon_curr.int_cons_0x0019_0x00=0 +hwmon_curr.src_0x0019_0x00=file +hwmon_curr.frmt_0x0019_0x00=buf +hwmon_curr.fpath_0x0019_0x00=/sys/bus/i2c/devices/89-0060/hwmon/ +hwmon_curr.addr_0x0019_0x00=0 +hwmon_curr.len_0x0019_0x00=8 +hwmon_curr.bit_offset_0x0019_0x00= +hwmon_curr.str_cons_0x0019_0x00=curr4_input +hwmon_curr.mode_0x0019_0x01=str_constant +hwmon_curr.str_cons_0x0019_0x01=VDD_PHYTILE3_C +hwmon_curr.mode_0x0019_0x02=str_constant +hwmon_curr.str_cons_0x0019_0x02=xdpe12284c +hwmon_curr.mode_0x0019_0x03=constant +hwmon_curr.int_cons_0x0019_0x03=64000 +hwmon_curr.mode_0x0019_0x05=constant +hwmon_curr.int_cons_0x0019_0x05=-3000 + +# curr26 +hwmon_curr.mode_0x001a_0x00=config +hwmon_curr.int_cons_0x001a_0x00=0 +hwmon_curr.src_0x001a_0x00=file +hwmon_curr.frmt_0x001a_0x00=buf +hwmon_curr.fpath_0x001a_0x00=/sys/bus/i2c/devices/90-0060/hwmon/ +hwmon_curr.addr_0x001a_0x00=0 +hwmon_curr.len_0x001a_0x00=8 +hwmon_curr.bit_offset_0x001a_0x00= +hwmon_curr.str_cons_0x001a_0x00=curr3_input +hwmon_curr.mode_0x001a_0x01=str_constant +hwmon_curr.str_cons_0x001a_0x01=VDD_PHYTILE4_C +hwmon_curr.mode_0x001a_0x02=str_constant +hwmon_curr.str_cons_0x001a_0x02=xdpe12284c +hwmon_curr.mode_0x001a_0x03=constant +hwmon_curr.int_cons_0x001a_0x03=64000 +hwmon_curr.mode_0x001a_0x05=constant +hwmon_curr.int_cons_0x001a_0x05=-3000 + +# curr27 +hwmon_curr.mode_0x001b_0x00=config +hwmon_curr.int_cons_0x001b_0x00=0 +hwmon_curr.src_0x001b_0x00=file +hwmon_curr.frmt_0x001b_0x00=buf +hwmon_curr.fpath_0x001b_0x00=/sys/bus/i2c/devices/90-0060/hwmon/ +hwmon_curr.addr_0x001b_0x00=0 +hwmon_curr.len_0x001b_0x00=8 +hwmon_curr.bit_offset_0x001b_0x00= +hwmon_curr.str_cons_0x001b_0x00=curr4_input +hwmon_curr.mode_0x001b_0x01=str_constant +hwmon_curr.str_cons_0x001b_0x01=VDD_PHYTILE5_C +hwmon_curr.mode_0x001b_0x02=str_constant +hwmon_curr.str_cons_0x001b_0x02=xdpe12284c +hwmon_curr.mode_0x001b_0x03=constant +hwmon_curr.int_cons_0x001b_0x03=64000 +hwmon_curr.mode_0x001b_0x05=constant +hwmon_curr.int_cons_0x001b_0x05=-3000 + +# curr28 +hwmon_curr.mode_0x001c_0x00=config +hwmon_curr.int_cons_0x001c_0x00=0 +hwmon_curr.src_0x001c_0x00=file +hwmon_curr.frmt_0x001c_0x00=buf +hwmon_curr.fpath_0x001c_0x00=/sys/bus/i2c/devices/98-0040/hwmon/ +hwmon_curr.addr_0x001c_0x00=0 +hwmon_curr.len_0x001c_0x00=8 +hwmon_curr.bit_offset_0x001c_0x00= +hwmon_curr.str_cons_0x001c_0x00=curr1_input +hwmon_curr.mode_0x001c_0x01=str_constant +hwmon_curr.str_cons_0x001c_0x01=VDDO1.2V_C +hwmon_curr.mode_0x001c_0x02=str_constant +hwmon_curr.str_cons_0x001c_0x02=INA3221A +hwmon_curr.mode_0x001c_0x03=constant +hwmon_curr.int_cons_0x001c_0x03=13200 +hwmon_curr.mode_0x001c_0x05=constant +hwmon_curr.int_cons_0x001c_0x05=-3000 + +# curr29 +hwmon_curr.mode_0x001d_0x00=config +hwmon_curr.int_cons_0x001d_0x00=0 +hwmon_curr.src_0x001d_0x00=file +hwmon_curr.frmt_0x001d_0x00=buf +hwmon_curr.fpath_0x001d_0x00=/sys/bus/i2c/devices/98-0040/hwmon/ +hwmon_curr.addr_0x001d_0x00=0 +hwmon_curr.len_0x001d_0x00=8 +hwmon_curr.bit_offset_0x001d_0x00= +hwmon_curr.str_cons_0x001d_0x00=curr2_input +hwmon_curr.mode_0x001d_0x01=str_constant +hwmon_curr.str_cons_0x001d_0x01=VDDO1.8V_C +hwmon_curr.mode_0x001d_0x02=str_constant +hwmon_curr.str_cons_0x001d_0x02=INA3221A +hwmon_curr.mode_0x001d_0x03=constant +hwmon_curr.int_cons_0x001d_0x03=13200 +hwmon_curr.mode_0x001d_0x05=constant +hwmon_curr.int_cons_0x001d_0x05=-3000 + +# curr30 +hwmon_curr.mode_0x001e_0x00=config +hwmon_curr.int_cons_0x001e_0x00=0 +hwmon_curr.src_0x001e_0x00=file +hwmon_curr.frmt_0x001e_0x00=buf +hwmon_curr.fpath_0x001e_0x00=/sys/bus/i2c/devices/98-0040/hwmon/ +hwmon_curr.addr_0x001e_0x00=0 +hwmon_curr.len_0x001e_0x00=8 +hwmon_curr.bit_offset_0x001e_0x00= +hwmon_curr.str_cons_0x001e_0x00=curr3_input +hwmon_curr.mode_0x001e_0x01=str_constant +hwmon_curr.str_cons_0x001e_0x01=VDD2.2V_C +hwmon_curr.mode_0x001e_0x02=str_constant +hwmon_curr.str_cons_0x001e_0x02=INA3221A +hwmon_curr.mode_0x001e_0x03=constant +hwmon_curr.int_cons_0x001e_0x03=6000 +hwmon_curr.mode_0x001e_0x05=constant +hwmon_curr.int_cons_0x001e_0x05=-3000 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SFF.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SFF.cfg new file mode 100644 index 0000000000..da451f6288 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/SFF.cfg @@ -0,0 +1,2681 @@ +# +# @Fill in the agreement +# 1. Complete comments must be filled in before configuration items. Comments must not be filled in the same line of +# configuration items and invalid Spaces must not be added between configuration items +# 2. The value can be in 10 or hexadecimal format. The hexadecimal value starts with "0x" +# 3. Some configuration items do not need to be filled in a specific product. To facilitate other products to copy and +# fill in the configuration items, do not delete them +# 4. Configuration item + +# Configuration item: Number of optical modules +# Description: Format dev_num_[main_dev]_[minor_dev] +# Note: main_dev,optical module is 3, minor_dev, 0:does not exist +dev_num_3_0=66 + +# Configuration items:: optical module EEPROM size +# Description: Format eeprom_size_[main_dev]_[index] +# Note: main_dev,optical module is 3, index, Optical module index, starting from 1 +eeprom_size_3_1=0x8180 +eeprom_size_3_2=0x8180 +eeprom_size_3_3=0x8180 +eeprom_size_3_4=0x8180 +eeprom_size_3_5=0x8180 +eeprom_size_3_6=0x8180 +eeprom_size_3_7=0x8180 +eeprom_size_3_8=0x8180 +eeprom_size_3_9=0x8180 +eeprom_size_3_10=0x8180 +eeprom_size_3_11=0x8180 +eeprom_size_3_12=0x8180 +eeprom_size_3_13=0x8180 +eeprom_size_3_14=0x8180 +eeprom_size_3_15=0x8180 +eeprom_size_3_16=0x8180 +eeprom_size_3_17=0x8180 +eeprom_size_3_18=0x8180 +eeprom_size_3_19=0x8180 +eeprom_size_3_20=0x8180 +eeprom_size_3_21=0x8180 +eeprom_size_3_22=0x8180 +eeprom_size_3_23=0x8180 +eeprom_size_3_24=0x8180 +eeprom_size_3_25=0x8180 +eeprom_size_3_26=0x8180 +eeprom_size_3_27=0x8180 +eeprom_size_3_28=0x8180 +eeprom_size_3_29=0x8180 +eeprom_size_3_30=0x8180 +eeprom_size_3_31=0x8180 +eeprom_size_3_32=0x8180 +eeprom_size_3_33=0x8180 +eeprom_size_3_34=0x8180 +eeprom_size_3_35=0x8180 +eeprom_size_3_36=0x8180 +eeprom_size_3_37=0x8180 +eeprom_size_3_38=0x8180 +eeprom_size_3_39=0x8180 +eeprom_size_3_40=0x8180 +eeprom_size_3_41=0x8180 +eeprom_size_3_42=0x8180 +eeprom_size_3_43=0x8180 +eeprom_size_3_44=0x8180 +eeprom_size_3_45=0x8180 +eeprom_size_3_46=0x8180 +eeprom_size_3_47=0x8180 +eeprom_size_3_48=0x8180 +eeprom_size_3_49=0x8180 +eeprom_size_3_50=0x8180 +eeprom_size_3_51=0x8180 +eeprom_size_3_52=0x8180 +eeprom_size_3_53=0x8180 +eeprom_size_3_54=0x8180 +eeprom_size_3_55=0x8180 +eeprom_size_3_56=0x8180 +eeprom_size_3_57=0x8180 +eeprom_size_3_58=0x8180 +eeprom_size_3_59=0x8180 +eeprom_size_3_60=0x8180 +eeprom_size_3_61=0x8180 +eeprom_size_3_62=0x8180 +eeprom_size_3_63=0x8180 +eeprom_size_3_64=0x8180 +eeprom_size_3_65=0x8180 +eeprom_size_3_66=0x8180 + +# Configuration items: optical module EEPROM sysfs path +# Description: Format eeprom_size_[main_dev]_[index] +# Note: main_dev,optical module is 3, index, Optical module index, starting from 1 +eeprom_path_3_1=/sys/bus/i2c/devices/233-0050/eeprom +eeprom_path_3_2=/sys/bus/i2c/devices/234-0050/eeprom +eeprom_path_3_3=/sys/bus/i2c/devices/201-0050/eeprom +eeprom_path_3_4=/sys/bus/i2c/devices/202-0050/eeprom +eeprom_path_3_5=/sys/bus/i2c/devices/235-0050/eeprom +eeprom_path_3_6=/sys/bus/i2c/devices/236-0050/eeprom +eeprom_path_3_7=/sys/bus/i2c/devices/203-0050/eeprom +eeprom_path_3_8=/sys/bus/i2c/devices/204-0050/eeprom +eeprom_path_3_9=/sys/bus/i2c/devices/237-0050/eeprom +eeprom_path_3_10=/sys/bus/i2c/devices/238-0050/eeprom +eeprom_path_3_11=/sys/bus/i2c/devices/205-0050/eeprom +eeprom_path_3_12=/sys/bus/i2c/devices/206-0050/eeprom +eeprom_path_3_13=/sys/bus/i2c/devices/239-0050/eeprom +eeprom_path_3_14=/sys/bus/i2c/devices/240-0050/eeprom +eeprom_path_3_15=/sys/bus/i2c/devices/207-0050/eeprom +eeprom_path_3_16=/sys/bus/i2c/devices/208-0050/eeprom +eeprom_path_3_17=/sys/bus/i2c/devices/241-0050/eeprom +eeprom_path_3_18=/sys/bus/i2c/devices/242-0050/eeprom +eeprom_path_3_19=/sys/bus/i2c/devices/209-0050/eeprom +eeprom_path_3_20=/sys/bus/i2c/devices/210-0050/eeprom +eeprom_path_3_21=/sys/bus/i2c/devices/243-0050/eeprom +eeprom_path_3_22=/sys/bus/i2c/devices/244-0050/eeprom +eeprom_path_3_23=/sys/bus/i2c/devices/211-0050/eeprom +eeprom_path_3_24=/sys/bus/i2c/devices/212-0050/eeprom +eeprom_path_3_25=/sys/bus/i2c/devices/245-0050/eeprom +eeprom_path_3_26=/sys/bus/i2c/devices/246-0050/eeprom +eeprom_path_3_27=/sys/bus/i2c/devices/213-0050/eeprom +eeprom_path_3_28=/sys/bus/i2c/devices/214-0050/eeprom +eeprom_path_3_29=/sys/bus/i2c/devices/247-0050/eeprom +eeprom_path_3_30=/sys/bus/i2c/devices/248-0050/eeprom +eeprom_path_3_31=/sys/bus/i2c/devices/215-0050/eeprom +eeprom_path_3_32=/sys/bus/i2c/devices/216-0050/eeprom +eeprom_path_3_33=/sys/bus/i2c/devices/249-0050/eeprom +eeprom_path_3_34=/sys/bus/i2c/devices/250-0050/eeprom +eeprom_path_3_35=/sys/bus/i2c/devices/217-0050/eeprom +eeprom_path_3_36=/sys/bus/i2c/devices/218-0050/eeprom +eeprom_path_3_37=/sys/bus/i2c/devices/251-0050/eeprom +eeprom_path_3_38=/sys/bus/i2c/devices/252-0050/eeprom +eeprom_path_3_39=/sys/bus/i2c/devices/219-0050/eeprom +eeprom_path_3_40=/sys/bus/i2c/devices/220-0050/eeprom +eeprom_path_3_41=/sys/bus/i2c/devices/253-0050/eeprom +eeprom_path_3_42=/sys/bus/i2c/devices/254-0050/eeprom +eeprom_path_3_43=/sys/bus/i2c/devices/221-0050/eeprom +eeprom_path_3_44=/sys/bus/i2c/devices/222-0050/eeprom +eeprom_path_3_45=/sys/bus/i2c/devices/255-0050/eeprom +eeprom_path_3_46=/sys/bus/i2c/devices/256-0050/eeprom +eeprom_path_3_47=/sys/bus/i2c/devices/223-0050/eeprom +eeprom_path_3_48=/sys/bus/i2c/devices/224-0050/eeprom +eeprom_path_3_49=/sys/bus/i2c/devices/257-0050/eeprom +eeprom_path_3_50=/sys/bus/i2c/devices/258-0050/eeprom +eeprom_path_3_51=/sys/bus/i2c/devices/225-0050/eeprom +eeprom_path_3_52=/sys/bus/i2c/devices/226-0050/eeprom +eeprom_path_3_53=/sys/bus/i2c/devices/259-0050/eeprom +eeprom_path_3_54=/sys/bus/i2c/devices/260-0050/eeprom +eeprom_path_3_55=/sys/bus/i2c/devices/227-0050/eeprom +eeprom_path_3_56=/sys/bus/i2c/devices/228-0050/eeprom +eeprom_path_3_57=/sys/bus/i2c/devices/261-0050/eeprom +eeprom_path_3_58=/sys/bus/i2c/devices/262-0050/eeprom +eeprom_path_3_59=/sys/bus/i2c/devices/229-0050/eeprom +eeprom_path_3_60=/sys/bus/i2c/devices/230-0050/eeprom +eeprom_path_3_61=/sys/bus/i2c/devices/263-0050/eeprom +eeprom_path_3_62=/sys/bus/i2c/devices/264-0050/eeprom +eeprom_path_3_63=/sys/bus/i2c/devices/231-0050/eeprom +eeprom_path_3_64=/sys/bus/i2c/devices/232-0050/eeprom +eeprom_path_3_65=/sys/bus/i2c/devices/265-0050/eeprom +eeprom_path_3_66=/sys/bus/i2c/devices/266-0050/eeprom + + +# Configuration items: Optical module CPLD register +# Description: Format sff_cpld_reg_[sff_index]_[cpld_reg] +# Note: sff_index indicates the optical module number, starting from 1. 0 indicates that the power_on register is useful +# cpld_reg 1:power_on 2:tx_fault, 3:tx_dis 4:reserve 5:rx_los +# 6:reset 7:lpmode 8:module_present 9:interrupt + + +# 1600G module reset signal +sff_cpld_reg.mode_1_6=config +sff_cpld_reg.src_1_6=cpld +sff_cpld_reg.frmt_1_6=byte +sff_cpld_reg.pola_1_6= +sff_cpld_reg.addr_1_6=0x00020020 +sff_cpld_reg.len_1_6=1 +sff_cpld_reg.bit_offset_1_6= + +sff_cpld_reg.mode_2_6=config +sff_cpld_reg.src_2_6=cpld +sff_cpld_reg.frmt_2_6=byte +sff_cpld_reg.pola_2_6= +sff_cpld_reg.addr_2_6=0x00020021 +sff_cpld_reg.len_2_6=1 +sff_cpld_reg.bit_offset_2_6= + +sff_cpld_reg.mode_3_6=config +sff_cpld_reg.src_3_6=cpld +sff_cpld_reg.frmt_3_6=byte +sff_cpld_reg.pola_3_6= +sff_cpld_reg.addr_3_6=0x00020022 +sff_cpld_reg.len_3_6=1 +sff_cpld_reg.bit_offset_3_6= + +sff_cpld_reg.mode_4_6=config +sff_cpld_reg.src_4_6=cpld +sff_cpld_reg.frmt_4_6=byte +sff_cpld_reg.pola_4_6= +sff_cpld_reg.addr_4_6=0x00020023 +sff_cpld_reg.len_4_6=1 +sff_cpld_reg.bit_offset_4_6= + +sff_cpld_reg.mode_5_6=config +sff_cpld_reg.src_5_6=cpld +sff_cpld_reg.frmt_5_6=byte +sff_cpld_reg.pola_5_6= +sff_cpld_reg.addr_5_6=0x00020024 +sff_cpld_reg.len_5_6=1 +sff_cpld_reg.bit_offset_5_6= + +sff_cpld_reg.mode_6_6=config +sff_cpld_reg.src_6_6=cpld +sff_cpld_reg.frmt_6_6=byte +sff_cpld_reg.pola_6_6= +sff_cpld_reg.addr_6_6=0x00020025 +sff_cpld_reg.len_6_6=1 +sff_cpld_reg.bit_offset_6_6= + +sff_cpld_reg.mode_7_6=config +sff_cpld_reg.src_7_6=cpld +sff_cpld_reg.frmt_7_6=byte +sff_cpld_reg.pola_7_6= +sff_cpld_reg.addr_7_6=0x00020026 +sff_cpld_reg.len_7_6=1 +sff_cpld_reg.bit_offset_7_6= + +sff_cpld_reg.mode_8_6=config +sff_cpld_reg.src_8_6=cpld +sff_cpld_reg.frmt_8_6=byte +sff_cpld_reg.pola_8_6= +sff_cpld_reg.addr_8_6=0x00020027 +sff_cpld_reg.len_8_6=1 +sff_cpld_reg.bit_offset_8_6= + +sff_cpld_reg.mode_9_6=config +sff_cpld_reg.src_9_6=cpld +sff_cpld_reg.frmt_9_6=byte +sff_cpld_reg.pola_9_6= +sff_cpld_reg.addr_9_6=0x00020028 +sff_cpld_reg.len_9_6=1 +sff_cpld_reg.bit_offset_9_6= + +sff_cpld_reg.mode_10_6=config +sff_cpld_reg.src_10_6=cpld +sff_cpld_reg.frmt_10_6=byte +sff_cpld_reg.pola_10_6= +sff_cpld_reg.addr_10_6=0x00020029 +sff_cpld_reg.len_10_6=1 +sff_cpld_reg.bit_offset_10_6= + +sff_cpld_reg.mode_11_6=config +sff_cpld_reg.src_11_6=cpld +sff_cpld_reg.frmt_11_6=byte +sff_cpld_reg.pola_11_6= +sff_cpld_reg.addr_11_6=0x0002002a +sff_cpld_reg.len_11_6=1 +sff_cpld_reg.bit_offset_11_6= + +sff_cpld_reg.mode_12_6=config +sff_cpld_reg.src_12_6=cpld +sff_cpld_reg.frmt_12_6=byte +sff_cpld_reg.pola_12_6= +sff_cpld_reg.addr_12_6=0x0002002b +sff_cpld_reg.len_12_6=1 +sff_cpld_reg.bit_offset_12_6= + +sff_cpld_reg.mode_13_6=config +sff_cpld_reg.src_13_6=cpld +sff_cpld_reg.frmt_13_6=byte +sff_cpld_reg.pola_13_6= +sff_cpld_reg.addr_13_6=0x0002002c +sff_cpld_reg.len_13_6=1 +sff_cpld_reg.bit_offset_13_6= + +sff_cpld_reg.mode_14_6=config +sff_cpld_reg.src_14_6=cpld +sff_cpld_reg.frmt_14_6=byte +sff_cpld_reg.pola_14_6= +sff_cpld_reg.addr_14_6=0x0002002d +sff_cpld_reg.len_14_6=1 +sff_cpld_reg.bit_offset_14_6= + +sff_cpld_reg.mode_15_6=config +sff_cpld_reg.src_15_6=cpld +sff_cpld_reg.frmt_15_6=byte +sff_cpld_reg.pola_15_6= +sff_cpld_reg.addr_15_6=0x0002002e +sff_cpld_reg.len_15_6=1 +sff_cpld_reg.bit_offset_15_6= + +sff_cpld_reg.mode_16_6=config +sff_cpld_reg.src_16_6=cpld +sff_cpld_reg.frmt_16_6=byte +sff_cpld_reg.pola_16_6= +sff_cpld_reg.addr_16_6=0x0002002f +sff_cpld_reg.len_16_6=1 +sff_cpld_reg.bit_offset_16_6= + +sff_cpld_reg.mode_17_6=config +sff_cpld_reg.src_17_6=cpld +sff_cpld_reg.frmt_17_6=byte +sff_cpld_reg.pola_17_6= +sff_cpld_reg.addr_17_6=0x00020030 +sff_cpld_reg.len_17_6=1 +sff_cpld_reg.bit_offset_17_6= + +sff_cpld_reg.mode_18_6=config +sff_cpld_reg.src_18_6=cpld +sff_cpld_reg.frmt_18_6=byte +sff_cpld_reg.pola_18_6= +sff_cpld_reg.addr_18_6=0x00020031 +sff_cpld_reg.len_18_6=1 +sff_cpld_reg.bit_offset_18_6= + +sff_cpld_reg.mode_19_6=config +sff_cpld_reg.src_19_6=cpld +sff_cpld_reg.frmt_19_6=byte +sff_cpld_reg.pola_19_6= +sff_cpld_reg.addr_19_6=0x00020032 +sff_cpld_reg.len_19_6=1 +sff_cpld_reg.bit_offset_19_6= + +sff_cpld_reg.mode_20_6=config +sff_cpld_reg.src_20_6=cpld +sff_cpld_reg.frmt_20_6=byte +sff_cpld_reg.pola_20_6= +sff_cpld_reg.addr_20_6=0x00020033 +sff_cpld_reg.len_20_6=1 +sff_cpld_reg.bit_offset_20_6= + +sff_cpld_reg.mode_21_6=config +sff_cpld_reg.src_21_6=cpld +sff_cpld_reg.frmt_21_6=byte +sff_cpld_reg.pola_21_6= +sff_cpld_reg.addr_21_6=0x00020034 +sff_cpld_reg.len_21_6=1 +sff_cpld_reg.bit_offset_21_6= + +sff_cpld_reg.mode_22_6=config +sff_cpld_reg.src_22_6=cpld +sff_cpld_reg.frmt_22_6=byte +sff_cpld_reg.pola_22_6= +sff_cpld_reg.addr_22_6=0x00020035 +sff_cpld_reg.len_22_6=1 +sff_cpld_reg.bit_offset_22_6= + +sff_cpld_reg.mode_23_6=config +sff_cpld_reg.src_23_6=cpld +sff_cpld_reg.frmt_23_6=byte +sff_cpld_reg.pola_23_6= +sff_cpld_reg.addr_23_6=0x00020036 +sff_cpld_reg.len_23_6=1 +sff_cpld_reg.bit_offset_23_6= + +sff_cpld_reg.mode_24_6=config +sff_cpld_reg.src_24_6=cpld +sff_cpld_reg.frmt_24_6=byte +sff_cpld_reg.pola_24_6= +sff_cpld_reg.addr_24_6=0x00020037 +sff_cpld_reg.len_24_6=1 +sff_cpld_reg.bit_offset_24_6= + +sff_cpld_reg.mode_25_6=config +sff_cpld_reg.src_25_6=cpld +sff_cpld_reg.frmt_25_6=byte +sff_cpld_reg.pola_25_6= +sff_cpld_reg.addr_25_6=0x00020038 +sff_cpld_reg.len_25_6=1 +sff_cpld_reg.bit_offset_25_6= + +sff_cpld_reg.mode_26_6=config +sff_cpld_reg.src_26_6=cpld +sff_cpld_reg.frmt_26_6=byte +sff_cpld_reg.pola_26_6= +sff_cpld_reg.addr_26_6=0x00020039 +sff_cpld_reg.len_26_6=1 +sff_cpld_reg.bit_offset_26_6= + +sff_cpld_reg.mode_27_6=config +sff_cpld_reg.src_27_6=cpld +sff_cpld_reg.frmt_27_6=byte +sff_cpld_reg.pola_27_6= +sff_cpld_reg.addr_27_6=0x0002003a +sff_cpld_reg.len_27_6=1 +sff_cpld_reg.bit_offset_27_6= + +sff_cpld_reg.mode_28_6=config +sff_cpld_reg.src_28_6=cpld +sff_cpld_reg.frmt_28_6=byte +sff_cpld_reg.pola_28_6= +sff_cpld_reg.addr_28_6=0x0002003b +sff_cpld_reg.len_28_6=1 +sff_cpld_reg.bit_offset_28_6= + +sff_cpld_reg.mode_29_6=config +sff_cpld_reg.src_29_6=cpld +sff_cpld_reg.frmt_29_6=byte +sff_cpld_reg.pola_29_6= +sff_cpld_reg.addr_29_6=0x0002003c +sff_cpld_reg.len_29_6=1 +sff_cpld_reg.bit_offset_29_6= + +sff_cpld_reg.mode_30_6=config +sff_cpld_reg.src_30_6=cpld +sff_cpld_reg.frmt_30_6=byte +sff_cpld_reg.pola_30_6= +sff_cpld_reg.addr_30_6=0x0002003d +sff_cpld_reg.len_30_6=1 +sff_cpld_reg.bit_offset_30_6= + +sff_cpld_reg.mode_31_6=config +sff_cpld_reg.src_31_6=cpld +sff_cpld_reg.frmt_31_6=byte +sff_cpld_reg.pola_31_6= +sff_cpld_reg.addr_31_6=0x0002003e +sff_cpld_reg.len_31_6=1 +sff_cpld_reg.bit_offset_31_6= + +sff_cpld_reg.mode_32_6=config +sff_cpld_reg.src_32_6=cpld +sff_cpld_reg.frmt_32_6=byte +sff_cpld_reg.pola_32_6= +sff_cpld_reg.addr_32_6=0x0002003f +sff_cpld_reg.len_32_6=1 +sff_cpld_reg.bit_offset_32_6= + +sff_cpld_reg.mode_33_6=config +sff_cpld_reg.src_33_6=cpld +sff_cpld_reg.frmt_33_6=byte +sff_cpld_reg.pola_33_6= +sff_cpld_reg.addr_33_6=0x00040020 +sff_cpld_reg.len_33_6=1 +sff_cpld_reg.bit_offset_33_6= + +sff_cpld_reg.mode_34_6=config +sff_cpld_reg.src_34_6=cpld +sff_cpld_reg.frmt_34_6=byte +sff_cpld_reg.pola_34_6= +sff_cpld_reg.addr_34_6=0x00040021 +sff_cpld_reg.len_34_6=1 +sff_cpld_reg.bit_offset_34_6= + +sff_cpld_reg.mode_35_6=config +sff_cpld_reg.src_35_6=cpld +sff_cpld_reg.frmt_35_6=byte +sff_cpld_reg.pola_35_6= +sff_cpld_reg.addr_35_6=0x00040022 +sff_cpld_reg.len_35_6=1 +sff_cpld_reg.bit_offset_35_6= + +sff_cpld_reg.mode_36_6=config +sff_cpld_reg.src_36_6=cpld +sff_cpld_reg.frmt_36_6=byte +sff_cpld_reg.pola_36_6= +sff_cpld_reg.addr_36_6=0x00040023 +sff_cpld_reg.len_36_6=1 +sff_cpld_reg.bit_offset_36_6= + +sff_cpld_reg.mode_37_6=config +sff_cpld_reg.src_37_6=cpld +sff_cpld_reg.frmt_37_6=byte +sff_cpld_reg.pola_37_6= +sff_cpld_reg.addr_37_6=0x00040024 +sff_cpld_reg.len_37_6=1 +sff_cpld_reg.bit_offset_37_6= + +sff_cpld_reg.mode_38_6=config +sff_cpld_reg.src_38_6=cpld +sff_cpld_reg.frmt_38_6=byte +sff_cpld_reg.pola_38_6= +sff_cpld_reg.addr_38_6=0x00040025 +sff_cpld_reg.len_38_6=1 +sff_cpld_reg.bit_offset_38_6= + +sff_cpld_reg.mode_39_6=config +sff_cpld_reg.src_39_6=cpld +sff_cpld_reg.frmt_39_6=byte +sff_cpld_reg.pola_39_6= +sff_cpld_reg.addr_39_6=0x00040026 +sff_cpld_reg.len_39_6=1 +sff_cpld_reg.bit_offset_39_6= + +sff_cpld_reg.mode_40_6=config +sff_cpld_reg.src_40_6=cpld +sff_cpld_reg.frmt_40_6=byte +sff_cpld_reg.pola_40_6= +sff_cpld_reg.addr_40_6=0x00040027 +sff_cpld_reg.len_40_6=1 +sff_cpld_reg.bit_offset_40_6= + +sff_cpld_reg.mode_41_6=config +sff_cpld_reg.src_41_6=cpld +sff_cpld_reg.frmt_41_6=byte +sff_cpld_reg.pola_41_6= +sff_cpld_reg.addr_41_6=0x00040028 +sff_cpld_reg.len_41_6=1 +sff_cpld_reg.bit_offset_41_6= + +sff_cpld_reg.mode_42_6=config +sff_cpld_reg.src_42_6=cpld +sff_cpld_reg.frmt_42_6=byte +sff_cpld_reg.pola_42_6= +sff_cpld_reg.addr_42_6=0x00040029 +sff_cpld_reg.len_42_6=1 +sff_cpld_reg.bit_offset_42_6= + +sff_cpld_reg.mode_43_6=config +sff_cpld_reg.src_43_6=cpld +sff_cpld_reg.frmt_43_6=byte +sff_cpld_reg.pola_43_6= +sff_cpld_reg.addr_43_6=0x0004002a +sff_cpld_reg.len_43_6=1 +sff_cpld_reg.bit_offset_43_6= + +sff_cpld_reg.mode_44_6=config +sff_cpld_reg.src_44_6=cpld +sff_cpld_reg.frmt_44_6=byte +sff_cpld_reg.pola_44_6= +sff_cpld_reg.addr_44_6=0x0004002b +sff_cpld_reg.len_44_6=1 +sff_cpld_reg.bit_offset_44_6= + +sff_cpld_reg.mode_45_6=config +sff_cpld_reg.src_45_6=cpld +sff_cpld_reg.frmt_45_6=byte +sff_cpld_reg.pola_45_6= +sff_cpld_reg.addr_45_6=0x0004002c +sff_cpld_reg.len_45_6=1 +sff_cpld_reg.bit_offset_45_6= + +sff_cpld_reg.mode_46_6=config +sff_cpld_reg.src_46_6=cpld +sff_cpld_reg.frmt_46_6=byte +sff_cpld_reg.pola_46_6= +sff_cpld_reg.addr_46_6=0x0004002d +sff_cpld_reg.len_46_6=1 +sff_cpld_reg.bit_offset_46_6= + +sff_cpld_reg.mode_47_6=config +sff_cpld_reg.src_47_6=cpld +sff_cpld_reg.frmt_47_6=byte +sff_cpld_reg.pola_47_6= +sff_cpld_reg.addr_47_6=0x0004002e +sff_cpld_reg.len_47_6=1 +sff_cpld_reg.bit_offset_47_6= + +sff_cpld_reg.mode_48_6=config +sff_cpld_reg.src_48_6=cpld +sff_cpld_reg.frmt_48_6=byte +sff_cpld_reg.pola_48_6= +sff_cpld_reg.addr_48_6=0x0004002f +sff_cpld_reg.len_48_6=1 +sff_cpld_reg.bit_offset_48_6= + +sff_cpld_reg.mode_49_6=config +sff_cpld_reg.src_49_6=cpld +sff_cpld_reg.frmt_49_6=byte +sff_cpld_reg.pola_49_6= +sff_cpld_reg.addr_49_6=0x00040030 +sff_cpld_reg.len_49_6=1 +sff_cpld_reg.bit_offset_49_6= + +sff_cpld_reg.mode_50_6=config +sff_cpld_reg.src_50_6=cpld +sff_cpld_reg.frmt_50_6=byte +sff_cpld_reg.pola_50_6= +sff_cpld_reg.addr_50_6=0x00040031 +sff_cpld_reg.len_50_6=1 +sff_cpld_reg.bit_offset_50_6= + +sff_cpld_reg.mode_51_6=config +sff_cpld_reg.src_51_6=cpld +sff_cpld_reg.frmt_51_6=byte +sff_cpld_reg.pola_51_6= +sff_cpld_reg.addr_51_6=0x00040032 +sff_cpld_reg.len_51_6=1 +sff_cpld_reg.bit_offset_51_6= + +sff_cpld_reg.mode_52_6=config +sff_cpld_reg.src_52_6=cpld +sff_cpld_reg.frmt_52_6=byte +sff_cpld_reg.pola_52_6= +sff_cpld_reg.addr_52_6=0x00040033 +sff_cpld_reg.len_52_6=1 +sff_cpld_reg.bit_offset_52_6= + +sff_cpld_reg.mode_53_6=config +sff_cpld_reg.src_53_6=cpld +sff_cpld_reg.frmt_53_6=byte +sff_cpld_reg.pola_53_6= +sff_cpld_reg.addr_53_6=0x00040034 +sff_cpld_reg.len_53_6=1 +sff_cpld_reg.bit_offset_53_6= + +sff_cpld_reg.mode_54_6=config +sff_cpld_reg.src_54_6=cpld +sff_cpld_reg.frmt_54_6=byte +sff_cpld_reg.pola_54_6= +sff_cpld_reg.addr_54_6=0x00040035 +sff_cpld_reg.len_54_6=1 +sff_cpld_reg.bit_offset_54_6= + +sff_cpld_reg.mode_55_6=config +sff_cpld_reg.src_55_6=cpld +sff_cpld_reg.frmt_55_6=byte +sff_cpld_reg.pola_55_6= +sff_cpld_reg.addr_55_6=0x00040036 +sff_cpld_reg.len_55_6=1 +sff_cpld_reg.bit_offset_55_6= + +sff_cpld_reg.mode_56_6=config +sff_cpld_reg.src_56_6=cpld +sff_cpld_reg.frmt_56_6=byte +sff_cpld_reg.pola_56_6= +sff_cpld_reg.addr_56_6=0x00040037 +sff_cpld_reg.len_56_6=1 +sff_cpld_reg.bit_offset_56_6= + +sff_cpld_reg.mode_57_6=config +sff_cpld_reg.src_57_6=cpld +sff_cpld_reg.frmt_57_6=byte +sff_cpld_reg.pola_57_6= +sff_cpld_reg.addr_57_6=0x00040038 +sff_cpld_reg.len_57_6=1 +sff_cpld_reg.bit_offset_57_6= + +sff_cpld_reg.mode_58_6=config +sff_cpld_reg.src_58_6=cpld +sff_cpld_reg.frmt_58_6=byte +sff_cpld_reg.pola_58_6= +sff_cpld_reg.addr_58_6=0x00040039 +sff_cpld_reg.len_58_6=1 +sff_cpld_reg.bit_offset_58_6= + +sff_cpld_reg.mode_59_6=config +sff_cpld_reg.src_59_6=cpld +sff_cpld_reg.frmt_59_6=byte +sff_cpld_reg.pola_59_6= +sff_cpld_reg.addr_59_6=0x0004003a +sff_cpld_reg.len_59_6=1 +sff_cpld_reg.bit_offset_59_6= + +sff_cpld_reg.mode_60_6=config +sff_cpld_reg.src_60_6=cpld +sff_cpld_reg.frmt_60_6=byte +sff_cpld_reg.pola_60_6= +sff_cpld_reg.addr_60_6=0x0004003b +sff_cpld_reg.len_60_6=1 +sff_cpld_reg.bit_offset_60_6= + +sff_cpld_reg.mode_61_6=config +sff_cpld_reg.src_61_6=cpld +sff_cpld_reg.frmt_61_6=byte +sff_cpld_reg.pola_61_6= +sff_cpld_reg.addr_61_6=0x0004003c +sff_cpld_reg.len_61_6=1 +sff_cpld_reg.bit_offset_61_6= + +sff_cpld_reg.mode_62_6=config +sff_cpld_reg.src_62_6=cpld +sff_cpld_reg.frmt_62_6=byte +sff_cpld_reg.pola_62_6= +sff_cpld_reg.addr_62_6=0x0004003d +sff_cpld_reg.len_62_6=1 +sff_cpld_reg.bit_offset_62_6= + +sff_cpld_reg.mode_63_6=config +sff_cpld_reg.src_63_6=cpld +sff_cpld_reg.frmt_63_6=byte +sff_cpld_reg.pola_63_6= +sff_cpld_reg.addr_63_6=0x0004003e +sff_cpld_reg.len_63_6=1 +sff_cpld_reg.bit_offset_63_6= + +sff_cpld_reg.mode_64_6=config +sff_cpld_reg.src_64_6=cpld +sff_cpld_reg.frmt_64_6=byte +sff_cpld_reg.pola_64_6= +sff_cpld_reg.addr_64_6=0x0004003f +sff_cpld_reg.len_64_6=1 +sff_cpld_reg.bit_offset_64_6= + +# 1600G module lpmode signal +sff_cpld_reg.mode_1_7=config +sff_cpld_reg.src_1_7=cpld +sff_cpld_reg.frmt_1_7=byte +sff_cpld_reg.pola_1_7= +sff_cpld_reg.addr_1_7=0x00020040 +sff_cpld_reg.len_1_7=1 +sff_cpld_reg.bit_offset_1_7= + +sff_cpld_reg.mode_2_7=config +sff_cpld_reg.src_2_7=cpld +sff_cpld_reg.frmt_2_7=byte +sff_cpld_reg.pola_2_7= +sff_cpld_reg.addr_2_7=0x00020041 +sff_cpld_reg.len_2_7=1 +sff_cpld_reg.bit_offset_2_7= + +sff_cpld_reg.mode_3_7=config +sff_cpld_reg.src_3_7=cpld +sff_cpld_reg.frmt_3_7=byte +sff_cpld_reg.pola_3_7= +sff_cpld_reg.addr_3_7=0x00020042 +sff_cpld_reg.len_3_7=1 +sff_cpld_reg.bit_offset_3_7= + +sff_cpld_reg.mode_4_7=config +sff_cpld_reg.src_4_7=cpld +sff_cpld_reg.frmt_4_7=byte +sff_cpld_reg.pola_4_7= +sff_cpld_reg.addr_4_7=0x00020043 +sff_cpld_reg.len_4_7=1 +sff_cpld_reg.bit_offset_4_7= + +sff_cpld_reg.mode_5_7=config +sff_cpld_reg.src_5_7=cpld +sff_cpld_reg.frmt_5_7=byte +sff_cpld_reg.pola_5_7= +sff_cpld_reg.addr_5_7=0x00020044 +sff_cpld_reg.len_5_7=1 +sff_cpld_reg.bit_offset_5_7= + +sff_cpld_reg.mode_6_7=config +sff_cpld_reg.src_6_7=cpld +sff_cpld_reg.frmt_6_7=byte +sff_cpld_reg.pola_6_7= +sff_cpld_reg.addr_6_7=0x00020045 +sff_cpld_reg.len_6_7=1 +sff_cpld_reg.bit_offset_6_7= + +sff_cpld_reg.mode_7_7=config +sff_cpld_reg.src_7_7=cpld +sff_cpld_reg.frmt_7_7=byte +sff_cpld_reg.pola_7_7= +sff_cpld_reg.addr_7_7=0x00020046 +sff_cpld_reg.len_7_7=1 +sff_cpld_reg.bit_offset_7_7= + +sff_cpld_reg.mode_8_7=config +sff_cpld_reg.src_8_7=cpld +sff_cpld_reg.frmt_8_7=byte +sff_cpld_reg.pola_8_7= +sff_cpld_reg.addr_8_7=0x00020057 +sff_cpld_reg.len_8_7=1 +sff_cpld_reg.bit_offset_8_7= + +sff_cpld_reg.mode_9_7=config +sff_cpld_reg.src_9_7=cpld +sff_cpld_reg.frmt_9_7=byte +sff_cpld_reg.pola_9_7= +sff_cpld_reg.addr_9_7=0x00020048 +sff_cpld_reg.len_9_7=1 +sff_cpld_reg.bit_offset_9_7= + +sff_cpld_reg.mode_10_7=config +sff_cpld_reg.src_10_7=cpld +sff_cpld_reg.frmt_10_7=byte +sff_cpld_reg.pola_10_7= +sff_cpld_reg.addr_10_7=0x00020049 +sff_cpld_reg.len_10_7=1 +sff_cpld_reg.bit_offset_10_7= + +sff_cpld_reg.mode_11_7=config +sff_cpld_reg.src_11_7=cpld +sff_cpld_reg.frmt_11_7=byte +sff_cpld_reg.pola_11_7= +sff_cpld_reg.addr_11_7=0x0002004a +sff_cpld_reg.len_11_7=1 +sff_cpld_reg.bit_offset_11_7= + +sff_cpld_reg.mode_12_7=config +sff_cpld_reg.src_12_7=cpld +sff_cpld_reg.frmt_12_7=byte +sff_cpld_reg.pola_12_7= +sff_cpld_reg.addr_12_7=0x0002004b +sff_cpld_reg.len_12_7=1 +sff_cpld_reg.bit_offset_12_7= + +sff_cpld_reg.mode_13_7=config +sff_cpld_reg.src_13_7=cpld +sff_cpld_reg.frmt_13_7=byte +sff_cpld_reg.pola_13_7= +sff_cpld_reg.addr_13_7=0x0002004c +sff_cpld_reg.len_13_7=1 +sff_cpld_reg.bit_offset_13_7= + +sff_cpld_reg.mode_14_7=config +sff_cpld_reg.src_14_7=cpld +sff_cpld_reg.frmt_14_7=byte +sff_cpld_reg.pola_14_7= +sff_cpld_reg.addr_14_7=0x0002004d +sff_cpld_reg.len_14_7=1 +sff_cpld_reg.bit_offset_14_7= + +sff_cpld_reg.mode_15_7=config +sff_cpld_reg.src_15_7=cpld +sff_cpld_reg.frmt_15_7=byte +sff_cpld_reg.pola_15_7= +sff_cpld_reg.addr_15_7=0x0002004e +sff_cpld_reg.len_15_7=1 +sff_cpld_reg.bit_offset_15_7= + +sff_cpld_reg.mode_16_7=config +sff_cpld_reg.src_16_7=cpld +sff_cpld_reg.frmt_16_7=byte +sff_cpld_reg.pola_16_7= +sff_cpld_reg.addr_16_7=0x0002004f +sff_cpld_reg.len_16_7=1 +sff_cpld_reg.bit_offset_16_7= + +sff_cpld_reg.mode_17_7=config +sff_cpld_reg.src_17_7=cpld +sff_cpld_reg.frmt_17_7=byte +sff_cpld_reg.pola_17_7= +sff_cpld_reg.addr_17_7=0x00020050 +sff_cpld_reg.len_17_7=1 +sff_cpld_reg.bit_offset_17_7= + +sff_cpld_reg.mode_18_7=config +sff_cpld_reg.src_18_7=cpld +sff_cpld_reg.frmt_18_7=byte +sff_cpld_reg.pola_18_7= +sff_cpld_reg.addr_18_7=0x00020051 +sff_cpld_reg.len_18_7=1 +sff_cpld_reg.bit_offset_18_7= + +sff_cpld_reg.mode_19_7=config +sff_cpld_reg.src_19_7=cpld +sff_cpld_reg.frmt_19_7=byte +sff_cpld_reg.pola_19_7= +sff_cpld_reg.addr_19_7=0x00020052 +sff_cpld_reg.len_19_7=1 +sff_cpld_reg.bit_offset_19_7= + +sff_cpld_reg.mode_20_7=config +sff_cpld_reg.src_20_7=cpld +sff_cpld_reg.frmt_20_7=byte +sff_cpld_reg.pola_20_7= +sff_cpld_reg.addr_20_7=0x00020053 +sff_cpld_reg.len_20_7=1 +sff_cpld_reg.bit_offset_20_7= + +sff_cpld_reg.mode_21_7=config +sff_cpld_reg.src_21_7=cpld +sff_cpld_reg.frmt_21_7=byte +sff_cpld_reg.pola_21_7= +sff_cpld_reg.addr_21_7=0x00020054 +sff_cpld_reg.len_21_7=1 +sff_cpld_reg.bit_offset_21_7= + +sff_cpld_reg.mode_22_7=config +sff_cpld_reg.src_22_7=cpld +sff_cpld_reg.frmt_22_7=byte +sff_cpld_reg.pola_22_7= +sff_cpld_reg.addr_22_7=0x00020055 +sff_cpld_reg.len_22_7=1 +sff_cpld_reg.bit_offset_22_7= + +sff_cpld_reg.mode_23_7=config +sff_cpld_reg.src_23_7=cpld +sff_cpld_reg.frmt_23_7=byte +sff_cpld_reg.pola_23_7= +sff_cpld_reg.addr_23_7=0x00020056 +sff_cpld_reg.len_23_7=1 +sff_cpld_reg.bit_offset_23_7= + +sff_cpld_reg.mode_24_7=config +sff_cpld_reg.src_24_7=cpld +sff_cpld_reg.frmt_24_7=byte +sff_cpld_reg.pola_24_7= +sff_cpld_reg.addr_24_7=0x00020057 +sff_cpld_reg.len_24_7=1 +sff_cpld_reg.bit_offset_24_7= + +sff_cpld_reg.mode_25_7=config +sff_cpld_reg.src_25_7=cpld +sff_cpld_reg.frmt_25_7=byte +sff_cpld_reg.pola_25_7= +sff_cpld_reg.addr_25_7=0x00020058 +sff_cpld_reg.len_25_7=1 +sff_cpld_reg.bit_offset_25_7= + +sff_cpld_reg.mode_26_7=config +sff_cpld_reg.src_26_7=cpld +sff_cpld_reg.frmt_26_7=byte +sff_cpld_reg.pola_26_7= +sff_cpld_reg.addr_26_7=0x00020059 +sff_cpld_reg.len_26_7=1 +sff_cpld_reg.bit_offset_26_7= + +sff_cpld_reg.mode_27_7=config +sff_cpld_reg.src_27_7=cpld +sff_cpld_reg.frmt_27_7=byte +sff_cpld_reg.pola_27_7= +sff_cpld_reg.addr_27_7=0x0002005a +sff_cpld_reg.len_27_7=1 +sff_cpld_reg.bit_offset_27_7= + +sff_cpld_reg.mode_28_7=config +sff_cpld_reg.src_28_7=cpld +sff_cpld_reg.frmt_28_7=byte +sff_cpld_reg.pola_28_7= +sff_cpld_reg.addr_28_7=0x0002005b +sff_cpld_reg.len_28_7=1 +sff_cpld_reg.bit_offset_28_7= + +sff_cpld_reg.mode_29_7=config +sff_cpld_reg.src_29_7=cpld +sff_cpld_reg.frmt_29_7=byte +sff_cpld_reg.pola_29_7= +sff_cpld_reg.addr_29_7=0x0002005c +sff_cpld_reg.len_29_7=1 +sff_cpld_reg.bit_offset_29_7= + +sff_cpld_reg.mode_30_7=config +sff_cpld_reg.src_30_7=cpld +sff_cpld_reg.frmt_30_7=byte +sff_cpld_reg.pola_30_7= +sff_cpld_reg.addr_30_7=0x0002005d +sff_cpld_reg.len_30_7=1 +sff_cpld_reg.bit_offset_30_7= + +sff_cpld_reg.mode_31_7=config +sff_cpld_reg.src_31_7=cpld +sff_cpld_reg.frmt_31_7=byte +sff_cpld_reg.pola_31_7= +sff_cpld_reg.addr_31_7=0x0002005e +sff_cpld_reg.len_31_7=1 +sff_cpld_reg.bit_offset_31_7= + +sff_cpld_reg.mode_32_7=config +sff_cpld_reg.src_32_7=cpld +sff_cpld_reg.frmt_32_7=byte +sff_cpld_reg.pola_32_7= +sff_cpld_reg.addr_32_7=0x0002005f +sff_cpld_reg.len_32_7=1 +sff_cpld_reg.bit_offset_32_7= + +sff_cpld_reg.mode_33_7=config +sff_cpld_reg.src_33_7=cpld +sff_cpld_reg.frmt_33_7=byte +sff_cpld_reg.pola_33_7= +sff_cpld_reg.addr_33_7=0x00040040 +sff_cpld_reg.len_33_7=1 +sff_cpld_reg.bit_offset_33_7= + +sff_cpld_reg.mode_34_7=config +sff_cpld_reg.src_34_7=cpld +sff_cpld_reg.frmt_34_7=byte +sff_cpld_reg.pola_34_7= +sff_cpld_reg.addr_34_7=0x00040041 +sff_cpld_reg.len_34_7=1 +sff_cpld_reg.bit_offset_34_7= + +sff_cpld_reg.mode_35_7=config +sff_cpld_reg.src_35_7=cpld +sff_cpld_reg.frmt_35_7=byte +sff_cpld_reg.pola_35_7= +sff_cpld_reg.addr_35_7=0x00040042 +sff_cpld_reg.len_35_7=1 +sff_cpld_reg.bit_offset_35_7= + +sff_cpld_reg.mode_36_7=config +sff_cpld_reg.src_36_7=cpld +sff_cpld_reg.frmt_36_7=byte +sff_cpld_reg.pola_36_7= +sff_cpld_reg.addr_36_7=0x00040043 +sff_cpld_reg.len_36_7=1 +sff_cpld_reg.bit_offset_36_7= + +sff_cpld_reg.mode_37_7=config +sff_cpld_reg.src_37_7=cpld +sff_cpld_reg.frmt_37_7=byte +sff_cpld_reg.pola_37_7= +sff_cpld_reg.addr_37_7=0x00040044 +sff_cpld_reg.len_37_7=1 +sff_cpld_reg.bit_offset_37_7= + +sff_cpld_reg.mode_38_7=config +sff_cpld_reg.src_38_7=cpld +sff_cpld_reg.frmt_38_7=byte +sff_cpld_reg.pola_38_7= +sff_cpld_reg.addr_38_7=0x00040045 +sff_cpld_reg.len_38_7=1 +sff_cpld_reg.bit_offset_38_7= + +sff_cpld_reg.mode_39_7=config +sff_cpld_reg.src_39_7=cpld +sff_cpld_reg.frmt_39_7=byte +sff_cpld_reg.pola_39_7= +sff_cpld_reg.addr_39_7=0x00040046 +sff_cpld_reg.len_39_7=1 +sff_cpld_reg.bit_offset_39_7= + +sff_cpld_reg.mode_40_7=config +sff_cpld_reg.src_40_7=cpld +sff_cpld_reg.frmt_40_7=byte +sff_cpld_reg.pola_40_7= +sff_cpld_reg.addr_40_7=0x00040047 +sff_cpld_reg.len_40_7=1 +sff_cpld_reg.bit_offset_40_7= + +sff_cpld_reg.mode_41_7=config +sff_cpld_reg.src_41_7=cpld +sff_cpld_reg.frmt_41_7=byte +sff_cpld_reg.pola_41_7= +sff_cpld_reg.addr_41_7=0x00040048 +sff_cpld_reg.len_41_7=1 +sff_cpld_reg.bit_offset_41_7= + +sff_cpld_reg.mode_42_7=config +sff_cpld_reg.src_42_7=cpld +sff_cpld_reg.frmt_42_7=byte +sff_cpld_reg.pola_42_7= +sff_cpld_reg.addr_42_7=0x00040049 +sff_cpld_reg.len_42_7=1 +sff_cpld_reg.bit_offset_42_7= + +sff_cpld_reg.mode_43_7=config +sff_cpld_reg.src_43_7=cpld +sff_cpld_reg.frmt_43_7=byte +sff_cpld_reg.pola_43_7= +sff_cpld_reg.addr_43_7=0x0004004a +sff_cpld_reg.len_43_7=1 +sff_cpld_reg.bit_offset_43_7= + +sff_cpld_reg.mode_44_7=config +sff_cpld_reg.src_44_7=cpld +sff_cpld_reg.frmt_44_7=byte +sff_cpld_reg.pola_44_7= +sff_cpld_reg.addr_44_7=0x0004004b +sff_cpld_reg.len_44_7=1 +sff_cpld_reg.bit_offset_44_7= + +sff_cpld_reg.mode_45_7=config +sff_cpld_reg.src_45_7=cpld +sff_cpld_reg.frmt_45_7=byte +sff_cpld_reg.pola_45_7= +sff_cpld_reg.addr_45_7=0x0004004c +sff_cpld_reg.len_45_7=1 +sff_cpld_reg.bit_offset_45_7= + +sff_cpld_reg.mode_46_7=config +sff_cpld_reg.src_46_7=cpld +sff_cpld_reg.frmt_46_7=byte +sff_cpld_reg.pola_46_7= +sff_cpld_reg.addr_46_7=0x0004004d +sff_cpld_reg.len_46_7=1 +sff_cpld_reg.bit_offset_46_7= + +sff_cpld_reg.mode_47_7=config +sff_cpld_reg.src_47_7=cpld +sff_cpld_reg.frmt_47_7=byte +sff_cpld_reg.pola_47_7= +sff_cpld_reg.addr_47_7=0x0004004e +sff_cpld_reg.len_47_7=1 +sff_cpld_reg.bit_offset_47_7= + +sff_cpld_reg.mode_48_7=config +sff_cpld_reg.src_48_7=cpld +sff_cpld_reg.frmt_48_7=byte +sff_cpld_reg.pola_48_7= +sff_cpld_reg.addr_48_7=0x0004004f +sff_cpld_reg.len_48_7=1 +sff_cpld_reg.bit_offset_48_7= + +sff_cpld_reg.mode_49_7=config +sff_cpld_reg.src_49_7=cpld +sff_cpld_reg.frmt_49_7=byte +sff_cpld_reg.pola_49_7= +sff_cpld_reg.addr_49_7=0x00040050 +sff_cpld_reg.len_49_7=1 +sff_cpld_reg.bit_offset_49_7= + +sff_cpld_reg.mode_50_7=config +sff_cpld_reg.src_50_7=cpld +sff_cpld_reg.frmt_50_7=byte +sff_cpld_reg.pola_50_7= +sff_cpld_reg.addr_50_7=0x00040051 +sff_cpld_reg.len_50_7=1 +sff_cpld_reg.bit_offset_50_7= + +sff_cpld_reg.mode_51_7=config +sff_cpld_reg.src_51_7=cpld +sff_cpld_reg.frmt_51_7=byte +sff_cpld_reg.pola_51_7= +sff_cpld_reg.addr_51_7=0x00040052 +sff_cpld_reg.len_51_7=1 +sff_cpld_reg.bit_offset_51_7= + +sff_cpld_reg.mode_52_7=config +sff_cpld_reg.src_52_7=cpld +sff_cpld_reg.frmt_52_7=byte +sff_cpld_reg.pola_52_7= +sff_cpld_reg.addr_52_7=0x00040053 +sff_cpld_reg.len_52_7=1 +sff_cpld_reg.bit_offset_52_7= + +sff_cpld_reg.mode_53_7=config +sff_cpld_reg.src_53_7=cpld +sff_cpld_reg.frmt_53_7=byte +sff_cpld_reg.pola_53_7= +sff_cpld_reg.addr_53_7=0x00040054 +sff_cpld_reg.len_53_7=1 +sff_cpld_reg.bit_offset_53_7= + +sff_cpld_reg.mode_54_7=config +sff_cpld_reg.src_54_7=cpld +sff_cpld_reg.frmt_54_7=byte +sff_cpld_reg.pola_54_7= +sff_cpld_reg.addr_54_7=0x00040055 +sff_cpld_reg.len_54_7=1 +sff_cpld_reg.bit_offset_54_7= + +sff_cpld_reg.mode_55_7=config +sff_cpld_reg.src_55_7=cpld +sff_cpld_reg.frmt_55_7=byte +sff_cpld_reg.pola_55_7= +sff_cpld_reg.addr_55_7=0x00040056 +sff_cpld_reg.len_55_7=1 +sff_cpld_reg.bit_offset_55_7= + +sff_cpld_reg.mode_56_7=config +sff_cpld_reg.src_56_7=cpld +sff_cpld_reg.frmt_56_7=byte +sff_cpld_reg.pola_56_7= +sff_cpld_reg.addr_56_7=0x00040057 +sff_cpld_reg.len_56_7=1 +sff_cpld_reg.bit_offset_56_7= + +sff_cpld_reg.mode_57_7=config +sff_cpld_reg.src_57_7=cpld +sff_cpld_reg.frmt_57_7=byte +sff_cpld_reg.pola_57_7= +sff_cpld_reg.addr_57_7=0x00040058 +sff_cpld_reg.len_57_7=1 +sff_cpld_reg.bit_offset_57_7= + +sff_cpld_reg.mode_58_7=config +sff_cpld_reg.src_58_7=cpld +sff_cpld_reg.frmt_58_7=byte +sff_cpld_reg.pola_58_7= +sff_cpld_reg.addr_58_7=0x00040059 +sff_cpld_reg.len_58_7=1 +sff_cpld_reg.bit_offset_58_7= + +sff_cpld_reg.mode_59_7=config +sff_cpld_reg.src_59_7=cpld +sff_cpld_reg.frmt_59_7=byte +sff_cpld_reg.pola_59_7= +sff_cpld_reg.addr_59_7=0x0004005a +sff_cpld_reg.len_59_7=1 +sff_cpld_reg.bit_offset_59_7= + +sff_cpld_reg.mode_60_7=config +sff_cpld_reg.src_60_7=cpld +sff_cpld_reg.frmt_60_7=byte +sff_cpld_reg.pola_60_7= +sff_cpld_reg.addr_60_7=0x0004005b +sff_cpld_reg.len_60_7=1 +sff_cpld_reg.bit_offset_60_7= + +sff_cpld_reg.mode_61_7=config +sff_cpld_reg.src_61_7=cpld +sff_cpld_reg.frmt_61_7=byte +sff_cpld_reg.pola_61_7= +sff_cpld_reg.addr_61_7=0x0004005c +sff_cpld_reg.len_61_7=1 +sff_cpld_reg.bit_offset_61_7= + +sff_cpld_reg.mode_62_7=config +sff_cpld_reg.src_62_7=cpld +sff_cpld_reg.frmt_62_7=byte +sff_cpld_reg.pola_62_7= +sff_cpld_reg.addr_62_7=0x0004005d +sff_cpld_reg.len_62_7=1 +sff_cpld_reg.bit_offset_62_7= + +sff_cpld_reg.mode_63_7=config +sff_cpld_reg.src_63_7=cpld +sff_cpld_reg.frmt_63_7=byte +sff_cpld_reg.pola_63_7= +sff_cpld_reg.addr_63_7=0x0004005e +sff_cpld_reg.len_63_7=1 +sff_cpld_reg.bit_offset_63_7= + +sff_cpld_reg.mode_64_7=config +sff_cpld_reg.src_64_7=cpld +sff_cpld_reg.frmt_64_7=byte +sff_cpld_reg.pola_64_7= +sff_cpld_reg.addr_64_7=0x0004005f +sff_cpld_reg.len_64_7=1 +sff_cpld_reg.bit_offset_64_7= + + +# 1600G module module_present signal +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x000400c0 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x000400c0 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x000200c0 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=0 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x000200c0 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=1 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x000400c0 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=2 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x000400c0 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=3 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x000200c0 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=2 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x000200c0 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=3 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x000400c0 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=4 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x000400c0 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=5 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x000200c0 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=4 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x000200c0 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=5 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x000400c0 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=6 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x000400c0 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=7 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x000200c0 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x000200c0 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x000400c1 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x000400c1 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x000200c1 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=0 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x000200c1 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=1 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x000400c1 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=2 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x000400c1 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=3 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x000200c1 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=2 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x000200c1 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=3 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x000400c1 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=4 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x000400c1 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=5 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x000200c1 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=4 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x000200c1 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=5 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x000400c1 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=6 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x000400c1 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=7 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x000200c1 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x000200c1 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +sff_cpld_reg.mode_33_8=config +sff_cpld_reg.src_33_8=cpld +sff_cpld_reg.frmt_33_8=bit +sff_cpld_reg.pola_33_8=negative +sff_cpld_reg.addr_33_8=0x000400c2 +sff_cpld_reg.len_33_8=1 +sff_cpld_reg.bit_offset_33_8=0 + +sff_cpld_reg.mode_34_8=config +sff_cpld_reg.src_34_8=cpld +sff_cpld_reg.frmt_34_8=bit +sff_cpld_reg.pola_34_8=negative +sff_cpld_reg.addr_34_8=0x000400c2 +sff_cpld_reg.len_34_8=1 +sff_cpld_reg.bit_offset_34_8=1 + +sff_cpld_reg.mode_35_8=config +sff_cpld_reg.src_35_8=cpld +sff_cpld_reg.frmt_35_8=bit +sff_cpld_reg.pola_35_8=negative +sff_cpld_reg.addr_35_8=0x000200c2 +sff_cpld_reg.len_35_8=1 +sff_cpld_reg.bit_offset_35_8=0 + +sff_cpld_reg.mode_36_8=config +sff_cpld_reg.src_36_8=cpld +sff_cpld_reg.frmt_36_8=bit +sff_cpld_reg.pola_36_8=negative +sff_cpld_reg.addr_36_8=0x000200c2 +sff_cpld_reg.len_36_8=1 +sff_cpld_reg.bit_offset_36_8=1 + +sff_cpld_reg.mode_37_8=config +sff_cpld_reg.src_37_8=cpld +sff_cpld_reg.frmt_37_8=bit +sff_cpld_reg.pola_37_8=negative +sff_cpld_reg.addr_37_8=0x000400c2 +sff_cpld_reg.len_37_8=1 +sff_cpld_reg.bit_offset_37_8=2 + +sff_cpld_reg.mode_38_8=config +sff_cpld_reg.src_38_8=cpld +sff_cpld_reg.frmt_38_8=bit +sff_cpld_reg.pola_38_8=negative +sff_cpld_reg.addr_38_8=0x000400c2 +sff_cpld_reg.len_38_8=1 +sff_cpld_reg.bit_offset_38_8=3 + +sff_cpld_reg.mode_39_8=config +sff_cpld_reg.src_39_8=cpld +sff_cpld_reg.frmt_39_8=bit +sff_cpld_reg.pola_39_8=negative +sff_cpld_reg.addr_39_8=0x000200c2 +sff_cpld_reg.len_39_8=1 +sff_cpld_reg.bit_offset_39_8=2 + +sff_cpld_reg.mode_40_8=config +sff_cpld_reg.src_40_8=cpld +sff_cpld_reg.frmt_40_8=bit +sff_cpld_reg.pola_40_8=negative +sff_cpld_reg.addr_40_8=0x000200c2 +sff_cpld_reg.len_40_8=1 +sff_cpld_reg.bit_offset_40_8=3 + +sff_cpld_reg.mode_41_8=config +sff_cpld_reg.src_41_8=cpld +sff_cpld_reg.frmt_41_8=bit +sff_cpld_reg.pola_41_8=negative +sff_cpld_reg.addr_41_8=0x000400c2 +sff_cpld_reg.len_41_8=1 +sff_cpld_reg.bit_offset_41_8=4 + +sff_cpld_reg.mode_42_8=config +sff_cpld_reg.src_42_8=cpld +sff_cpld_reg.frmt_42_8=bit +sff_cpld_reg.pola_42_8=negative +sff_cpld_reg.addr_42_8=0x000400c2 +sff_cpld_reg.len_42_8=1 +sff_cpld_reg.bit_offset_42_8=5 + +sff_cpld_reg.mode_43_8=config +sff_cpld_reg.src_43_8=cpld +sff_cpld_reg.frmt_43_8=bit +sff_cpld_reg.pola_43_8=negative +sff_cpld_reg.addr_43_8=0x000200c2 +sff_cpld_reg.len_43_8=1 +sff_cpld_reg.bit_offset_43_8=4 + +sff_cpld_reg.mode_44_8=config +sff_cpld_reg.src_44_8=cpld +sff_cpld_reg.frmt_44_8=bit +sff_cpld_reg.pola_44_8=negative +sff_cpld_reg.addr_44_8=0x000200c2 +sff_cpld_reg.len_44_8=1 +sff_cpld_reg.bit_offset_44_8=5 + +sff_cpld_reg.mode_45_8=config +sff_cpld_reg.src_45_8=cpld +sff_cpld_reg.frmt_45_8=bit +sff_cpld_reg.pola_45_8=negative +sff_cpld_reg.addr_45_8=0x000400c2 +sff_cpld_reg.len_45_8=1 +sff_cpld_reg.bit_offset_45_8=6 + +sff_cpld_reg.mode_46_8=config +sff_cpld_reg.src_46_8=cpld +sff_cpld_reg.frmt_46_8=bit +sff_cpld_reg.pola_46_8=negative +sff_cpld_reg.addr_46_8=0x000400c2 +sff_cpld_reg.len_46_8=1 +sff_cpld_reg.bit_offset_46_8=7 + +sff_cpld_reg.mode_47_8=config +sff_cpld_reg.src_47_8=cpld +sff_cpld_reg.frmt_47_8=bit +sff_cpld_reg.pola_47_8=negative +sff_cpld_reg.addr_47_8=0x000200c2 +sff_cpld_reg.len_47_8=1 +sff_cpld_reg.bit_offset_47_8=6 + +sff_cpld_reg.mode_48_8=config +sff_cpld_reg.src_48_8=cpld +sff_cpld_reg.frmt_48_8=bit +sff_cpld_reg.pola_48_8=negative +sff_cpld_reg.addr_48_8=0x000200c2 +sff_cpld_reg.len_48_8=1 +sff_cpld_reg.bit_offset_48_8=7 + +sff_cpld_reg.mode_49_8=config +sff_cpld_reg.src_49_8=cpld +sff_cpld_reg.frmt_49_8=bit +sff_cpld_reg.pola_49_8=negative +sff_cpld_reg.addr_49_8=0x000400c3 +sff_cpld_reg.len_49_8=1 +sff_cpld_reg.bit_offset_49_8=0 + +sff_cpld_reg.mode_50_8=config +sff_cpld_reg.src_50_8=cpld +sff_cpld_reg.frmt_50_8=bit +sff_cpld_reg.pola_50_8=negative +sff_cpld_reg.addr_50_8=0x000400c3 +sff_cpld_reg.len_50_8=1 +sff_cpld_reg.bit_offset_50_8=1 + +sff_cpld_reg.mode_51_8=config +sff_cpld_reg.src_51_8=cpld +sff_cpld_reg.frmt_51_8=bit +sff_cpld_reg.pola_51_8=negative +sff_cpld_reg.addr_51_8=0x000200c3 +sff_cpld_reg.len_51_8=1 +sff_cpld_reg.bit_offset_51_8=0 + +sff_cpld_reg.mode_52_8=config +sff_cpld_reg.src_52_8=cpld +sff_cpld_reg.frmt_52_8=bit +sff_cpld_reg.pola_52_8=negative +sff_cpld_reg.addr_52_8=0x000200c3 +sff_cpld_reg.len_52_8=1 +sff_cpld_reg.bit_offset_52_8=1 + +sff_cpld_reg.mode_53_8=config +sff_cpld_reg.src_53_8=cpld +sff_cpld_reg.frmt_53_8=bit +sff_cpld_reg.pola_53_8=negative +sff_cpld_reg.addr_53_8=0x000400c3 +sff_cpld_reg.len_53_8=1 +sff_cpld_reg.bit_offset_53_8=2 + +sff_cpld_reg.mode_54_8=config +sff_cpld_reg.src_54_8=cpld +sff_cpld_reg.frmt_54_8=bit +sff_cpld_reg.pola_54_8=negative +sff_cpld_reg.addr_54_8=0x000400c3 +sff_cpld_reg.len_54_8=1 +sff_cpld_reg.bit_offset_54_8=3 + +sff_cpld_reg.mode_55_8=config +sff_cpld_reg.src_55_8=cpld +sff_cpld_reg.frmt_55_8=bit +sff_cpld_reg.pola_55_8=negative +sff_cpld_reg.addr_55_8=0x000200c3 +sff_cpld_reg.len_55_8=1 +sff_cpld_reg.bit_offset_55_8=2 + +sff_cpld_reg.mode_56_8=config +sff_cpld_reg.src_56_8=cpld +sff_cpld_reg.frmt_56_8=bit +sff_cpld_reg.pola_56_8=negative +sff_cpld_reg.addr_56_8=0x000200c3 +sff_cpld_reg.len_56_8=1 +sff_cpld_reg.bit_offset_56_8=3 + +sff_cpld_reg.mode_57_8=config +sff_cpld_reg.src_57_8=cpld +sff_cpld_reg.frmt_57_8=bit +sff_cpld_reg.pola_57_8=negative +sff_cpld_reg.addr_57_8=0x000400c3 +sff_cpld_reg.len_57_8=1 +sff_cpld_reg.bit_offset_57_8=4 + +sff_cpld_reg.mode_58_8=config +sff_cpld_reg.src_58_8=cpld +sff_cpld_reg.frmt_58_8=bit +sff_cpld_reg.pola_58_8=negative +sff_cpld_reg.addr_58_8=0x000400c3 +sff_cpld_reg.len_58_8=1 +sff_cpld_reg.bit_offset_58_8=5 + +sff_cpld_reg.mode_59_8=config +sff_cpld_reg.src_59_8=cpld +sff_cpld_reg.frmt_59_8=bit +sff_cpld_reg.pola_59_8=negative +sff_cpld_reg.addr_59_8=0x000200c3 +sff_cpld_reg.len_59_8=1 +sff_cpld_reg.bit_offset_59_8=4 + +sff_cpld_reg.mode_60_8=config +sff_cpld_reg.src_60_8=cpld +sff_cpld_reg.frmt_60_8=bit +sff_cpld_reg.pola_60_8=negative +sff_cpld_reg.addr_60_8=0x000200c3 +sff_cpld_reg.len_60_8=1 +sff_cpld_reg.bit_offset_60_8=5 + +sff_cpld_reg.mode_61_8=config +sff_cpld_reg.src_61_8=cpld +sff_cpld_reg.frmt_61_8=bit +sff_cpld_reg.pola_61_8=negative +sff_cpld_reg.addr_61_8=0x000400c3 +sff_cpld_reg.len_61_8=1 +sff_cpld_reg.bit_offset_61_8=6 + +sff_cpld_reg.mode_62_8=config +sff_cpld_reg.src_62_8=cpld +sff_cpld_reg.frmt_62_8=bit +sff_cpld_reg.pola_62_8=negative +sff_cpld_reg.addr_62_8=0x000400c3 +sff_cpld_reg.len_62_8=1 +sff_cpld_reg.bit_offset_62_8=7 + +sff_cpld_reg.mode_63_8=config +sff_cpld_reg.src_63_8=cpld +sff_cpld_reg.frmt_63_8=bit +sff_cpld_reg.pola_63_8=negative +sff_cpld_reg.addr_63_8=0x000200c3 +sff_cpld_reg.len_63_8=1 +sff_cpld_reg.bit_offset_63_8=6 + +sff_cpld_reg.mode_64_8=config +sff_cpld_reg.src_64_8=cpld +sff_cpld_reg.frmt_64_8=bit +sff_cpld_reg.pola_64_8=negative +sff_cpld_reg.addr_64_8=0x000200c3 +sff_cpld_reg.len_64_8=1 +sff_cpld_reg.bit_offset_64_8=7 + +sff_cpld_reg.mode_65_8=config +sff_cpld_reg.src_65_8=cpld +sff_cpld_reg.frmt_65_8=bit +sff_cpld_reg.pola_65_8=negative +sff_cpld_reg.addr_65_8=0x00030075 +sff_cpld_reg.len_65_8=1 +sff_cpld_reg.bit_offset_65_8=0 + +sff_cpld_reg.mode_66_8=config +sff_cpld_reg.src_66_8=cpld +sff_cpld_reg.frmt_66_8=bit +sff_cpld_reg.pola_66_8=negative +sff_cpld_reg.addr_66_8=0x00030075 +sff_cpld_reg.len_66_8=1 +sff_cpld_reg.bit_offset_66_8=1 + + +# 1600G module power_on signal +sff_cpld_reg.mode_1_1=config +sff_cpld_reg.src_1_1=cpld +sff_cpld_reg.frmt_1_1=byte +sff_cpld_reg.addr_1_1=0x00030042 +sff_cpld_reg.len_1_1=1 +sff_cpld_reg.bit_offset_1_1= + +sff_cpld_reg.mode_2_1=config +sff_cpld_reg.src_2_1=cpld +sff_cpld_reg.frmt_2_1=byte +sff_cpld_reg.addr_2_1=0x00030042 +sff_cpld_reg.len_2_1=1 +sff_cpld_reg.bit_offset_2_1= + +sff_cpld_reg.mode_3_1=config +sff_cpld_reg.src_3_1=cpld +sff_cpld_reg.frmt_3_1=byte +sff_cpld_reg.addr_3_1=0x00030042 +sff_cpld_reg.len_3_1=1 +sff_cpld_reg.bit_offset_3_1= + +sff_cpld_reg.mode_4_1=config +sff_cpld_reg.src_4_1=cpld +sff_cpld_reg.frmt_4_1=byte +sff_cpld_reg.addr_4_1=0x00030042 +sff_cpld_reg.len_4_1=1 +sff_cpld_reg.bit_offset_4_1= + +sff_cpld_reg.mode_5_1=config +sff_cpld_reg.src_5_1=cpld +sff_cpld_reg.frmt_5_1=byte +sff_cpld_reg.addr_5_1=0x00030042 +sff_cpld_reg.len_5_1=1 +sff_cpld_reg.bit_offset_5_1= + +sff_cpld_reg.mode_6_1=config +sff_cpld_reg.src_6_1=cpld +sff_cpld_reg.frmt_6_1=byte +sff_cpld_reg.addr_6_1=0x00030042 +sff_cpld_reg.len_6_1=1 +sff_cpld_reg.bit_offset_6_1= + +sff_cpld_reg.mode_7_1=config +sff_cpld_reg.src_7_1=cpld +sff_cpld_reg.frmt_7_1=byte +sff_cpld_reg.addr_7_1=0x00030042 +sff_cpld_reg.len_7_1=1 +sff_cpld_reg.bit_offset_7_1= + +sff_cpld_reg.mode_8_1=config +sff_cpld_reg.src_8_1=cpld +sff_cpld_reg.frmt_8_1=byte +sff_cpld_reg.addr_8_1=0x00030042 +sff_cpld_reg.len_8_1=1 +sff_cpld_reg.bit_offset_8_1= + +sff_cpld_reg.mode_9_1=config +sff_cpld_reg.src_9_1=cpld +sff_cpld_reg.frmt_9_1=byte +sff_cpld_reg.addr_9_1=0x00030043 +sff_cpld_reg.len_9_1=1 +sff_cpld_reg.bit_offset_9_1= + +sff_cpld_reg.mode_10_1=config +sff_cpld_reg.src_10_1=cpld +sff_cpld_reg.frmt_10_1=byte +sff_cpld_reg.addr_10_1=0x00030043 +sff_cpld_reg.len_10_1=1 +sff_cpld_reg.bit_offset_10_1= + +sff_cpld_reg.mode_11_1=config +sff_cpld_reg.src_11_1=cpld +sff_cpld_reg.frmt_11_1=byte +sff_cpld_reg.addr_11_1=0x00030043 +sff_cpld_reg.len_11_1=1 +sff_cpld_reg.bit_offset_11_1= + +sff_cpld_reg.mode_12_1=config +sff_cpld_reg.src_12_1=cpld +sff_cpld_reg.frmt_12_1=byte +sff_cpld_reg.addr_12_1=0x00030043 +sff_cpld_reg.len_12_1=1 +sff_cpld_reg.bit_offset_12_1= + +sff_cpld_reg.mode_13_1=config +sff_cpld_reg.src_13_1=cpld +sff_cpld_reg.frmt_13_1=byte +sff_cpld_reg.addr_13_1=0x00030043 +sff_cpld_reg.len_13_1=1 +sff_cpld_reg.bit_offset_13_1= + +sff_cpld_reg.mode_14_1=config +sff_cpld_reg.src_14_1=cpld +sff_cpld_reg.frmt_14_1=byte +sff_cpld_reg.addr_14_1=0x00030043 +sff_cpld_reg.len_14_1=1 +sff_cpld_reg.bit_offset_14_1= + +sff_cpld_reg.mode_15_1=config +sff_cpld_reg.src_15_1=cpld +sff_cpld_reg.frmt_15_1=byte +sff_cpld_reg.addr_15_1=0x00030043 +sff_cpld_reg.len_15_1=1 +sff_cpld_reg.bit_offset_15_1= + +sff_cpld_reg.mode_16_1=config +sff_cpld_reg.src_16_1=cpld +sff_cpld_reg.frmt_16_1=byte +sff_cpld_reg.addr_16_1=0x00030043 +sff_cpld_reg.len_16_1=1 +sff_cpld_reg.bit_offset_16_1= + +sff_cpld_reg.mode_17_1=config +sff_cpld_reg.src_17_1=cpld +sff_cpld_reg.frmt_17_1=byte +sff_cpld_reg.addr_17_1=0x00030044 +sff_cpld_reg.len_17_1=1 +sff_cpld_reg.bit_offset_17_1= + +sff_cpld_reg.mode_18_1=config +sff_cpld_reg.src_18_1=cpld +sff_cpld_reg.frmt_18_1=byte +sff_cpld_reg.addr_18_1=0x00030044 +sff_cpld_reg.len_18_1=1 +sff_cpld_reg.bit_offset_18_1= + +sff_cpld_reg.mode_19_1=config +sff_cpld_reg.src_19_1=cpld +sff_cpld_reg.frmt_19_1=byte +sff_cpld_reg.addr_19_1=0x00030044 +sff_cpld_reg.len_19_1=1 +sff_cpld_reg.bit_offset_19_1= + +sff_cpld_reg.mode_20_1=config +sff_cpld_reg.src_20_1=cpld +sff_cpld_reg.frmt_20_1=byte +sff_cpld_reg.addr_20_1=0x00030044 +sff_cpld_reg.len_20_1=1 +sff_cpld_reg.bit_offset_20_1= + +sff_cpld_reg.mode_21_1=config +sff_cpld_reg.src_21_1=cpld +sff_cpld_reg.frmt_21_1=byte +sff_cpld_reg.addr_21_1=0x00030044 +sff_cpld_reg.len_21_1=1 +sff_cpld_reg.bit_offset_21_1= + +sff_cpld_reg.mode_22_1=config +sff_cpld_reg.src_22_1=cpld +sff_cpld_reg.frmt_22_1=byte +sff_cpld_reg.addr_22_1=0x00030044 +sff_cpld_reg.len_22_1=1 +sff_cpld_reg.bit_offset_22_1= + +sff_cpld_reg.mode_23_1=config +sff_cpld_reg.src_23_1=cpld +sff_cpld_reg.frmt_23_1=byte +sff_cpld_reg.addr_23_1=0x00030044 +sff_cpld_reg.len_23_1=1 +sff_cpld_reg.bit_offset_23_1= + +sff_cpld_reg.mode_24_1=config +sff_cpld_reg.src_24_1=cpld +sff_cpld_reg.frmt_24_1=byte +sff_cpld_reg.addr_24_1=0x00030044 +sff_cpld_reg.len_24_1=1 +sff_cpld_reg.bit_offset_24_1= + +sff_cpld_reg.mode_25_1=config +sff_cpld_reg.src_25_1=cpld +sff_cpld_reg.frmt_25_1=byte +sff_cpld_reg.addr_25_1=0x00030045 +sff_cpld_reg.len_25_1=1 +sff_cpld_reg.bit_offset_25_1= + +sff_cpld_reg.mode_26_1=config +sff_cpld_reg.src_26_1=cpld +sff_cpld_reg.frmt_26_1=byte +sff_cpld_reg.addr_26_1=0x00030045 +sff_cpld_reg.len_26_1=1 +sff_cpld_reg.bit_offset_26_1= + +sff_cpld_reg.mode_27_1=config +sff_cpld_reg.src_27_1=cpld +sff_cpld_reg.frmt_27_1=byte +sff_cpld_reg.addr_27_1=0x00030045 +sff_cpld_reg.len_27_1=1 +sff_cpld_reg.bit_offset_27_1= + +sff_cpld_reg.mode_28_1=config +sff_cpld_reg.src_28_1=cpld +sff_cpld_reg.frmt_28_1=byte +sff_cpld_reg.addr_28_1=0x00030045 +sff_cpld_reg.len_28_1=1 +sff_cpld_reg.bit_offset_28_1= + +sff_cpld_reg.mode_29_1=config +sff_cpld_reg.src_29_1=cpld +sff_cpld_reg.frmt_29_1=byte +sff_cpld_reg.addr_29_1=0x00030045 +sff_cpld_reg.len_29_1=1 +sff_cpld_reg.bit_offset_29_1= + +sff_cpld_reg.mode_30_1=config +sff_cpld_reg.src_30_1=cpld +sff_cpld_reg.frmt_30_1=byte +sff_cpld_reg.addr_30_1=0x00030045 +sff_cpld_reg.len_30_1=1 +sff_cpld_reg.bit_offset_30_1= + +sff_cpld_reg.mode_31_1=config +sff_cpld_reg.src_31_1=cpld +sff_cpld_reg.frmt_31_1=byte +sff_cpld_reg.addr_31_1=0x00030045 +sff_cpld_reg.len_31_1=1 +sff_cpld_reg.bit_offset_31_1= + +sff_cpld_reg.mode_32_1=config +sff_cpld_reg.src_32_1=cpld +sff_cpld_reg.frmt_32_1=byte +sff_cpld_reg.addr_32_1=0x00030045 +sff_cpld_reg.len_32_1=1 +sff_cpld_reg.bit_offset_32_1= + +sff_cpld_reg.mode_33_1=config +sff_cpld_reg.src_33_1=cpld +sff_cpld_reg.frmt_33_1=byte +sff_cpld_reg.addr_33_1=0x00030040 +sff_cpld_reg.len_33_1=1 +sff_cpld_reg.bit_offset_33_1= + +sff_cpld_reg.mode_34_1=config +sff_cpld_reg.src_34_1=cpld +sff_cpld_reg.frmt_34_1=byte +sff_cpld_reg.addr_34_1=0x00030040 +sff_cpld_reg.len_34_1=1 +sff_cpld_reg.bit_offset_34_1= + +sff_cpld_reg.mode_35_1=config +sff_cpld_reg.src_35_1=cpld +sff_cpld_reg.frmt_35_1=byte +sff_cpld_reg.addr_35_1=0x00030040 +sff_cpld_reg.len_35_1=1 +sff_cpld_reg.bit_offset_35_1= + +sff_cpld_reg.mode_36_1=config +sff_cpld_reg.src_36_1=cpld +sff_cpld_reg.frmt_36_1=byte +sff_cpld_reg.addr_36_1=0x00030040 +sff_cpld_reg.len_36_1=1 +sff_cpld_reg.bit_offset_36_1= + +sff_cpld_reg.mode_37_1=config +sff_cpld_reg.src_37_1=cpld +sff_cpld_reg.frmt_37_1=byte +sff_cpld_reg.addr_37_1=0x00030040 +sff_cpld_reg.len_37_1=1 +sff_cpld_reg.bit_offset_37_1= + +sff_cpld_reg.mode_38_1=config +sff_cpld_reg.src_38_1=cpld +sff_cpld_reg.frmt_38_1=byte +sff_cpld_reg.addr_38_1=0x00030040 +sff_cpld_reg.len_38_1=1 +sff_cpld_reg.bit_offset_38_1= + +sff_cpld_reg.mode_39_1=config +sff_cpld_reg.src_39_1=cpld +sff_cpld_reg.frmt_39_1=byte +sff_cpld_reg.addr_39_1=0x00030040 +sff_cpld_reg.len_39_1=1 +sff_cpld_reg.bit_offset_39_1= + +sff_cpld_reg.mode_40_1=config +sff_cpld_reg.src_40_1=cpld +sff_cpld_reg.frmt_40_1=byte +sff_cpld_reg.addr_40_1=0x00030040 +sff_cpld_reg.len_40_1=1 +sff_cpld_reg.bit_offset_40_1= + +sff_cpld_reg.mode_41_1=config +sff_cpld_reg.src_41_1=cpld +sff_cpld_reg.frmt_41_1=byte +sff_cpld_reg.addr_41_1=0x00030040 +sff_cpld_reg.len_41_1=1 +sff_cpld_reg.bit_offset_41_1= + +sff_cpld_reg.mode_42_1=config +sff_cpld_reg.src_42_1=cpld +sff_cpld_reg.frmt_42_1=byte +sff_cpld_reg.addr_42_1=0x00030040 +sff_cpld_reg.len_42_1=1 +sff_cpld_reg.bit_offset_42_1= + +sff_cpld_reg.mode_43_1=config +sff_cpld_reg.src_43_1=cpld +sff_cpld_reg.frmt_43_1=byte +sff_cpld_reg.addr_43_1=0x00030040 +sff_cpld_reg.len_43_1=1 +sff_cpld_reg.bit_offset_43_1= + +sff_cpld_reg.mode_44_1=config +sff_cpld_reg.src_44_1=cpld +sff_cpld_reg.frmt_44_1=byte +sff_cpld_reg.addr_44_1=0x00030040 +sff_cpld_reg.len_44_1=1 +sff_cpld_reg.bit_offset_44_1= + +sff_cpld_reg.mode_45_1=config +sff_cpld_reg.src_45_1=cpld +sff_cpld_reg.frmt_45_1=byte +sff_cpld_reg.addr_45_1=0x00030040 +sff_cpld_reg.len_45_1=1 +sff_cpld_reg.bit_offset_45_1= + +sff_cpld_reg.mode_46_1=config +sff_cpld_reg.src_46_1=cpld +sff_cpld_reg.frmt_46_1=byte +sff_cpld_reg.addr_46_1=0x00030040 +sff_cpld_reg.len_46_1=1 +sff_cpld_reg.bit_offset_46_1= + +sff_cpld_reg.mode_47_1=config +sff_cpld_reg.src_47_1=cpld +sff_cpld_reg.frmt_47_1=byte +sff_cpld_reg.addr_47_1=0x00030040 +sff_cpld_reg.len_47_1=1 +sff_cpld_reg.bit_offset_47_1= + +sff_cpld_reg.mode_48_1=config +sff_cpld_reg.src_48_1=cpld +sff_cpld_reg.frmt_48_1=byte +sff_cpld_reg.addr_48_1=0x00030040 +sff_cpld_reg.len_48_1=1 +sff_cpld_reg.bit_offset_48_1= + +sff_cpld_reg.mode_49_1=config +sff_cpld_reg.src_49_1=cpld +sff_cpld_reg.frmt_49_1=byte +sff_cpld_reg.addr_49_1=0x00030041 +sff_cpld_reg.len_49_1=1 +sff_cpld_reg.bit_offset_49_1= + +sff_cpld_reg.mode_50_1=config +sff_cpld_reg.src_50_1=cpld +sff_cpld_reg.frmt_50_1=byte +sff_cpld_reg.addr_50_1=0x00030041 +sff_cpld_reg.len_50_1=1 +sff_cpld_reg.bit_offset_50_1= + +sff_cpld_reg.mode_51_1=config +sff_cpld_reg.src_51_1=cpld +sff_cpld_reg.frmt_51_1=byte +sff_cpld_reg.addr_51_1=0x00030041 +sff_cpld_reg.len_51_1=1 +sff_cpld_reg.bit_offset_51_1= + +sff_cpld_reg.mode_52_1=config +sff_cpld_reg.src_52_1=cpld +sff_cpld_reg.frmt_52_1=byte +sff_cpld_reg.addr_52_1=0x00030041 +sff_cpld_reg.len_52_1=1 +sff_cpld_reg.bit_offset_52_1= + +sff_cpld_reg.mode_53_1=config +sff_cpld_reg.src_53_1=cpld +sff_cpld_reg.frmt_53_1=byte +sff_cpld_reg.addr_53_1=0x00030041 +sff_cpld_reg.len_53_1=1 +sff_cpld_reg.bit_offset_53_1= + +sff_cpld_reg.mode_54_1=config +sff_cpld_reg.src_54_1=cpld +sff_cpld_reg.frmt_54_1=byte +sff_cpld_reg.addr_54_1=0x00030041 +sff_cpld_reg.len_54_1=1 +sff_cpld_reg.bit_offset_54_1= + +sff_cpld_reg.mode_55_1=config +sff_cpld_reg.src_55_1=cpld +sff_cpld_reg.frmt_55_1=byte +sff_cpld_reg.addr_55_1=0x00030041 +sff_cpld_reg.len_55_1=1 +sff_cpld_reg.bit_offset_55_1= + +sff_cpld_reg.mode_56_1=config +sff_cpld_reg.src_56_1=cpld +sff_cpld_reg.frmt_56_1=byte +sff_cpld_reg.addr_56_1=0x00030041 +sff_cpld_reg.len_56_1=1 +sff_cpld_reg.bit_offset_56_1= + +sff_cpld_reg.mode_57_1=config +sff_cpld_reg.src_57_1=cpld +sff_cpld_reg.frmt_57_1=byte +sff_cpld_reg.addr_57_1=0x00030041 +sff_cpld_reg.len_57_1=1 +sff_cpld_reg.bit_offset_57_1= + +sff_cpld_reg.mode_58_1=config +sff_cpld_reg.src_58_1=cpld +sff_cpld_reg.frmt_58_1=byte +sff_cpld_reg.addr_58_1=0x00030041 +sff_cpld_reg.len_58_1=1 +sff_cpld_reg.bit_offset_58_1= + +sff_cpld_reg.mode_59_1=config +sff_cpld_reg.src_59_1=cpld +sff_cpld_reg.frmt_59_1=byte +sff_cpld_reg.addr_59_1=0x00030041 +sff_cpld_reg.len_59_1=1 +sff_cpld_reg.bit_offset_59_1= + +sff_cpld_reg.mode_60_1=config +sff_cpld_reg.src_60_1=cpld +sff_cpld_reg.frmt_60_1=byte +sff_cpld_reg.addr_60_1=0x00030041 +sff_cpld_reg.len_60_1=1 +sff_cpld_reg.bit_offset_60_1= + +sff_cpld_reg.mode_61_1=config +sff_cpld_reg.src_61_1=cpld +sff_cpld_reg.frmt_61_1=byte +sff_cpld_reg.addr_61_1=0x00030041 +sff_cpld_reg.len_61_1=1 +sff_cpld_reg.bit_offset_61_1= + +sff_cpld_reg.mode_62_1=config +sff_cpld_reg.src_62_1=cpld +sff_cpld_reg.frmt_62_1=byte +sff_cpld_reg.addr_62_1=0x00030041 +sff_cpld_reg.len_62_1=1 +sff_cpld_reg.bit_offset_62_1= + +sff_cpld_reg.mode_63_1=config +sff_cpld_reg.src_63_1=cpld +sff_cpld_reg.frmt_63_1=byte +sff_cpld_reg.addr_63_1=0x00030041 +sff_cpld_reg.len_63_1=1 +sff_cpld_reg.bit_offset_63_1= + +sff_cpld_reg.mode_64_1=config +sff_cpld_reg.src_64_1=cpld +sff_cpld_reg.frmt_64_1=byte +sff_cpld_reg.addr_64_1=0x00030041 +sff_cpld_reg.len_64_1=1 +sff_cpld_reg.bit_offset_64_1= + + +# interrupt +sff_cpld_reg.mode_1_9=config +sff_cpld_reg.src_1_9=cpld +sff_cpld_reg.frmt_1_9=bit +sff_cpld_reg.pola_1_9=negative +sff_cpld_reg.addr_1_9=0x000200b3 +sff_cpld_reg.len_1_9=1 +sff_cpld_reg.bit_offset_1_9=0 + +sff_cpld_reg.mode_2_9=config +sff_cpld_reg.src_2_9=cpld +sff_cpld_reg.frmt_2_9=bit +sff_cpld_reg.pola_2_9=negative +sff_cpld_reg.addr_2_9=0x000200b3 +sff_cpld_reg.len_2_9=1 +sff_cpld_reg.bit_offset_2_9=1 + +sff_cpld_reg.mode_3_9=config +sff_cpld_reg.src_3_9=cpld +sff_cpld_reg.frmt_3_9=bit +sff_cpld_reg.pola_3_9=negative +sff_cpld_reg.addr_3_9=0x000200b3 +sff_cpld_reg.len_3_9=1 +sff_cpld_reg.bit_offset_3_9=2 + +sff_cpld_reg.mode_4_9=config +sff_cpld_reg.src_4_9=cpld +sff_cpld_reg.frmt_4_9=bit +sff_cpld_reg.pola_4_9=negative +sff_cpld_reg.addr_4_9=0x000200b3 +sff_cpld_reg.len_4_9=1 +sff_cpld_reg.bit_offset_4_9=3 + +sff_cpld_reg.mode_5_9=config +sff_cpld_reg.src_5_9=cpld +sff_cpld_reg.frmt_5_9=bit +sff_cpld_reg.pola_5_9=negative +sff_cpld_reg.addr_5_9=0x000200b3 +sff_cpld_reg.len_5_9=1 +sff_cpld_reg.bit_offset_5_9=4 + +sff_cpld_reg.mode_6_9=config +sff_cpld_reg.src_6_9=cpld +sff_cpld_reg.frmt_6_9=bit +sff_cpld_reg.pola_6_9=negative +sff_cpld_reg.addr_6_9=0x000200b3 +sff_cpld_reg.len_6_9=1 +sff_cpld_reg.bit_offset_6_9=5 + +sff_cpld_reg.mode_7_9=config +sff_cpld_reg.src_7_9=cpld +sff_cpld_reg.frmt_7_9=bit +sff_cpld_reg.pola_7_9=negative +sff_cpld_reg.addr_7_9=0x000200b3 +sff_cpld_reg.len_7_9=1 +sff_cpld_reg.bit_offset_7_9=6 + +sff_cpld_reg.mode_8_9=config +sff_cpld_reg.src_8_9=cpld +sff_cpld_reg.frmt_8_9=bit +sff_cpld_reg.pola_8_9=negative +sff_cpld_reg.addr_8_9=0x000200b3 +sff_cpld_reg.len_8_9=1 +sff_cpld_reg.bit_offset_8_9=7 + +sff_cpld_reg.mode_9_9=config +sff_cpld_reg.src_9_9=cpld +sff_cpld_reg.frmt_9_9=bit +sff_cpld_reg.pola_9_9=negative +sff_cpld_reg.addr_9_9=0x000200b5 +sff_cpld_reg.len_9_9=1 +sff_cpld_reg.bit_offset_9_9=0 + +sff_cpld_reg.mode_10_9=config +sff_cpld_reg.src_10_9=cpld +sff_cpld_reg.frmt_10_9=bit +sff_cpld_reg.pola_10_9=negative +sff_cpld_reg.addr_10_9=0x000200b5 +sff_cpld_reg.len_10_9=1 +sff_cpld_reg.bit_offset_10_9=1 + +sff_cpld_reg.mode_11_9=config +sff_cpld_reg.src_11_9=cpld +sff_cpld_reg.frmt_11_9=bit +sff_cpld_reg.pola_11_9=negative +sff_cpld_reg.addr_11_9=0x000200b5 +sff_cpld_reg.len_11_9=1 +sff_cpld_reg.bit_offset_11_9=2 + +sff_cpld_reg.mode_12_9=config +sff_cpld_reg.src_12_9=cpld +sff_cpld_reg.frmt_12_9=bit +sff_cpld_reg.pola_12_9=negative +sff_cpld_reg.addr_12_9=0x000200b5 +sff_cpld_reg.len_12_9=1 +sff_cpld_reg.bit_offset_12_9=3 + +sff_cpld_reg.mode_13_9=config +sff_cpld_reg.src_13_9=cpld +sff_cpld_reg.frmt_13_9=bit +sff_cpld_reg.pola_13_9=negative +sff_cpld_reg.addr_13_9=0x000200b5 +sff_cpld_reg.len_13_9=1 +sff_cpld_reg.bit_offset_13_9=4 + +sff_cpld_reg.mode_14_9=config +sff_cpld_reg.src_14_9=cpld +sff_cpld_reg.frmt_14_9=bit +sff_cpld_reg.pola_14_9=negative +sff_cpld_reg.addr_14_9=0x000200b5 +sff_cpld_reg.len_14_9=1 +sff_cpld_reg.bit_offset_14_9=5 + +sff_cpld_reg.mode_15_9=config +sff_cpld_reg.src_15_9=cpld +sff_cpld_reg.frmt_15_9=bit +sff_cpld_reg.pola_15_9=negative +sff_cpld_reg.addr_15_9=0x000200b5 +sff_cpld_reg.len_15_9=1 +sff_cpld_reg.bit_offset_15_9=6 + +sff_cpld_reg.mode_16_9=config +sff_cpld_reg.src_16_9=cpld +sff_cpld_reg.frmt_16_9=bit +sff_cpld_reg.pola_16_9=negative +sff_cpld_reg.addr_16_9=0x000200b5 +sff_cpld_reg.len_16_9=1 +sff_cpld_reg.bit_offset_16_9=7 + +sff_cpld_reg.mode_17_9=config +sff_cpld_reg.src_17_9=cpld +sff_cpld_reg.frmt_17_9=bit +sff_cpld_reg.pola_17_9=negative +sff_cpld_reg.addr_17_9=0x000200b7 +sff_cpld_reg.len_17_9=1 +sff_cpld_reg.bit_offset_17_9=0 + +sff_cpld_reg.mode_18_9=config +sff_cpld_reg.src_18_9=cpld +sff_cpld_reg.frmt_18_9=bit +sff_cpld_reg.pola_18_9=negative +sff_cpld_reg.addr_18_9=0x000200b7 +sff_cpld_reg.len_18_9=1 +sff_cpld_reg.bit_offset_18_9=1 + +sff_cpld_reg.mode_19_9=config +sff_cpld_reg.src_19_9=cpld +sff_cpld_reg.frmt_19_9=bit +sff_cpld_reg.pola_19_9=negative +sff_cpld_reg.addr_19_9=0x000200b7 +sff_cpld_reg.len_19_9=1 +sff_cpld_reg.bit_offset_19_9=2 + +sff_cpld_reg.mode_20_9=config +sff_cpld_reg.src_20_9=cpld +sff_cpld_reg.frmt_20_9=bit +sff_cpld_reg.pola_20_9=negative +sff_cpld_reg.addr_20_9=0x000200b7 +sff_cpld_reg.len_20_9=1 +sff_cpld_reg.bit_offset_20_9=3 + +sff_cpld_reg.mode_21_9=config +sff_cpld_reg.src_21_9=cpld +sff_cpld_reg.frmt_21_9=bit +sff_cpld_reg.pola_21_9=negative +sff_cpld_reg.addr_21_9=0x000200b7 +sff_cpld_reg.len_21_9=1 +sff_cpld_reg.bit_offset_21_9=4 + +sff_cpld_reg.mode_22_9=config +sff_cpld_reg.src_22_9=cpld +sff_cpld_reg.frmt_22_9=bit +sff_cpld_reg.pola_22_9=negative +sff_cpld_reg.addr_22_9=0x000200b7 +sff_cpld_reg.len_22_9=1 +sff_cpld_reg.bit_offset_22_9=5 + +sff_cpld_reg.mode_23_9=config +sff_cpld_reg.src_23_9=cpld +sff_cpld_reg.frmt_23_9=bit +sff_cpld_reg.pola_23_9=negative +sff_cpld_reg.addr_23_9=0x000200b7 +sff_cpld_reg.len_23_9=1 +sff_cpld_reg.bit_offset_23_9=6 + +sff_cpld_reg.mode_24_9=config +sff_cpld_reg.src_24_9=cpld +sff_cpld_reg.frmt_24_9=bit +sff_cpld_reg.pola_24_9=negative +sff_cpld_reg.addr_24_9=0x000200b7 +sff_cpld_reg.len_24_9=1 +sff_cpld_reg.bit_offset_24_9=7 + +sff_cpld_reg.mode_25_9=config +sff_cpld_reg.src_25_9=cpld +sff_cpld_reg.frmt_25_9=bit +sff_cpld_reg.pola_25_9=negative +sff_cpld_reg.addr_25_9=0x000200b9 +sff_cpld_reg.len_25_9=1 +sff_cpld_reg.bit_offset_25_9=0 + +sff_cpld_reg.mode_26_9=config +sff_cpld_reg.src_26_9=cpld +sff_cpld_reg.frmt_26_9=bit +sff_cpld_reg.pola_26_9=negative +sff_cpld_reg.addr_26_9=0x000200b9 +sff_cpld_reg.len_26_9=1 +sff_cpld_reg.bit_offset_26_9=1 + +sff_cpld_reg.mode_27_9=config +sff_cpld_reg.src_27_9=cpld +sff_cpld_reg.frmt_27_9=bit +sff_cpld_reg.pola_27_9=negative +sff_cpld_reg.addr_27_9=0x000200b9 +sff_cpld_reg.len_27_9=1 +sff_cpld_reg.bit_offset_27_9=2 + +sff_cpld_reg.mode_28_9=config +sff_cpld_reg.src_28_9=cpld +sff_cpld_reg.frmt_28_9=bit +sff_cpld_reg.pola_28_9=negative +sff_cpld_reg.addr_28_9=0x000200b9 +sff_cpld_reg.len_28_9=1 +sff_cpld_reg.bit_offset_28_9=3 + +sff_cpld_reg.mode_29_9=config +sff_cpld_reg.src_29_9=cpld +sff_cpld_reg.frmt_29_9=bit +sff_cpld_reg.pola_29_9=negative +sff_cpld_reg.addr_29_9=0x000200b9 +sff_cpld_reg.len_29_9=1 +sff_cpld_reg.bit_offset_29_9=4 + +sff_cpld_reg.mode_30_9=config +sff_cpld_reg.src_30_9=cpld +sff_cpld_reg.frmt_30_9=bit +sff_cpld_reg.pola_30_9=negative +sff_cpld_reg.addr_30_9=0x000200b9 +sff_cpld_reg.len_30_9=1 +sff_cpld_reg.bit_offset_30_9=5 + +sff_cpld_reg.mode_31_9=config +sff_cpld_reg.src_31_9=cpld +sff_cpld_reg.frmt_31_9=bit +sff_cpld_reg.pola_31_9=negative +sff_cpld_reg.addr_31_9=0x000200b9 +sff_cpld_reg.len_31_9=1 +sff_cpld_reg.bit_offset_31_9=6 + +sff_cpld_reg.mode_32_9=config +sff_cpld_reg.src_32_9=cpld +sff_cpld_reg.frmt_32_9=bit +sff_cpld_reg.pola_32_9=negative +sff_cpld_reg.addr_32_9=0x000200b9 +sff_cpld_reg.len_32_9=1 +sff_cpld_reg.bit_offset_32_9=7 + +sff_cpld_reg.mode_33_9=config +sff_cpld_reg.src_33_9=cpld +sff_cpld_reg.frmt_33_9=bit +sff_cpld_reg.pola_33_9=negative +sff_cpld_reg.addr_33_9=0x000400b3 +sff_cpld_reg.len_33_9=1 +sff_cpld_reg.bit_offset_33_9=0 + +sff_cpld_reg.mode_34_9=config +sff_cpld_reg.src_34_9=cpld +sff_cpld_reg.frmt_34_9=bit +sff_cpld_reg.pola_34_9=negative +sff_cpld_reg.addr_34_9=0x000400b3 +sff_cpld_reg.len_34_9=1 +sff_cpld_reg.bit_offset_34_9=1 + +sff_cpld_reg.mode_35_9=config +sff_cpld_reg.src_35_9=cpld +sff_cpld_reg.frmt_35_9=bit +sff_cpld_reg.pola_35_9=negative +sff_cpld_reg.addr_35_9=0x000400b3 +sff_cpld_reg.len_35_9=1 +sff_cpld_reg.bit_offset_35_9=2 + +sff_cpld_reg.mode_36_9=config +sff_cpld_reg.src_36_9=cpld +sff_cpld_reg.frmt_36_9=bit +sff_cpld_reg.pola_36_9=negative +sff_cpld_reg.addr_36_9=0x000400b3 +sff_cpld_reg.len_36_9=1 +sff_cpld_reg.bit_offset_36_9=3 + +sff_cpld_reg.mode_37_9=config +sff_cpld_reg.src_37_9=cpld +sff_cpld_reg.frmt_37_9=bit +sff_cpld_reg.pola_37_9=negative +sff_cpld_reg.addr_37_9=0x000400b3 +sff_cpld_reg.len_37_9=1 +sff_cpld_reg.bit_offset_37_9=4 + +sff_cpld_reg.mode_38_9=config +sff_cpld_reg.src_38_9=cpld +sff_cpld_reg.frmt_38_9=bit +sff_cpld_reg.pola_38_9=negative +sff_cpld_reg.addr_38_9=0x000400b3 +sff_cpld_reg.len_38_9=1 +sff_cpld_reg.bit_offset_38_9=5 + +sff_cpld_reg.mode_39_9=config +sff_cpld_reg.src_39_9=cpld +sff_cpld_reg.frmt_39_9=bit +sff_cpld_reg.pola_39_9=negative +sff_cpld_reg.addr_39_9=0x000400b3 +sff_cpld_reg.len_39_9=1 +sff_cpld_reg.bit_offset_39_9=6 + +sff_cpld_reg.mode_40_9=config +sff_cpld_reg.src_40_9=cpld +sff_cpld_reg.frmt_40_9=bit +sff_cpld_reg.pola_40_9=negative +sff_cpld_reg.addr_40_9=0x000400b3 +sff_cpld_reg.len_40_9=1 +sff_cpld_reg.bit_offset_40_9=7 + +sff_cpld_reg.mode_41_9=config +sff_cpld_reg.src_41_9=cpld +sff_cpld_reg.frmt_41_9=bit +sff_cpld_reg.pola_41_9=negative +sff_cpld_reg.addr_41_9=0x000400b5 +sff_cpld_reg.len_41_9=1 +sff_cpld_reg.bit_offset_41_9=0 + +sff_cpld_reg.mode_42_9=config +sff_cpld_reg.src_42_9=cpld +sff_cpld_reg.frmt_42_9=bit +sff_cpld_reg.pola_42_9=negative +sff_cpld_reg.addr_42_9=0x000400b5 +sff_cpld_reg.len_42_9=1 +sff_cpld_reg.bit_offset_42_9=1 + +sff_cpld_reg.mode_43_9=config +sff_cpld_reg.src_43_9=cpld +sff_cpld_reg.frmt_43_9=bit +sff_cpld_reg.pola_43_9=negative +sff_cpld_reg.addr_43_9=0x000400b5 +sff_cpld_reg.len_43_9=1 +sff_cpld_reg.bit_offset_43_9=2 + +sff_cpld_reg.mode_44_9=config +sff_cpld_reg.src_44_9=cpld +sff_cpld_reg.frmt_44_9=bit +sff_cpld_reg.pola_44_9=negative +sff_cpld_reg.addr_44_9=0x000400b5 +sff_cpld_reg.len_44_9=1 +sff_cpld_reg.bit_offset_44_9=3 + +sff_cpld_reg.mode_45_9=config +sff_cpld_reg.src_45_9=cpld +sff_cpld_reg.frmt_45_9=bit +sff_cpld_reg.pola_45_9=negative +sff_cpld_reg.addr_45_9=0x000400b5 +sff_cpld_reg.len_45_9=1 +sff_cpld_reg.bit_offset_45_9=4 + +sff_cpld_reg.mode_46_9=config +sff_cpld_reg.src_46_9=cpld +sff_cpld_reg.frmt_46_9=bit +sff_cpld_reg.pola_46_9=negative +sff_cpld_reg.addr_46_9=0x000400b5 +sff_cpld_reg.len_46_9=1 +sff_cpld_reg.bit_offset_46_9=5 + +sff_cpld_reg.mode_47_9=config +sff_cpld_reg.src_47_9=cpld +sff_cpld_reg.frmt_47_9=bit +sff_cpld_reg.pola_47_9=negative +sff_cpld_reg.addr_47_9=0x000400b5 +sff_cpld_reg.len_47_9=1 +sff_cpld_reg.bit_offset_47_9=6 + +sff_cpld_reg.mode_48_9=config +sff_cpld_reg.src_48_9=cpld +sff_cpld_reg.frmt_48_9=bit +sff_cpld_reg.pola_48_9=negative +sff_cpld_reg.addr_48_9=0x000400b5 +sff_cpld_reg.len_48_9=1 +sff_cpld_reg.bit_offset_48_9=7 + +sff_cpld_reg.mode_49_9=config +sff_cpld_reg.src_49_9=cpld +sff_cpld_reg.frmt_49_9=bit +sff_cpld_reg.pola_49_9=negative +sff_cpld_reg.addr_49_9=0x000400b7 +sff_cpld_reg.len_49_9=1 +sff_cpld_reg.bit_offset_49_9=0 + +sff_cpld_reg.mode_50_9=config +sff_cpld_reg.src_50_9=cpld +sff_cpld_reg.frmt_50_9=bit +sff_cpld_reg.pola_50_9=negative +sff_cpld_reg.addr_50_9=0x000400b7 +sff_cpld_reg.len_50_9=1 +sff_cpld_reg.bit_offset_50_9=1 + +sff_cpld_reg.mode_51_9=config +sff_cpld_reg.src_51_9=cpld +sff_cpld_reg.frmt_51_9=bit +sff_cpld_reg.pola_51_9=negative +sff_cpld_reg.addr_51_9=0x000400b7 +sff_cpld_reg.len_51_9=1 +sff_cpld_reg.bit_offset_51_9=2 + +sff_cpld_reg.mode_52_9=config +sff_cpld_reg.src_52_9=cpld +sff_cpld_reg.frmt_52_9=bit +sff_cpld_reg.pola_52_9=negative +sff_cpld_reg.addr_52_9=0x000400b7 +sff_cpld_reg.len_52_9=1 +sff_cpld_reg.bit_offset_52_9=3 + +sff_cpld_reg.mode_53_9=config +sff_cpld_reg.src_53_9=cpld +sff_cpld_reg.frmt_53_9=bit +sff_cpld_reg.pola_53_9=negative +sff_cpld_reg.addr_53_9=0x000400b7 +sff_cpld_reg.len_53_9=1 +sff_cpld_reg.bit_offset_53_9=4 + +sff_cpld_reg.mode_54_9=config +sff_cpld_reg.src_54_9=cpld +sff_cpld_reg.frmt_54_9=bit +sff_cpld_reg.pola_54_9=negative +sff_cpld_reg.addr_54_9=0x000400b7 +sff_cpld_reg.len_54_9=1 +sff_cpld_reg.bit_offset_54_9=5 + +sff_cpld_reg.mode_55_9=config +sff_cpld_reg.src_55_9=cpld +sff_cpld_reg.frmt_55_9=bit +sff_cpld_reg.pola_55_9=negative +sff_cpld_reg.addr_55_9=0x000400b7 +sff_cpld_reg.len_55_9=1 +sff_cpld_reg.bit_offset_55_9=6 + +sff_cpld_reg.mode_56_9=config +sff_cpld_reg.src_56_9=cpld +sff_cpld_reg.frmt_56_9=bit +sff_cpld_reg.pola_56_9=negative +sff_cpld_reg.addr_56_9=0x000400b7 +sff_cpld_reg.len_56_9=1 +sff_cpld_reg.bit_offset_56_9=7 + +sff_cpld_reg.mode_57_9=config +sff_cpld_reg.src_57_9=cpld +sff_cpld_reg.frmt_57_9=bit +sff_cpld_reg.pola_57_9=negative +sff_cpld_reg.addr_57_9=0x000400b9 +sff_cpld_reg.len_57_9=1 +sff_cpld_reg.bit_offset_57_9=0 + +sff_cpld_reg.mode_58_9=config +sff_cpld_reg.src_58_9=cpld +sff_cpld_reg.frmt_58_9=bit +sff_cpld_reg.pola_58_9=negative +sff_cpld_reg.addr_58_9=0x000400b9 +sff_cpld_reg.len_58_9=1 +sff_cpld_reg.bit_offset_58_9=1 + +sff_cpld_reg.mode_59_9=config +sff_cpld_reg.src_59_9=cpld +sff_cpld_reg.frmt_59_9=bit +sff_cpld_reg.pola_59_9=negative +sff_cpld_reg.addr_59_9=0x000400b9 +sff_cpld_reg.len_59_9=1 +sff_cpld_reg.bit_offset_59_9=2 + +sff_cpld_reg.mode_60_9=config +sff_cpld_reg.src_60_9=cpld +sff_cpld_reg.frmt_60_9=bit +sff_cpld_reg.pola_60_9=negative +sff_cpld_reg.addr_60_9=0x000400b9 +sff_cpld_reg.len_60_9=1 +sff_cpld_reg.bit_offset_60_9=3 + +sff_cpld_reg.mode_61_9=config +sff_cpld_reg.src_61_9=cpld +sff_cpld_reg.frmt_61_9=bit +sff_cpld_reg.pola_61_9=negative +sff_cpld_reg.addr_61_9=0x000400b9 +sff_cpld_reg.len_61_9=1 +sff_cpld_reg.bit_offset_61_9=4 + +sff_cpld_reg.mode_62_9=config +sff_cpld_reg.src_62_9=cpld +sff_cpld_reg.frmt_62_9=bit +sff_cpld_reg.pola_62_9=negative +sff_cpld_reg.addr_62_9=0x000400b9 +sff_cpld_reg.len_62_9=1 +sff_cpld_reg.bit_offset_62_9=5 + +sff_cpld_reg.mode_63_9=config +sff_cpld_reg.src_63_9=cpld +sff_cpld_reg.frmt_63_9=bit +sff_cpld_reg.pola_63_9=negative +sff_cpld_reg.addr_63_9=0x000400b9 +sff_cpld_reg.len_63_9=1 +sff_cpld_reg.bit_offset_63_9=6 + +sff_cpld_reg.mode_64_9=config +sff_cpld_reg.src_64_9=cpld +sff_cpld_reg.frmt_64_9=bit +sff_cpld_reg.pola_64_9=negative +sff_cpld_reg.addr_64_9=0x000400b9 +sff_cpld_reg.len_64_9=1 +sff_cpld_reg.bit_offset_64_9=7 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg new file mode 100644 index 0000000000..c4c85e312f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/cfg_file/WATCHDOG.cfg @@ -0,0 +1,18 @@ + +# Configuration item: watchdog number +# Description: Format watchdog_id_[index] +watchdog_id_0=0 + +# Configuration item: watchdog device name +# Description: Format watchdog_name_[index]_[type] +watchdog_name_0_0=identity +watchdog_name_0_1=state +watchdog_name_0_2=timeleft +watchdog_name_0_3=timeout + +watchdog_dev.mode_0_4=config +watchdog_dev.src_0_4=cpld +watchdog_dev.frmt_0_4=bit +watchdog_dev.addr_0_4=0x00010040 +watchdog_dev.len_0_4=1 +watchdog_dev.bit_offset_0_4=0 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/file_name/0x414c b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/file_name/0x414c new file mode 100644 index 0000000000..3944674a47 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/s3ip_sysfs_cfg/file_name/0x414c @@ -0,0 +1,8 @@ +CPLD +FAN +LED +PSU +SENSOR +SFF +FPGA +WATCHDOG diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/setup.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/setup.py new file mode 100644 index 0000000000..6c3916921a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6951-64hc-cp/setup.py @@ -0,0 +1,39 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation', + license='Apache 2.0', + author='SONiC Team', + author_email='support', + url='', + maintainer='support', + maintainer_email='', + packages=[ + 'sonic_platform', + 'plat_hal', + 'wbutil', + 'eepromutil', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +)